wayland.compositor: user UserDataMap to store per-surface data

This commit is contained in:
Victor Berger 2019-04-23 22:46:11 +02:00 committed by Victor Berger
parent 0712bdefec
commit c604a48dce
17 changed files with 431 additions and 525 deletions

View File

@ -28,7 +28,7 @@ use smithay::{
};
use crate::shaders;
use crate::shell::{MyCompositorToken, MyWindowMap};
use crate::shell::{MyCompositorToken, MyWindowMap, SurfaceData};
#[derive(Copy, Clone)]
struct Vertex {
@ -299,8 +299,9 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
location,
|_surface, attributes, role, &(mut x, mut y)| {
// Pull a new buffer if available
if attributes.user_data.texture.is_none() {
if let Some(buffer) = attributes.user_data.buffer.take() {
if let Some(data) = attributes.user_data.get_mut::<SurfaceData>() {
if data.texture.is_none() {
if let Some(buffer) = data.buffer.take() {
if let Ok(m) = self.texture_from_buffer(buffer.clone()) {
// release the buffer if it was an SHM buffer
#[cfg(feature = "egl")]
@ -314,7 +315,7 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
buffer.release();
}
attributes.user_data.texture = Some(m);
data.texture = Some(m);
} else {
// there was an error reading the buffer, release it, we
// already logged the error
@ -323,7 +324,7 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
}
}
// Now, should we be drawn ?
if attributes.user_data.texture.is_some() {
if data.texture.is_some() {
// if yes, also process the children
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
x += subdata.location.0;
@ -331,12 +332,17 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
}
TraversalAction::DoChildren((x, y))
} else {
// we are not display, so our children are neither
// we are not displayed, so our children are neither
TraversalAction::SkipChildren
}
} else {
// we are not displayed, so our children are neither
TraversalAction::SkipChildren
}
},
|_surface, attributes, role, &(mut x, mut y)| {
if let Some(ref metadata) = attributes.user_data.texture {
if let Some(ref data) = attributes.user_data.get::<SurfaceData>() {
if let Some(ref metadata) = data.texture {
// we need to re-extract the subsurface offset, as the previous closure
// only passes it to our children
if let Ok(subdata) = Role::<SubsurfaceRole>::data(role) {
@ -364,6 +370,7 @@ impl<F: GLGraphicsBackend + 'static> GliumDrawer<F> {
},
);
}
}
},
|_, _, _, _| true,
);

View File

@ -36,18 +36,17 @@ define_roles!(Roles =>
[ CursorImage, CursorImageRole ]
);
pub type MyWindowMap =
WindowMap<SurfaceData, Roles, (), (), fn(&SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)>>;
pub type MyWindowMap = WindowMap<Roles, (), (), fn(&SurfaceAttributes) -> Option<(i32, i32)>>;
pub type MyCompositorToken = CompositorToken<SurfaceData, Roles>;
pub type MyCompositorToken = CompositorToken<Roles>;
pub fn init_shell(
display: &mut Display,
log: ::slog::Logger,
) -> (
CompositorToken<SurfaceData, Roles>,
Arc<Mutex<XdgShellState<SurfaceData, Roles, ()>>>,
Arc<Mutex<WlShellState<SurfaceData, Roles, ()>>>,
CompositorToken<Roles>,
Arc<Mutex<XdgShellState<Roles, ()>>>,
Arc<Mutex<WlShellState<Roles, ()>>>,
Rc<RefCell<MyWindowMap>>,
) {
// Create the compositor
@ -63,7 +62,7 @@ pub fn init_shell(
);
// Init a window map, to track the location of our windows
let window_map = Rc::new(RefCell::new(WindowMap::<_, _, (), (), _>::new(
let window_map = Rc::new(RefCell::new(WindowMap::<_, (), (), _>::new(
compositor_token,
get_size as _,
)));
@ -105,7 +104,7 @@ pub fn init_shell(
let (wl_shell_state, _) = wl_shell_init(
display,
compositor_token,
move |req: ShellRequest<_, _, ()>| {
move |req: ShellRequest<_, ()>| {
if let ShellRequest::SetKind {
surface,
kind: ShellSurfaceKind::Toplevel,
@ -135,31 +134,34 @@ pub struct SurfaceData {
pub texture: Option<crate::glium_drawer::TextureMetadata>,
}
fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<SurfaceData, Roles>) {
fn surface_commit(surface: &wl_surface::WlSurface, token: CompositorToken<Roles>) {
// we retrieve the contents of the associated buffer and copy it
token.with_surface_data(surface, |attributes| {
attributes.user_data.insert_if_missing(|| SurfaceData::default());
match attributes.buffer.take() {
Some(Some((buffer, (_x, _y)))) => {
// new contents
// TODO: handle hotspot coordinates
attributes.user_data.buffer = Some(buffer);
attributes.user_data.texture = None;
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
data.buffer = Some(buffer);
data.texture = None;
}
Some(None) => {
// erase the contents
attributes.user_data.buffer = None;
attributes.user_data.texture = None;
let data = attributes.user_data.get_mut::<SurfaceData>().unwrap();
data.buffer = None;
data.texture = None;
}
None => {}
}
});
}
fn get_size(attrs: &SurfaceAttributes<SurfaceData>) -> Option<(i32, i32)> {
attrs
.user_data
.texture
fn get_size(attrs: &SurfaceAttributes) -> Option<(i32, i32)> {
attrs.user_data.get::<SurfaceData>().and_then(|data| {
data.texture
.as_ref()
.map(|ref meta| meta.dimensions)
.map(|(x, y)| (x as i32, y as i32))
})
}

View File

@ -63,7 +63,7 @@ use smithay::{
use crate::glium_drawer::GliumDrawer;
use crate::input_handler::AnvilInputHandler;
use crate::shell::{init_shell, MyWindowMap, Roles, SurfaceData};
use crate::shell::{init_shell, MyWindowMap, Roles};
pub struct SessionFd(RawFd);
impl AsRawFd for SessionFd {
@ -272,7 +272,7 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop<()>, log: Logger
}
struct UdevHandlerImpl<S: SessionNotifier, Data: 'static> {
compositor_token: CompositorToken<SurfaceData, Roles>,
compositor_token: CompositorToken<Roles>,
#[cfg(feature = "egl")]
active_egl_context: Rc<RefCell<Option<EGLDisplay>>>,
session: AutoSession,
@ -522,7 +522,7 @@ impl<S: SessionNotifier, Data: 'static> UdevHandler for UdevHandlerImpl<S, Data>
}
pub struct DrmHandlerImpl {
compositor_token: CompositorToken<SurfaceData, Roles>,
compositor_token: CompositorToken<Roles>,
backends: Rc<RefCell<HashMap<crtc::Handle, GliumDrawer<RenderSurface>>>>,
window_map: Rc<RefCell<MyWindowMap>>,
pointer_location: Rc<RefCell<(f64, f64)>>,

View File

@ -12,14 +12,13 @@ use smithay::{
},
};
pub enum Kind<U, R, SD, D> {
Xdg(ToplevelSurface<U, R, SD>),
Wl(ShellSurface<U, R, D>),
pub enum Kind<R, SD, D> {
Xdg(ToplevelSurface<R, SD>),
Wl(ShellSurface<R, D>),
}
impl<U, R, SD, D> Kind<U, R, SD, D>
impl<R, SD, D> Kind<R, SD, D>
where
U: 'static,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static,
D: 'static,
@ -38,15 +37,14 @@ where
}
}
struct Window<U, R, SD, D> {
struct Window<R, SD, D> {
location: (i32, i32),
surface: Rectangle,
toplevel: Kind<U, R, SD, D>,
toplevel: Kind<R, SD, D>,
}
impl<U, R, SD, D> Window<U, R, SD, D>
impl<R, SD, D> Window<R, SD, D>
where
U: 'static,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static,
D: 'static,
@ -55,11 +53,11 @@ where
fn matching<F>(
&self,
point: (f64, f64),
ctoken: CompositorToken<U, R>,
ctoken: CompositorToken<R>,
get_size: F,
) -> Option<(wl_surface::WlSurface, (f64, f64))>
where
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>,
F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
{
if !self.surface.contains((point.0 as i32, point.1 as i32)) {
return None;
@ -101,9 +99,9 @@ where
found.into_inner()
}
fn self_update<F>(&mut self, ctoken: CompositorToken<U, R>, get_size: F)
fn self_update<F>(&mut self, ctoken: CompositorToken<R>, get_size: F)
where
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>,
F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
{
let (base_x, base_y) = self.location;
let (mut min_x, mut min_y, mut max_x, mut max_y) = (base_x, base_y, base_x, base_y);
@ -148,21 +146,20 @@ where
}
}
pub struct WindowMap<U, R, SD, D, F> {
ctoken: CompositorToken<U, R>,
windows: Vec<Window<U, R, SD, D>>,
pub struct WindowMap<R, SD, D, F> {
ctoken: CompositorToken<R>,
windows: Vec<Window<R, SD, D>>,
get_size: F,
}
impl<U, R, SD, D, F> WindowMap<U, R, SD, D, F>
impl<R, SD, D, F> WindowMap<R, SD, D, F>
where
F: Fn(&SurfaceAttributes<U>) -> Option<(i32, i32)>,
U: 'static,
F: Fn(&SurfaceAttributes) -> Option<(i32, i32)>,
R: Role<SubsurfaceRole> + Role<XdgSurfaceRole> + Role<ShellSurfaceRole<D>> + 'static,
SD: 'static,
D: 'static,
{
pub fn new(ctoken: CompositorToken<U, R>, get_size: F) -> WindowMap<U, R, D, SD, F> {
pub fn new(ctoken: CompositorToken<R>, get_size: F) -> WindowMap<R, D, SD, F> {
WindowMap {
ctoken,
windows: Vec::new(),
@ -170,7 +167,7 @@ where
}
}
pub fn insert(&mut self, toplevel: Kind<U, R, SD, D>, location: (i32, i32)) {
pub fn insert(&mut self, toplevel: Kind<R, SD, D>, location: (i32, i32)) {
let mut window = Window {
location,
surface: Rectangle {
@ -216,7 +213,7 @@ where
pub fn with_windows_from_bottom_to_top<Func>(&self, mut f: Func)
where
Func: FnMut(&Kind<U, R, SD, D>, (i32, i32)),
Func: FnMut(&Kind<R, SD, D>, (i32, i32)),
{
for w in self.windows.iter().rev() {
f(&w.toplevel, w.location)

View File

@ -300,7 +300,6 @@ impl Drop for EGLImages {
}
}
}
println!("RELEASING EGL BUFFER");
self.buffer.release();
}
}

View File

@ -15,15 +15,14 @@ use super::{
* wl_compositor
*/
pub(crate) fn implement_compositor<U, R, Impl>(
pub(crate) fn implement_compositor<R, Impl>(
compositor: NewResource<wl_compositor::WlCompositor>,
log: ::slog::Logger,
implem: Rc<RefCell<Impl>>,
) -> wl_compositor::WlCompositor
where
U: Default + 'static,
R: Default + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>) + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
{
compositor.implement_closure(
move |request, _compositor| match request {
@ -47,34 +46,33 @@ where
*/
// Internal implementation data of surfaces
pub(crate) struct SurfaceImplem<U, R> {
pub(crate) struct SurfaceImplem<R> {
log: ::slog::Logger,
implem: Rc<RefCell<dyn FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>)>>,
implem: Rc<RefCell<dyn FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>)>>,
}
impl<U, R> SurfaceImplem<U, R> {
fn make<Impl>(log: ::slog::Logger, implem: Rc<RefCell<Impl>>) -> SurfaceImplem<U, R>
impl<R> SurfaceImplem<R> {
fn make<Impl>(log: ::slog::Logger, implem: Rc<RefCell<Impl>>) -> SurfaceImplem<R>
where
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>) + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
{
SurfaceImplem { log, implem }
}
}
impl<U, R> SurfaceImplem<U, R>
impl<R> SurfaceImplem<R>
where
U: 'static,
R: 'static,
{
fn receive_surface_request(&mut self, req: wl_surface::Request, surface: wl_surface::WlSurface) {
match req {
wl_surface::Request::Attach { buffer, x, y } => {
SurfaceData::<U, R>::with_data(&surface, |d| {
SurfaceData::<R>::with_data(&surface, |d| {
d.buffer = Some(buffer.map(|b| (b.clone(), (x, y))))
});
}
wl_surface::Request::Damage { x, y, width, height } => {
SurfaceData::<U, R>::with_data(&surface, |d| {
SurfaceData::<R>::with_data(&surface, |d| {
d.damage = Damage::Surface(Rectangle { x, y, width, height })
});
}
@ -88,14 +86,14 @@ where
let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap();
attributes_mutex.lock().unwrap().clone()
});
SurfaceData::<U, R>::with_data(&surface, |d| d.opaque_region = attributes);
SurfaceData::<R>::with_data(&surface, |d| d.opaque_region = attributes);
}
wl_surface::Request::SetInputRegion { region } => {
let attributes = region.map(|r| {
let attributes_mutex = r.as_ref().user_data::<Mutex<RegionAttributes>>().unwrap();
attributes_mutex.lock().unwrap().clone()
});
SurfaceData::<U, R>::with_data(&surface, |d| d.input_region = attributes);
SurfaceData::<R>::with_data(&surface, |d| d.input_region = attributes);
}
wl_surface::Request::Commit => {
let mut user_impl = self.implem.borrow_mut();
@ -103,13 +101,13 @@ where
(&mut *user_impl)(SurfaceEvent::Commit, surface, CompositorToken::make());
}
wl_surface::Request::SetBufferTransform { transform } => {
SurfaceData::<U, R>::with_data(&surface, |d| d.buffer_transform = transform);
SurfaceData::<R>::with_data(&surface, |d| d.buffer_transform = transform);
}
wl_surface::Request::SetBufferScale { scale } => {
SurfaceData::<U, R>::with_data(&surface, |d| d.buffer_scale = scale);
SurfaceData::<R>::with_data(&surface, |d| d.buffer_scale = scale);
}
wl_surface::Request::DamageBuffer { x, y, width, height } => {
SurfaceData::<U, R>::with_data(&surface, |d| {
SurfaceData::<R>::with_data(&surface, |d| {
d.damage = Damage::Buffer(Rectangle { x, y, width, height })
});
}
@ -121,25 +119,24 @@ where
}
}
fn implement_surface<U, R, Impl>(
fn implement_surface<R, Impl>(
surface: NewResource<wl_surface::WlSurface>,
log: ::slog::Logger,
implem: Rc<RefCell<Impl>>,
) -> wl_surface::WlSurface
where
U: Default + 'static,
R: Default + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<U, R>) + 'static,
Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken<R>) + 'static,
{
let surface = surface.implement_closure(
{
let mut implem = SurfaceImplem::make(log, implem);
move |req, surface| implem.receive_surface_request(req, surface)
},
Some(|surface| SurfaceData::<U, R>::cleanup(&surface)),
SurfaceData::<U, R>::new(),
Some(|surface| SurfaceData::<R>::cleanup(&surface)),
SurfaceData::<R>::new(),
);
SurfaceData::<U, R>::init(&surface);
SurfaceData::<R>::init(&surface);
surface
}
@ -176,24 +173,23 @@ fn implement_region(region: NewResource<wl_region::WlRegion>) -> wl_region::WlRe
* wl_subcompositor
*/
pub(crate) fn implement_subcompositor<U, R>(
pub(crate) fn implement_subcompositor<R>(
subcompositor: NewResource<wl_subcompositor::WlSubcompositor>,
) -> wl_subcompositor::WlSubcompositor
where
R: RoleType + Role<SubsurfaceRole> + 'static,
U: 'static,
{
subcompositor.implement_closure(
move |request, subcompositor| match request {
wl_subcompositor::Request::GetSubsurface { id, surface, parent } => {
if let Err(()) = SurfaceData::<U, R>::set_parent(&surface, &parent) {
if let Err(()) = SurfaceData::<R>::set_parent(&surface, &parent) {
subcompositor.as_ref().post_error(
wl_subcompositor::Error::BadSurface as u32,
"Surface already has a role.".into(),
);
return;
}
implement_subsurface::<U, R>(id, surface.clone());
implement_subsurface::<R>(id, surface.clone());
}
wl_subcompositor::Request::Destroy => {}
_ => unreachable!(),
@ -207,36 +203,34 @@ where
* wl_subsurface
*/
fn with_subsurface_attributes<U, R, F>(subsurface: &wl_subsurface::WlSubsurface, f: F)
fn with_subsurface_attributes<R, F>(subsurface: &wl_subsurface::WlSubsurface, f: F)
where
F: FnOnce(&mut SubsurfaceRole),
U: 'static,
R: RoleType + Role<SubsurfaceRole> + 'static,
{
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
SurfaceData::<U, R>::with_role_data::<SubsurfaceRole, _, _>(surface, |d| f(d))
SurfaceData::<R>::with_role_data::<SubsurfaceRole, _, _>(surface, |d| f(d))
.expect("The surface does not have a subsurface role while it has a wl_subsurface?!");
}
fn implement_subsurface<U, R>(
fn implement_subsurface<R>(
subsurface: NewResource<wl_subsurface::WlSubsurface>,
surface: wl_surface::WlSurface,
) -> wl_subsurface::WlSubsurface
where
U: 'static,
R: RoleType + Role<SubsurfaceRole> + 'static,
{
subsurface.implement_closure(
|request, subsurface| {
match request {
wl_subsurface::Request::SetPosition { x, y } => {
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| {
with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
attrs.location = (x, y);
})
}
wl_subsurface::Request::PlaceAbove { sibling } => {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
if let Err(()) = SurfaceData::<U, R>::reorder(surface, Location::After, &sibling) {
if let Err(()) = SurfaceData::<R>::reorder(surface, Location::After, &sibling) {
subsurface.as_ref().post_error(
wl_subsurface::Error::BadSurface as u32,
"Provided surface is not a sibling or parent.".into(),
@ -245,20 +239,18 @@ where
}
wl_subsurface::Request::PlaceBelow { sibling } => {
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
if let Err(()) = SurfaceData::<U, R>::reorder(surface, Location::Before, &sibling) {
if let Err(()) = SurfaceData::<R>::reorder(surface, Location::Before, &sibling) {
subsurface.as_ref().post_error(
wl_subsurface::Error::BadSurface as u32,
"Provided surface is not a sibling or parent.".into(),
)
}
}
wl_subsurface::Request::SetSync => {
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| {
wl_subsurface::Request::SetSync => with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
attrs.sync = true;
})
}
}),
wl_subsurface::Request::SetDesync => {
with_subsurface_attributes::<U, R, _>(&subsurface, |attrs| {
with_subsurface_attributes::<R, _>(&subsurface, |attrs| {
attrs.sync = false;
})
}
@ -268,18 +260,17 @@ where
_ => unreachable!(),
}
},
Some(|subsurface| destroy_subsurface::<U, R>(&subsurface)),
Some(|subsurface| destroy_subsurface::<R>(&subsurface)),
surface,
)
}
fn destroy_subsurface<U, R>(subsurface: &wl_subsurface::WlSubsurface)
fn destroy_subsurface<R>(subsurface: &wl_subsurface::WlSubsurface)
where
U: 'static,
R: RoleType + Role<SubsurfaceRole> + 'static,
{
let surface = subsurface.as_ref().user_data::<wl_surface::WlSurface>().unwrap();
if surface.as_ref().is_alive() {
SurfaceData::<U, R>::unset_parent(&surface);
SurfaceData::<R>::unset_parent(&surface);
}
}

View File

@ -32,14 +32,6 @@
//! # #[macro_use] extern crate smithay;
//! use smithay::wayland::compositor::compositor_init;
//!
//! // Define some user data to be associated with the surfaces.
//! // It must implement the Default trait, which will represent the state of a surface which
//! // has just been created.
//! #[derive(Default)]
//! struct MyData {
//! // whatever you need here
//! }
//!
//! // Declare the roles enum
//! define_roles!(MyRoles);
//!
@ -47,7 +39,7 @@
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! // Call the init function:
//! let (token, _, _) = compositor_init::<MyData, MyRoles, _, _>(
//! let (token, _, _) = compositor_init::<MyRoles, _, _>(
//! &mut display,
//! |request, surface, compositor_token| {
//! /*
@ -112,8 +104,7 @@ pub enum Damage {
}
#[derive(Copy, Clone, Default)]
struct Marker<U, R> {
_u: ::std::marker::PhantomData<U>,
struct Marker<R> {
_r: ::std::marker::PhantomData<R>,
}
@ -125,7 +116,7 @@ struct Marker<U, R> {
///
/// You are responsible for setting those values as you see fit to avoid
/// processing them two times.
pub struct SurfaceAttributes<U> {
pub struct SurfaceAttributes {
/// Buffer defining the contents of the surface
///
/// The tuple represent the coordinates of this buffer
@ -164,11 +155,11 @@ pub struct SurfaceAttributes<U> {
/// User-controlled data
///
/// This is your field to host whatever you need.
pub user_data: U,
pub user_data: ::wayland_commons::utils::UserDataMap,
}
impl<U: Default> Default for SurfaceAttributes<U> {
fn default() -> SurfaceAttributes<U> {
impl Default for SurfaceAttributes {
fn default() -> SurfaceAttributes {
SurfaceAttributes {
buffer: None,
buffer_scale: 1,
@ -176,7 +167,7 @@ impl<U: Default> Default for SurfaceAttributes<U> {
opaque_region: None,
input_region: None,
damage: Damage::Full,
user_data: Default::default(),
user_data: ::wayland_commons::utils::UserDataMap::new(),
}
}
}
@ -239,33 +230,30 @@ impl Default for RegionAttributes {
/// access data associated with the [`wl_surface`](wayland_server::protocol::wl_surface)
/// and [`wl_region`](wayland_server::protocol::wl_region) managed
/// by the `CompositorGlobal` that provided it.
pub struct CompositorToken<U, R> {
_data: ::std::marker::PhantomData<*mut U>,
pub struct CompositorToken<R> {
_role: ::std::marker::PhantomData<*mut R>,
}
// we implement them manually because #[derive(..)] would require
// U: Clone and R: Clone
impl<U, R> Copy for CompositorToken<U, R> {}
impl<U, R> Clone for CompositorToken<U, R> {
fn clone(&self) -> CompositorToken<U, R> {
// we implement them manually because #[derive(..)] would require R: Clone
impl<R> Copy for CompositorToken<R> {}
impl<R> Clone for CompositorToken<R> {
fn clone(&self) -> CompositorToken<R> {
*self
}
}
unsafe impl<U, R> Send for CompositorToken<U, R> {}
unsafe impl<U, R> Sync for CompositorToken<U, R> {}
unsafe impl<R> Send for CompositorToken<R> {}
unsafe impl<R> Sync for CompositorToken<R> {}
impl<U, R> CompositorToken<U, R> {
pub(crate) fn make() -> CompositorToken<U, R> {
impl<R> CompositorToken<R> {
pub(crate) fn make() -> CompositorToken<R> {
CompositorToken {
_data: ::std::marker::PhantomData,
_role: ::std::marker::PhantomData,
}
}
}
impl<U: 'static, R: 'static> CompositorToken<U, R> {
impl<R: 'static> CompositorToken<R> {
/// Access the data of a surface
///
/// The closure will be called with the contents of the data associated with this surface.
@ -274,15 +262,14 @@ impl<U: 'static, R: 'static> CompositorToken<U, R> {
/// will panic (having more than one compositor is not supported).
pub fn with_surface_data<F, T>(&self, surface: &WlSurface, f: F) -> T
where
F: FnOnce(&mut SurfaceAttributes<U>) -> T,
F: FnOnce(&mut SurfaceAttributes) -> T,
{
SurfaceData::<U, R>::with_data(surface, f)
SurfaceData::<R>::with_data(surface, f)
}
}
impl<U, R> CompositorToken<U, R>
impl<R> CompositorToken<R>
where
U: 'static,
R: RoleType + Role<SubsurfaceRole> + 'static,
{
/// Access the data of a surface tree from bottom to top
@ -319,11 +306,11 @@ where
processor: F2,
post_filter: F3,
) where
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool,
F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{
SurfaceData::<U, R>::map_tree(surface, &initial, filter, processor, post_filter, false);
SurfaceData::<R>::map_tree(surface, &initial, filter, processor, post_filter, false);
}
/// Access the data of a surface tree from top to bottom
@ -340,11 +327,11 @@ where
processor: F2,
post_filter: F3,
) where
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool,
F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{
SurfaceData::<U, R>::map_tree(surface, &initial, filter, processor, post_filter, true);
SurfaceData::<R>::map_tree(surface, &initial, filter, processor, post_filter, true);
}
/// Retrieve the parent of this surface
@ -354,7 +341,7 @@ where
/// If the surface is not managed by the `CompositorGlobal` that provided this token, this
/// will panic (having more than one compositor is not supported).
pub fn get_parent(&self, surface: &WlSurface) -> Option<WlSurface> {
SurfaceData::<U, R>::get_parent(surface)
SurfaceData::<R>::get_parent(surface)
}
/// Retrieve the children of this surface
@ -362,17 +349,17 @@ where
/// If the surface is not managed by the `CompositorGlobal` that provided this token, this
/// will panic (having more than one compositor is not supported).
pub fn get_children(&self, surface: &WlSurface) -> Vec<WlSurface> {
SurfaceData::<U, R>::get_children(surface)
SurfaceData::<R>::get_children(surface)
}
}
impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
impl<R: RoleType + 'static> CompositorToken<R> {
/// Check whether this surface as a role or not
///
/// If the surface is not managed by the `CompositorGlobal` that provided this token, this
/// will panic (having more than one compositor is not supported).
pub fn has_a_role(&self, surface: &WlSurface) -> bool {
SurfaceData::<U, R>::has_a_role(surface)
SurfaceData::<R>::has_a_role(surface)
}
/// Check whether this surface as a specific role
@ -383,7 +370,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
where
R: Role<RoleData>,
{
SurfaceData::<U, R>::has_role::<RoleData>(surface)
SurfaceData::<R>::has_role::<RoleData>(surface)
}
/// Register that this surface has given role with default data
@ -397,7 +384,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
R: Role<RoleData>,
RoleData: Default,
{
SurfaceData::<U, R>::give_role::<RoleData>(surface)
SurfaceData::<R>::give_role::<RoleData>(surface)
}
/// Register that this surface has given role with given data
@ -410,7 +397,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
where
R: Role<RoleData>,
{
SurfaceData::<U, R>::give_role_with::<RoleData>(surface, data)
SurfaceData::<R>::give_role_with::<RoleData>(surface, data)
}
/// Access the role data of a surface
@ -424,7 +411,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
R: Role<RoleData>,
F: FnOnce(&mut RoleData) -> T,
{
SurfaceData::<U, R>::with_role_data::<RoleData, _, _>(surface, f)
SurfaceData::<R>::with_role_data::<RoleData, _, _>(surface, f)
}
/// Register that this surface does not have a role any longer and retrieve the data
@ -437,7 +424,7 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
where
R: Role<RoleData>,
{
SurfaceData::<U, R>::remove_role::<RoleData>(surface)
SurfaceData::<R>::remove_role::<RoleData>(surface)
}
/// Retrieve the metadata associated with a `wl_region`
@ -461,30 +448,29 @@ impl<U: 'static, R: RoleType + 'static> CompositorToken<U, R> {
///
/// It also returns the two global handles, in case you wish to remove these
/// globals from the event loop in the future.
pub fn compositor_init<U, R, Impl, L>(
pub fn compositor_init<R, Impl, L>(
display: &mut Display,
implem: Impl,
logger: L,
) -> (
CompositorToken<U, R>,
CompositorToken<R>,
Global<wl_compositor::WlCompositor>,
Global<wl_subcompositor::WlSubcompositor>,
)
where
L: Into<Option<::slog::Logger>>,
U: Default + 'static,
R: Default + RoleType + Role<SubsurfaceRole> + 'static,
Impl: FnMut(SurfaceEvent, WlSurface, CompositorToken<U, R>) + 'static,
Impl: FnMut(SurfaceEvent, WlSurface, CompositorToken<R>) + 'static,
{
let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "compositor_handler"));
let implem = Rc::new(RefCell::new(implem));
let compositor = display.create_global(4, move |new_compositor, _version| {
self::handlers::implement_compositor::<U, R, Impl>(new_compositor, log.clone(), implem.clone());
self::handlers::implement_compositor::<R, Impl>(new_compositor, log.clone(), implem.clone());
});
let subcompositor = display.create_global(1, move |new_subcompositor, _version| {
self::handlers::implement_subcompositor::<U, R>(new_subcompositor);
self::handlers::implement_subcompositor::<R>(new_subcompositor);
});
(CompositorToken::make(), compositor, subcompositor)

View File

@ -15,11 +15,11 @@ use wayland_server::protocol::wl_surface::WlSurface;
///
/// Each node also appears within its children list, to allow relative placement
/// between them.
pub struct SurfaceData<U, R> {
pub struct SurfaceData<R> {
parent: Option<WlSurface>,
children: Vec<WlSurface>,
role: R,
attributes: SurfaceAttributes<U>,
attributes: SurfaceAttributes,
}
pub enum Location {
@ -37,8 +37,8 @@ pub enum TraversalAction<T> {
Break,
}
impl<U: Default, R: Default> SurfaceData<U, R> {
pub fn new() -> Mutex<SurfaceData<U, R>> {
impl<R: Default> SurfaceData<R> {
pub fn new() -> Mutex<SurfaceData<R>> {
Mutex::new(SurfaceData {
parent: None,
children: vec![],
@ -48,14 +48,13 @@ impl<U: Default, R: Default> SurfaceData<U, R> {
}
}
impl<U, R> SurfaceData<U, R>
impl<R> SurfaceData<R>
where
U: 'static,
R: 'static,
{
/// Initializes the surface, must be called at creation for state coherence
pub fn init(surface: &WlSurface) {
let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut my_data = my_data_mutex.lock().unwrap();
debug_assert!(my_data.children.len() == 0);
my_data.children.push(surface.clone());
@ -63,14 +62,11 @@ where
/// Cleans the `as_ref().user_data` of that surface, must be called when it is destroyed
pub fn cleanup(surface: &WlSurface) {
let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let my_data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut my_data = my_data_mutex.lock().unwrap();
if let Some(old_parent) = my_data.parent.take() {
// We had a parent, lets unregister ourselves from it
let old_parent_mutex = old_parent
.as_ref()
.user_data::<Mutex<SurfaceData<U, R>>>()
.unwrap();
let old_parent_mutex = old_parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut old_parent_guard = old_parent_mutex.lock().unwrap();
old_parent_guard
.children
@ -82,17 +78,17 @@ where
if child.as_ref().equals(surface.as_ref()) {
continue;
}
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut child_guard = child_mutex.lock().unwrap();
child_guard.parent = None;
}
}
}
impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
impl<R: RoleType + 'static> SurfaceData<R> {
pub fn has_a_role(surface: &WlSurface) -> bool {
debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let data_guard = data_mutex.lock().unwrap();
<R as RoleType>::has_role(&data_guard.role)
}
@ -103,7 +99,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
R: Role<RoleData>,
{
debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::has(&data_guard.role)
}
@ -115,7 +111,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
RoleData: Default,
{
debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::set(&mut data_guard.role)
}
@ -128,7 +124,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
R: Role<RoleData>,
{
debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::set_with(&mut data_guard.role, data)
}
@ -142,7 +138,7 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
R: Role<RoleData>,
{
debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap();
<R as Role<RoleData>>::unset(&mut data_guard.role)
}
@ -154,17 +150,17 @@ impl<U: 'static, R: RoleType + 'static> SurfaceData<U, R> {
F: FnOnce(&mut RoleData) -> T,
{
debug_assert!(surface.as_ref().is_alive());
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap();
let data = <R as Role<RoleData>>::data_mut(&mut data_guard.role)?;
Ok(f(data))
}
}
impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R> {
impl<R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<R> {
/// Checks if the first surface is an ancestor of the second
pub fn is_ancestor(a: &WlSurface, b: &WlSurface) -> bool {
let b_mutex = b.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let b_mutex = b.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let b_guard = b_mutex.lock().unwrap();
if let Some(ref parent) = b_guard.parent {
if parent.as_ref().equals(a.as_ref()) {
@ -191,7 +187,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
// change child's parent
{
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut child_guard = child_mutex.lock().unwrap();
// if surface already has a role, it cannot become a subsurface
<R as Role<SubsurfaceRole>>::set(&mut child_guard.role)?;
@ -200,7 +196,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
}
// register child to new parent
{
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut parent_guard = parent_mutex.lock().unwrap();
parent_guard.children.push(child.clone())
}
@ -213,7 +209,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
pub fn unset_parent(child: &WlSurface) {
debug_assert!(child.as_ref().is_alive());
let old_parent = {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut child_guard = child_mutex.lock().unwrap();
let old_parent = child_guard.parent.take();
if old_parent.is_some() {
@ -225,10 +221,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
};
// unregister from our parent
if let Some(old_parent) = old_parent {
let parent_mutex = old_parent
.as_ref()
.user_data::<Mutex<SurfaceData<U, R>>>()
.unwrap();
let parent_mutex = old_parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut parent_guard = parent_mutex.lock().unwrap();
parent_guard
.children
@ -238,14 +231,14 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
/// Retrieve the parent surface (if any) of this surface
pub fn get_parent(child: &WlSurface) -> Option<WlSurface> {
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let child_mutex = child.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let child_guard = child_mutex.lock().unwrap();
child_guard.parent.as_ref().cloned()
}
/// Retrieve the children surface (if any) of this surface
pub fn get_children(parent: &WlSurface) -> Vec<WlSurface> {
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let parent_guard = parent_mutex.lock().unwrap();
parent_guard
.children
@ -260,7 +253,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
/// Fails if `relative_to` is not a sibling or parent of `surface`.
pub fn reorder(surface: &WlSurface, to: Location, relative_to: &WlSurface) -> Result<(), ()> {
let parent = {
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let data_guard = data_mutex.lock().unwrap();
data_guard.parent.as_ref().cloned().unwrap()
};
@ -274,7 +267,7 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
None
}
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let parent_mutex = parent.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut parent_guard = parent_mutex.lock().unwrap();
let my_index = index_of(surface, &parent_guard.children).unwrap();
let mut other_index = match index_of(relative_to, &parent_guard.children) {
@ -294,18 +287,18 @@ impl<U: 'static, R: RoleType + Role<SubsurfaceRole> + 'static> SurfaceData<U, R>
}
}
impl<U: 'static, R: 'static> SurfaceData<U, R> {
impl<R: 'static> SurfaceData<R> {
/// Access the attributes associated with a surface
///
/// Note that an internal lock is taken during access of this data,
/// so the tree cannot be manipulated at the same time
pub fn with_data<T, F>(surface: &WlSurface, f: F) -> T
where
F: FnOnce(&mut SurfaceAttributes<U>) -> T,
F: FnOnce(&mut SurfaceAttributes) -> T,
{
let data_mutex = surface
.as_ref()
.user_data::<Mutex<SurfaceData<U, R>>>()
.user_data::<Mutex<SurfaceData<R>>>()
.expect("Accessing the data of foreign surfaces is not supported.");
let mut data_guard = data_mutex.lock().unwrap();
f(&mut data_guard.attributes)
@ -332,9 +325,9 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
mut post_filter: F3,
reverse: bool,
) where
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool,
F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{
Self::map(
surface,
@ -356,11 +349,11 @@ impl<U: 'static, R: 'static> SurfaceData<U, R> {
reverse: bool,
) -> bool
where
F1: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes<U>, &mut R, &T) -> bool,
F1: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction<T>,
F2: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T),
F3: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> bool,
{
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<U, R>>>().unwrap();
let data_mutex = surface.as_ref().user_data::<Mutex<SurfaceData<R>>>().unwrap();
let mut data_guard = data_mutex.lock().unwrap();
let data_guard = &mut *data_guard;
// call the filter on ourselves

View File

@ -13,7 +13,7 @@ use crate::wayland::{
use super::{with_source_metadata, DataDeviceData, DnDIconRole, SeatData};
pub(crate) struct DnDGrab<U, R> {
pub(crate) struct DnDGrab<R> {
data_source: Option<wl_data_source::WlDataSource>,
current_focus: Option<wl_surface::WlSurface>,
pending_offers: Vec<wl_data_offer::WlDataOffer>,
@ -21,19 +21,19 @@ pub(crate) struct DnDGrab<U, R> {
icon: Option<wl_surface::WlSurface>,
origin: wl_surface::WlSurface,
callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
seat: Seat,
}
impl<U: 'static, R: Role<DnDIconRole> + 'static> DnDGrab<U, R> {
impl<R: Role<DnDIconRole> + 'static> DnDGrab<R> {
pub(crate) fn new(
source: Option<wl_data_source::WlDataSource>,
origin: wl_surface::WlSurface,
seat: Seat,
icon: Option<wl_surface::WlSurface>,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
callback: Rc<RefCell<dyn FnMut(super::DataDeviceEvent)>>,
) -> DnDGrab<U, R> {
) -> DnDGrab<R> {
DnDGrab {
data_source: source,
current_focus: None,
@ -48,7 +48,7 @@ impl<U: 'static, R: Role<DnDIconRole> + 'static> DnDGrab<U, R> {
}
}
impl<U: 'static, R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<U, R> {
impl<R: Role<DnDIconRole> + 'static> PointerGrab for DnDGrab<R> {
fn motion(
&mut self,
_handle: &mut PointerInnerHandle<'_>,

View File

@ -43,7 +43,7 @@
//! # fn main(){
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = compositor_init::<(), Roles, _, _>(&mut display, |_, _, _| {}, None);
//! # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
//! // init the data device:
//! init_data_device(
//! &mut display, // the display
@ -286,18 +286,17 @@ impl SeatData {
/// and the second argument is the preferred action reported by the target. If no action should be
/// chosen (and thus the drag'n'drop should abort on drop), return
/// [`DndAction::empty()`](wayland_server::protocol::wl_data_device_manager::DndAction::empty).
pub fn init_data_device<F, C, U, R, L>(
pub fn init_data_device<F, C, R, L>(
display: &mut Display,
callback: C,
action_choice: F,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
logger: L,
) -> Global<wl_data_device_manager::WlDataDeviceManager>
where
F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static,
U: 'static,
L: Into<Option<::slog::Logger>>,
{
let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "data_device_mgr"));
@ -378,18 +377,17 @@ where
}
}
fn implement_ddm<F, C, U, R>(
fn implement_ddm<F, C, R>(
new_ddm: NewResource<wl_data_device_manager::WlDataDeviceManager>,
callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<F>>,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
log: ::slog::Logger,
) -> wl_data_device_manager::WlDataDeviceManager
where
F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static,
U: 'static,
{
use self::wl_data_device_manager::Request;
new_ddm.implement_closure(
@ -429,19 +427,18 @@ struct DataDeviceData {
action_choice: Rc<RefCell<dyn FnMut(DndAction, DndAction) -> DndAction + 'static>>,
}
fn implement_data_device<F, C, U, R>(
fn implement_data_device<F, C, R>(
new_dd: NewResource<wl_data_device::WlDataDevice>,
seat: Seat,
callback: Rc<RefCell<C>>,
action_choice: Rc<RefCell<F>>,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
log: ::slog::Logger,
) -> wl_data_device::WlDataDevice
where
F: FnMut(DndAction, DndAction) -> DndAction + 'static,
C: FnMut(DataDeviceEvent) + 'static,
R: Role<DnDIconRole> + 'static,
U: 'static,
{
use self::wl_data_device::Request;
let dd_data = DataDeviceData {

View File

@ -20,7 +20,7 @@
//! # fn main(){
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = compositor_init::<(), Roles, _, _>(&mut display, |_, _, _| {}, None);
//! # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
//! // insert the seat:
//! let (seat, seat_global) = Seat::new(
//! &mut display, // the display
@ -121,14 +121,13 @@ impl Seat {
/// You are provided with the state token to retrieve it (allowing
/// you to add or remove capabilities from it), and the global handle,
/// in case you want to remove it.
pub fn new<U, R, L>(
pub fn new<R, L>(
display: &mut Display,
name: String,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
logger: L,
) -> (Seat, Global<wl_seat::WlSeat>)
where
U: 'static,
R: Role<CursorImageRole> + 'static,
L: Into<Option<::slog::Logger>>,
{
@ -194,7 +193,7 @@ impl Seat {
/// # fn main(){
/// # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
/// # let mut display = wayland_server::Display::new(event_loop.handle());
/// # let (compositor_token, _, _) = compositor_init::<(), Roles, _, _>(&mut display, |_, _, _| {}, None);
/// # let (compositor_token, _, _) = compositor_init::<Roles, _, _>(&mut display, |_, _, _| {}, None);
/// # let (mut seat, seat_global) = Seat::new(
/// # &mut display,
/// # "seat-0".into(),
@ -207,9 +206,8 @@ impl Seat {
/// );
/// # }
/// ```
pub fn add_pointer<U, R, F>(&mut self, token: CompositorToken<U, R>, cb: F) -> PointerHandle
pub fn add_pointer<R, F>(&mut self, token: CompositorToken<R>, cb: F) -> PointerHandle
where
U: 'static,
R: Role<CursorImageRole> + 'static,
F: FnMut(CursorImageStatus) + 'static,
{
@ -336,14 +334,13 @@ impl ::std::cmp::PartialEq for Seat {
}
}
fn implement_seat<U, R>(
fn implement_seat<R>(
new_seat: NewResource<wl_seat::WlSeat>,
arc: Rc<SeatRc>,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
) -> wl_seat::WlSeat
where
R: Role<CursorImageRole> + 'static,
U: 'static,
{
let dest_arc = arc.clone();
new_seat.implement_closure(

View File

@ -46,9 +46,8 @@ struct PointerInternal {
}
impl PointerInternal {
fn new<F, U, R>(token: CompositorToken<U, R>, mut cb: F) -> PointerInternal
fn new<F, R>(token: CompositorToken<R>, mut cb: F) -> PointerInternal
where
U: 'static,
R: Role<CursorImageRole> + 'static,
F: FnMut(CursorImageStatus) + 'static,
{
@ -514,10 +513,9 @@ impl AxisFrame {
}
}
pub(crate) fn create_pointer_handler<F, U, R>(token: CompositorToken<U, R>, cb: F) -> PointerHandle
pub(crate) fn create_pointer_handler<F, R>(token: CompositorToken<R>, cb: F) -> PointerHandle
where
R: Role<CursorImageRole> + 'static,
U: 'static,
F: FnMut(CursorImageStatus) + 'static,
{
PointerHandle {
@ -525,14 +523,13 @@ where
}
}
pub(crate) fn implement_pointer<U, R>(
pub(crate) fn implement_pointer<R>(
new_pointer: NewResource<WlPointer>,
handle: Option<&PointerHandle>,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
) -> WlPointer
where
R: Role<CursorImageRole> + 'static,
U: 'static,
{
let inner = handle.map(|h| h.inner.clone());
let destructor = match inner.clone() {

View File

@ -52,7 +52,7 @@
//! # fn main() {
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<(), MyRoles, _, _>(
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>(
//! # &mut display,
//! # |_, _, _| {},
//! # None
@ -62,7 +62,7 @@
//! // token from the compositor implementation
//! compositor_token,
//! // your implementation
//! |event: ShellRequest<_, _, MyShellSurfaceData>| { /* ... */ },
//! |event: ShellRequest<_, MyShellSurfaceData>| { /* ... */ },
//! None // put a logger if you want
//! );
//!
@ -97,16 +97,15 @@ pub struct ShellSurfaceRole<D: 'static> {
}
/// A handle to a shell surface
pub struct ShellSurface<U, R, D> {
pub struct ShellSurface<R, D> {
wl_surface: wl_surface::WlSurface,
shell_surface: wl_shell_surface::WlShellSurface,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
_d: ::std::marker::PhantomData<D>,
}
impl<U, R, D> ShellSurface<U, R, D>
impl<R, D> ShellSurface<R, D>
where
U: 'static,
R: Role<ShellSurfaceRole<D>> + 'static,
D: 'static,
{
@ -235,13 +234,13 @@ pub enum ShellSurfaceKind {
}
/// A request triggered by a `wl_shell_surface`
pub enum ShellRequest<U, R, D> {
pub enum ShellRequest<R, D> {
/// A new shell surface was created
///
/// by default it has no kind and this should not be displayed
NewShellSurface {
/// The created surface
surface: ShellSurface<U, R, D>,
surface: ShellSurface<R, D>,
},
/// A pong event
///
@ -249,14 +248,14 @@ pub enum ShellRequest<U, R, D> {
/// event, smithay has already checked that the responded serial was valid.
Pong {
/// The surface that sent the pong
surface: ShellSurface<U, R, D>,
surface: ShellSurface<R, D>,
},
/// Start of an interactive move
///
/// The surface requests that an interactive move is started on it
Move {
/// The surface requesting the move
surface: ShellSurface<U, R, D>,
surface: ShellSurface<R, D>,
/// Serial of the implicit grab that initiated the move
serial: u32,
/// Seat associated with the move
@ -267,7 +266,7 @@ pub enum ShellRequest<U, R, D> {
/// The surface requests that an interactive resize is started on it
Resize {
/// The surface requesting the resize
surface: ShellSurface<U, R, D>,
surface: ShellSurface<R, D>,
/// Serial of the implicit grab that initiated the resize
serial: u32,
/// Seat associated with the resize
@ -278,7 +277,7 @@ pub enum ShellRequest<U, R, D> {
/// The surface changed its kind
SetKind {
/// The surface
surface: ShellSurface<U, R, D>,
surface: ShellSurface<R, D>,
/// Its new kind
kind: ShellSurfaceKind,
},
@ -288,13 +287,12 @@ pub enum ShellRequest<U, R, D> {
///
/// This state allows you to retrieve a list of surfaces
/// currently known to the shell global.
pub struct ShellState<U, R, D> {
known_surfaces: Vec<ShellSurface<U, R, D>>,
pub struct ShellState<R, D> {
known_surfaces: Vec<ShellSurface<R, D>>,
}
impl<U, R, D> ShellState<U, R, D>
impl<R, D> ShellState<R, D>
where
U: 'static,
R: Role<ShellSurfaceRole<D>> + 'static,
D: 'static,
{
@ -304,24 +302,23 @@ where
}
/// Access all the shell surfaces known by this handler
pub fn surfaces(&self) -> &[ShellSurface<U, R, D>] {
pub fn surfaces(&self) -> &[ShellSurface<R, D>] {
&self.known_surfaces[..]
}
}
/// Create a new `wl_shell` global
pub fn wl_shell_init<U, R, D, L, Impl>(
pub fn wl_shell_init<R, D, L, Impl>(
display: &mut Display,
ctoken: CompositorToken<U, R>,
ctoken: CompositorToken<R>,
implementation: Impl,
logger: L,
) -> (Arc<Mutex<ShellState<U, R, D>>>, Global<wl_shell::WlShell>)
) -> (Arc<Mutex<ShellState<R, D>>>, Global<wl_shell::WlShell>)
where
U: 'static,
D: Default + 'static,
R: Role<ShellSurfaceRole<D>> + 'static,
L: Into<Option<::slog::Logger>>,
Impl: FnMut(ShellRequest<U, R, D>) + 'static,
Impl: FnMut(ShellRequest<R, D>) + 'static,
{
let _log = crate::slog_or_stdlog(logger);

View File

@ -13,16 +13,15 @@ use crate::wayland::compositor::{roles::Role, CompositorToken};
use super::{ShellRequest, ShellState, ShellSurface, ShellSurfaceKind, ShellSurfaceRole};
pub(crate) fn implement_shell<U, R, D, Impl>(
pub(crate) fn implement_shell<R, D, Impl>(
shell: NewResource<wl_shell::WlShell>,
ctoken: CompositorToken<U, R>,
ctoken: CompositorToken<R>,
implementation: Rc<RefCell<Impl>>,
state: Arc<Mutex<ShellState<U, R, D>>>,
state: Arc<Mutex<ShellState<R, D>>>,
) where
U: 'static,
D: Default + 'static,
R: Role<ShellSurfaceRole<D>> + 'static,
Impl: FnMut(ShellRequest<U, R, D>) + 'static,
Impl: FnMut(ShellRequest<R, D>) + 'static,
{
shell.implement_closure(
move |req, shell| {
@ -59,18 +58,17 @@ pub(crate) fn implement_shell<U, R, D, Impl>(
);
}
fn make_handle<U, R, SD>(
fn make_handle<R, SD>(
shell_surface: &wl_shell_surface::WlShellSurface,
token: CompositorToken<U, R>,
) -> ShellSurface<U, R, SD>
token: CompositorToken<R>,
) -> ShellSurface<R, SD>
where
U: 'static,
R: Role<ShellSurfaceRole<SD>> + 'static,
SD: 'static,
{
let data = shell_surface
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
ShellSurface {
wl_surface: data.surface.clone(),
@ -80,30 +78,29 @@ where
}
}
pub(crate) struct ShellSurfaceUserData<U, R, SD> {
pub(crate) struct ShellSurfaceUserData<R, SD> {
surface: wl_surface::WlSurface,
state: Arc<Mutex<ShellState<U, R, SD>>>,
state: Arc<Mutex<ShellState<R, SD>>>,
}
fn implement_shell_surface<U, R, Impl, SD>(
fn implement_shell_surface<R, Impl, SD>(
shell_surface: NewResource<wl_shell_surface::WlShellSurface>,
surface: wl_surface::WlSurface,
implementation: Rc<RefCell<Impl>>,
ctoken: CompositorToken<U, R>,
state: Arc<Mutex<ShellState<U, R, SD>>>,
ctoken: CompositorToken<R>,
state: Arc<Mutex<ShellState<R, SD>>>,
) -> wl_shell_surface::WlShellSurface
where
U: 'static,
SD: 'static,
R: Role<ShellSurfaceRole<SD>> + 'static,
Impl: FnMut(ShellRequest<U, R, SD>) + 'static,
Impl: FnMut(ShellRequest<R, SD>) + 'static,
{
use self::wl_shell_surface::Request;
shell_surface.implement_closure(
move |req, shell_surface| {
let data = shell_surface
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let mut user_impl = implementation.borrow_mut();
match req {
@ -196,7 +193,7 @@ where
Some(|shell_surface: wl_shell_surface::WlShellSurface| {
let data = shell_surface
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
data.state.lock().unwrap().cleanup_surfaces();
}),

View File

@ -35,7 +35,6 @@
//! use smithay::wayland::shell::xdg::{xdg_shell_init, XdgSurfaceRole, XdgRequest};
//! use wayland_protocols::unstable::xdg_shell::v6::server::zxdg_shell_v6::ZxdgShellV6;
//! # use wayland_server::protocol::{wl_seat, wl_output};
//! # #[derive(Default)] struct MySurfaceData;
//!
//! // define the roles type. You need to integrate the XdgSurface role:
//! define_roles!(MyRoles =>
@ -51,7 +50,7 @@
//! # fn main() {
//! # let mut event_loop = wayland_server::calloop::EventLoop::<()>::new().unwrap();
//! # let mut display = wayland_server::Display::new(event_loop.handle());
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<(), MyRoles, _, _>(
//! # let (compositor_token, _, _) = smithay::wayland::compositor::compositor_init::<MyRoles, _, _>(
//! # &mut display,
//! # |_, _, _| {},
//! # None
@ -61,7 +60,7 @@
//! // token from the compositor implementation
//! compositor_token,
//! // your implementation
//! |event: XdgRequest<_, _, MyShellData>| { /* ... */ },
//! |event: XdgRequest<_, MyShellData>| { /* ... */ },
//! None // put a logger if you want
//! );
//!
@ -259,14 +258,14 @@ impl Default for XdgSurfacePendingState {
}
}
pub(crate) struct ShellData<U, R, SD> {
pub(crate) struct ShellData<R, SD> {
log: ::slog::Logger,
compositor_token: CompositorToken<U, R>,
user_impl: Rc<RefCell<dyn FnMut(XdgRequest<U, R, SD>)>>,
shell_state: Arc<Mutex<ShellState<U, R, SD>>>,
compositor_token: CompositorToken<R>,
user_impl: Rc<RefCell<dyn FnMut(XdgRequest<R, SD>)>>,
shell_state: Arc<Mutex<ShellState<R, SD>>>,
}
impl<U, R, SD> Clone for ShellData<U, R, SD> {
impl<R, SD> Clone for ShellData<R, SD> {
fn clone(&self) -> Self {
ShellData {
log: self.log.clone(),
@ -278,22 +277,21 @@ impl<U, R, SD> Clone for ShellData<U, R, SD> {
}
/// Create a new `xdg_shell` globals
pub fn xdg_shell_init<U, R, SD, L, Impl>(
pub fn xdg_shell_init<R, SD, L, Impl>(
display: &mut Display,
ctoken: CompositorToken<U, R>,
ctoken: CompositorToken<R>,
implementation: Impl,
logger: L,
) -> (
Arc<Mutex<ShellState<U, R, SD>>>,
Arc<Mutex<ShellState<R, SD>>>,
Global<xdg_wm_base::XdgWmBase>,
Global<zxdg_shell_v6::ZxdgShellV6>,
)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static,
L: Into<Option<::slog::Logger>>,
Impl: FnMut(XdgRequest<U, R, SD>) + 'static,
Impl: FnMut(XdgRequest<R, SD>) + 'static,
{
let log = crate::slog_or_stdlog(logger);
let shell_state = Arc::new(Mutex::new(ShellState {
@ -325,24 +323,23 @@ where
///
/// This state allows you to retrieve a list of surfaces
/// currently known to the shell global.
pub struct ShellState<U, R, SD> {
known_toplevels: Vec<ToplevelSurface<U, R, SD>>,
known_popups: Vec<PopupSurface<U, R, SD>>,
pub struct ShellState<R, SD> {
known_toplevels: Vec<ToplevelSurface<R, SD>>,
known_popups: Vec<PopupSurface<R, SD>>,
}
impl<U, R, SD> ShellState<U, R, SD>
impl<R, SD> ShellState<R, SD>
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
/// Access all the shell surfaces known by this handler
pub fn toplevel_surfaces(&self) -> &[ToplevelSurface<U, R, SD>] {
pub fn toplevel_surfaces(&self) -> &[ToplevelSurface<R, SD>] {
&self.known_toplevels[..]
}
/// Access all the popup surfaces known by this handler
pub fn popup_surfaces(&self) -> &[PopupSurface<U, R, SD>] {
pub fn popup_surfaces(&self) -> &[PopupSurface<R, SD>] {
&self.known_popups[..]
}
}
@ -378,15 +375,14 @@ fn make_shell_client_data<SD: Default>() -> ShellClientData<SD> {
///
/// You can use this handle to access a storage for any
/// client-specific data you wish to associate with it.
pub struct ShellClient<U, R, SD> {
pub struct ShellClient<R, SD> {
kind: ShellClientKind,
_token: CompositorToken<U, R>,
_token: CompositorToken<R>,
_data: ::std::marker::PhantomData<*mut SD>,
}
impl<U, R, SD> ShellClient<U, R, SD>
impl<R, SD> ShellClient<R, SD>
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
@ -427,7 +423,7 @@ where
ShellClientKind::Xdg(ref shell) => {
let user_data = shell
.as_ref()
.user_data::<self::xdg_handlers::ShellUserData<U, R, SD>>()
.user_data::<self::xdg_handlers::ShellUserData<R, SD>>()
.unwrap();
let mut guard = user_data.client_data.lock().unwrap();
if guard.pending_ping == 0 {
@ -439,7 +435,7 @@ where
ShellClientKind::ZxdgV6(ref shell) => {
let user_data = shell
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellUserData<U, R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellUserData<R, SD>>()
.unwrap();
let mut guard = user_data.client_data.lock().unwrap();
if guard.pending_ping == 0 {
@ -464,7 +460,7 @@ where
ShellClientKind::Xdg(ref shell) => {
let data = shell
.as_ref()
.user_data::<self::xdg_handlers::ShellUserData<U, R, SD>>()
.user_data::<self::xdg_handlers::ShellUserData<R, SD>>()
.unwrap();
let mut guard = data.client_data.lock().unwrap();
Ok(f(&mut guard.data))
@ -472,7 +468,7 @@ where
ShellClientKind::ZxdgV6(ref shell) => {
let data = shell
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellUserData<U, R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellUserData<R, SD>>()
.unwrap();
let mut guard = data.client_data.lock().unwrap();
Ok(f(&mut guard.data))
@ -487,16 +483,15 @@ pub(crate) enum ToplevelKind {
}
/// A handle to a toplevel surface
pub struct ToplevelSurface<U, R, SD> {
pub struct ToplevelSurface<R, SD> {
wl_surface: wl_surface::WlSurface,
shell_surface: ToplevelKind,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
_shell_data: ::std::marker::PhantomData<SD>,
}
impl<U, R, SD> ToplevelSurface<U, R, SD>
impl<R, SD> ToplevelSurface<R, SD>
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
@ -517,7 +512,7 @@ where
/// Retrieve the shell client owning this toplevel surface
///
/// Returns `None` if the surface does actually no longer exist.
pub fn client(&self) -> Option<ShellClient<U, R, SD>> {
pub fn client(&self) -> Option<ShellClient<R, SD>> {
if !self.alive() {
return None;
}
@ -526,14 +521,14 @@ where
ToplevelKind::Xdg(ref s) => {
let data = s
.as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap();
ShellClientKind::Xdg(data.wm_base.clone())
}
ToplevelKind::ZxdgV6(ref s) => {
let data = s
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap();
ShellClientKind::ZxdgV6(data.shell.clone())
}
@ -554,8 +549,8 @@ where
return;
}
match self.shell_surface {
ToplevelKind::Xdg(ref s) => self::xdg_handlers::send_toplevel_configure::<U, R, SD>(s, cfg),
ToplevelKind::ZxdgV6(ref s) => self::zxdgv6_handlers::send_toplevel_configure::<U, R, SD>(s, cfg),
ToplevelKind::Xdg(ref s) => self::xdg_handlers::send_toplevel_configure::<R, SD>(s, cfg),
ToplevelKind::ZxdgV6(ref s) => self::zxdgv6_handlers::send_toplevel_configure::<R, SD>(s, cfg),
}
}
@ -580,7 +575,7 @@ where
ToplevelKind::Xdg(ref s) => {
let data = s
.as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap();
data.xdg_surface.as_ref().post_error(
xdg_surface::Error::NotConstructed as u32,
@ -590,7 +585,7 @@ where
ToplevelKind::ZxdgV6(ref s) => {
let data = s
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap();
data.xdg_surface.as_ref().post_error(
zxdg_surface_v6::Error::NotConstructed as u32,
@ -647,16 +642,15 @@ pub(crate) enum PopupKind {
///
/// This is an unified abstraction over the popup surfaces
/// of both `wl_shell` and `xdg_shell`.
pub struct PopupSurface<U, R, SD> {
pub struct PopupSurface<R, SD> {
wl_surface: wl_surface::WlSurface,
shell_surface: PopupKind,
token: CompositorToken<U, R>,
token: CompositorToken<R>,
_shell_data: ::std::marker::PhantomData<SD>,
}
impl<U, R, SD> PopupSurface<U, R, SD>
impl<R, SD> PopupSurface<R, SD>
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
@ -677,7 +671,7 @@ where
/// Retrieve the shell client owning this popup surface
///
/// Returns `None` if the surface does actually no longer exist.
pub fn client(&self) -> Option<ShellClient<U, R, SD>> {
pub fn client(&self) -> Option<ShellClient<R, SD>> {
if !self.alive() {
return None;
}
@ -686,14 +680,14 @@ where
PopupKind::Xdg(ref p) => {
let data = p
.as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap();
ShellClientKind::Xdg(data.wm_base.clone())
}
PopupKind::ZxdgV6(ref p) => {
let data = p
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap();
ShellClientKind::ZxdgV6(data.shell.clone())
}
@ -715,10 +709,10 @@ where
}
match self.shell_surface {
PopupKind::Xdg(ref p) => {
self::xdg_handlers::send_popup_configure::<U, R, SD>(p, cfg);
self::xdg_handlers::send_popup_configure::<R, SD>(p, cfg);
}
PopupKind::ZxdgV6(ref p) => {
self::zxdgv6_handlers::send_popup_configure::<U, R, SD>(p, cfg);
self::zxdgv6_handlers::send_popup_configure::<R, SD>(p, cfg);
}
}
}
@ -744,7 +738,7 @@ where
PopupKind::Xdg(ref s) => {
let data = s
.as_ref()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<U, R, SD>>()
.user_data::<self::xdg_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap();
data.xdg_surface.as_ref().post_error(
xdg_surface::Error::NotConstructed as u32,
@ -754,7 +748,7 @@ where
PopupKind::ZxdgV6(ref s) => {
let data = s
.as_ref()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<U, R, SD>>()
.user_data::<self::zxdgv6_handlers::ShellSurfaceUserData<R, SD>>()
.unwrap();
data.xdg_surface.as_ref().post_error(
zxdg_surface_v6::Error::NotConstructed as u32,
@ -843,11 +837,11 @@ pub struct PopupConfigure {
/// for you directly.
///
/// Depending on what you want to do, you might ignore some of them
pub enum XdgRequest<U, R, SD> {
pub enum XdgRequest<R, SD> {
/// A new shell client was instantiated
NewClient {
/// the client
client: ShellClient<U, R, SD>,
client: ShellClient<R, SD>,
},
/// The pong for a pending ping of this shell client was received
///
@ -855,7 +849,7 @@ pub enum XdgRequest<U, R, SD> {
/// from the pending ping.
ClientPong {
/// the client
client: ShellClient<U, R, SD>,
client: ShellClient<R, SD>,
},
/// A new toplevel surface was created
///
@ -863,7 +857,7 @@ pub enum XdgRequest<U, R, SD> {
/// client as to how its window should be
NewToplevel {
/// the surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
},
/// A new popup surface was created
///
@ -871,12 +865,12 @@ pub enum XdgRequest<U, R, SD> {
/// client as to how its popup should be
NewPopup {
/// the surface
surface: PopupSurface<U, R, SD>,
surface: PopupSurface<R, SD>,
},
/// The client requested the start of an interactive move for this surface
Move {
/// the surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
/// the seat associated to this move
seat: wl_seat::WlSeat,
/// the grab serial
@ -885,7 +879,7 @@ pub enum XdgRequest<U, R, SD> {
/// The client requested the start of an interactive resize for this surface
Resize {
/// The surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
/// The seat associated with this resize
seat: wl_seat::WlSeat,
/// The grab serial
@ -899,7 +893,7 @@ pub enum XdgRequest<U, R, SD> {
/// the grab area.
Grab {
/// The surface
surface: PopupSurface<U, R, SD>,
surface: PopupSurface<R, SD>,
/// The seat to grab
seat: wl_seat::WlSeat,
/// The grab serial
@ -908,29 +902,29 @@ pub enum XdgRequest<U, R, SD> {
/// A toplevel surface requested to be maximized
Maximize {
/// The surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
},
/// A toplevel surface requested to stop being maximized
UnMaximize {
/// The surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
},
/// A toplevel surface requested to be set fullscreen
Fullscreen {
/// The surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
/// The output (if any) on which the fullscreen is requested
output: Option<wl_output::WlOutput>,
},
/// A toplevel surface request to stop being fullscreen
UnFullscreen {
/// The surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
},
/// A toplevel surface requested to be minimized
Minimize {
/// The surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
},
/// The client requests the window menu to be displayed on this surface at this location
///
@ -938,7 +932,7 @@ pub enum XdgRequest<U, R, SD> {
/// control of the window (maximize/minimize/close/move/etc...).
ShowWindowMenu {
/// The surface
surface: ToplevelSurface<U, R, SD>,
surface: ToplevelSurface<R, SD>,
/// The seat associated with this input grab
seat: wl_seat::WlSeat,
/// the grab serial

View File

@ -14,17 +14,16 @@ use super::{
XdgSurfacePendingState, XdgSurfaceRole,
};
pub(crate) fn implement_wm_base<U, R, SD>(
pub(crate) fn implement_wm_base<R, SD>(
shell: NewResource<xdg_wm_base::XdgWmBase>,
shell_data: &ShellData<U, R, SD>,
shell_data: &ShellData<R, SD>,
) -> xdg_wm_base::XdgWmBase
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static,
{
let shell = shell.implement_closure(
wm_implementation::<U, R, SD>,
wm_implementation::<R, SD>,
None::<fn(_)>,
ShellUserData {
shell_data: shell_data.clone(),
@ -42,15 +41,15 @@ where
* xdg_shell
*/
pub(crate) struct ShellUserData<U, R, SD> {
shell_data: ShellData<U, R, SD>,
pub(crate) struct ShellUserData<R, SD> {
shell_data: ShellData<R, SD>,
pub(crate) client_data: Mutex<ShellClientData<SD>>,
}
pub(crate) fn make_shell_client<U, R, SD>(
pub(crate) fn make_shell_client<R, SD>(
resource: &xdg_wm_base::XdgWmBase,
token: CompositorToken<U, R>,
) -> ShellClient<U, R, SD> {
token: CompositorToken<R>,
) -> ShellClient<R, SD> {
ShellClient {
kind: super::ShellClientKind::Xdg(resource.clone()),
_token: token,
@ -58,13 +57,12 @@ pub(crate) fn make_shell_client<U, R, SD>(
}
}
fn wm_implementation<U, R, SD>(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBase)
fn wm_implementation<R, SD>(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBase)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = shell.as_ref().user_data::<ShellUserData<U, R, SD>>().unwrap();
let data = shell.as_ref().user_data::<ShellUserData<R, SD>>().unwrap();
match request {
xdg_wm_base::Request::Destroy => {
// all is handled by destructor
@ -92,8 +90,8 @@ where
return;
}
id.implement_closure(
xdg_surface_implementation::<U, R, SD>,
Some(destroy_surface::<U, R, SD>),
xdg_surface_implementation::<R, SD>,
Some(destroy_surface::<R, SD>),
XdgSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: surface,
@ -188,22 +186,18 @@ fn implement_positioner(
* xdg_surface
*/
struct XdgSurfaceUserData<U, R, SD> {
shell_data: ShellData<U, R, SD>,
struct XdgSurfaceUserData<R, SD> {
shell_data: ShellData<R, SD>,
wl_surface: wl_surface::WlSurface,
wm_base: xdg_wm_base::XdgWmBase,
}
fn destroy_surface<U, R, SD>(surface: xdg_surface::XdgSurface)
fn destroy_surface<R, SD>(surface: xdg_surface::XdgSurface)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = surface
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.unwrap();
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a
@ -225,15 +219,14 @@ where
.expect("xdg_surface exists but surface has not shell_surface role?!");
}
fn xdg_surface_implementation<U, R, SD>(request: xdg_surface::Request, xdg_surface: xdg_surface::XdgSurface)
fn xdg_surface_implementation<R, SD>(request: xdg_surface::Request, xdg_surface: xdg_surface::XdgSurface)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = xdg_surface
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.user_data::<XdgSurfaceUserData<R, SD>>()
.unwrap();
match request {
xdg_surface::Request::Destroy => {
@ -253,8 +246,8 @@ where
})
.expect("xdg_surface exists but surface has not shell_surface role?!");
let toplevel = id.implement_closure(
toplevel_implementation::<U, R, SD>,
Some(destroy_toplevel::<U, R, SD>),
toplevel_implementation::<R, SD>,
Some(destroy_toplevel::<R, SD>),
ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
@ -285,10 +278,7 @@ where
.unwrap();
let parent_surface = parent.map(|parent| {
let parent_data = parent
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.unwrap();
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
parent_data.wl_surface.clone()
});
data.shell_data
@ -301,8 +291,8 @@ where
})
.expect("xdg_surface exists but surface has not shell_surface role?!");
let popup = id.implement_closure(
xg_popup_implementation::<U, R, SD>,
Some(destroy_popup::<U, R, SD>),
xg_popup_implementation::<R, SD>,
Some(destroy_popup::<R, SD>),
ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
@ -360,27 +350,26 @@ where
* xdg_toplevel
*/
pub(crate) struct ShellSurfaceUserData<U, R, SD> {
pub(crate) shell_data: ShellData<U, R, SD>,
pub(crate) struct ShellSurfaceUserData<R, SD> {
pub(crate) shell_data: ShellData<R, SD>,
pub(crate) wl_surface: wl_surface::WlSurface,
pub(crate) wm_base: xdg_wm_base::XdgWmBase,
pub(crate) xdg_surface: xdg_surface::XdgSurface,
}
// Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_data<U, R, SD, F>(
shell_data: &ShellData<U, R, SD>,
fn with_surface_toplevel_data<R, SD, F>(
shell_data: &ShellData<R, SD>,
toplevel: &xdg_toplevel::XdgToplevel,
f: F,
) where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
F: FnOnce(&mut ToplevelState),
{
let toplevel_data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
shell_data
.compositor_token
@ -391,15 +380,14 @@ fn with_surface_toplevel_data<U, R, SD, F>(
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
pub fn send_toplevel_configure<U, R, SD>(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure)
pub fn send_toplevel_configure<R, SD>(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let (width, height) = configure.size.unwrap_or((0, 0));
// convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
@ -421,12 +409,12 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>(
fn make_toplevel_handle<R: 'static, SD: 'static>(
resource: &xdg_toplevel::XdgToplevel,
) -> super::ToplevelSurface<U, R, SD> {
) -> super::ToplevelSurface<R, SD> {
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
super::ToplevelSurface {
wl_surface: data.wl_surface.clone(),
@ -436,15 +424,14 @@ fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>(
}
}
fn toplevel_implementation<U, R, SD>(request: xdg_toplevel::Request, toplevel: xdg_toplevel::XdgToplevel)
fn toplevel_implementation<R, SD>(request: xdg_toplevel::Request, toplevel: xdg_toplevel::XdgToplevel)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
match request {
xdg_toplevel::Request::Destroy => {
@ -455,7 +442,7 @@ where
toplevel_data.parent = parent.map(|toplevel_surface_parent| {
toplevel_surface_parent
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap()
.wl_surface
.clone()
@ -544,15 +531,14 @@ where
}
}
fn destroy_toplevel<U, R, SD>(toplevel: xdg_toplevel::XdgToplevel)
fn destroy_toplevel<R, SD>(toplevel: xdg_toplevel::XdgToplevel)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
@ -580,15 +566,14 @@ where
* xdg_popup
*/
pub(crate) fn send_popup_configure<U, R, SD>(resource: &xdg_popup::XdgPopup, configure: PopupConfigure)
pub(crate) fn send_popup_configure<R, SD>(resource: &xdg_popup::XdgPopup, configure: PopupConfigure)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let (x, y) = configure.position;
let (width, height) = configure.size;
@ -602,12 +587,10 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_popup_handle<U: 'static, R: 'static, SD: 'static>(
resource: &xdg_popup::XdgPopup,
) -> super::PopupSurface<U, R, SD> {
fn make_popup_handle<R: 'static, SD: 'static>(resource: &xdg_popup::XdgPopup) -> super::PopupSurface<R, SD> {
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
super::PopupSurface {
wl_surface: data.wl_surface.clone(),
@ -617,16 +600,12 @@ fn make_popup_handle<U: 'static, R: 'static, SD: 'static>(
}
}
fn xg_popup_implementation<U, R, SD>(request: xdg_popup::Request, popup: xdg_popup::XdgPopup)
fn xg_popup_implementation<R, SD>(request: xdg_popup::Request, popup: xdg_popup::XdgPopup)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = popup
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.unwrap();
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
match request {
xdg_popup::Request::Destroy => {
// all is handled by our destructor
@ -644,16 +623,12 @@ where
}
}
fn destroy_popup<U, R, SD>(popup: xdg_popup::XdgPopup)
fn destroy_popup<R, SD>(popup: xdg_popup::XdgPopup)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = popup
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.unwrap();
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a

View File

@ -17,17 +17,16 @@ use super::{
XdgSurfacePendingState, XdgSurfaceRole,
};
pub(crate) fn implement_shell<U, R, SD>(
pub(crate) fn implement_shell<R, SD>(
shell: NewResource<zxdg_shell_v6::ZxdgShellV6>,
shell_data: &ShellData<U, R, SD>,
shell_data: &ShellData<R, SD>,
) -> zxdg_shell_v6::ZxdgShellV6
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: Default + 'static,
{
let shell = shell.implement_closure(
shell_implementation::<U, R, SD>,
shell_implementation::<R, SD>,
None::<fn(_)>,
ShellUserData {
shell_data: shell_data.clone(),
@ -45,15 +44,15 @@ where
* xdg_shell
*/
pub(crate) struct ShellUserData<U, R, SD> {
shell_data: ShellData<U, R, SD>,
pub(crate) struct ShellUserData<R, SD> {
shell_data: ShellData<R, SD>,
pub(crate) client_data: Mutex<ShellClientData<SD>>,
}
pub(crate) fn make_shell_client<U, R, SD>(
pub(crate) fn make_shell_client<R, SD>(
resource: &zxdg_shell_v6::ZxdgShellV6,
token: CompositorToken<U, R>,
) -> ShellClient<U, R, SD> {
token: CompositorToken<R>,
) -> ShellClient<R, SD> {
ShellClient {
kind: super::ShellClientKind::ZxdgV6(resource.clone()),
_token: token,
@ -61,13 +60,12 @@ pub(crate) fn make_shell_client<U, R, SD>(
}
}
fn shell_implementation<U, R, SD>(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::ZxdgShellV6)
fn shell_implementation<R, SD>(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::ZxdgShellV6)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = shell.as_ref().user_data::<ShellUserData<U, R, SD>>().unwrap();
let data = shell.as_ref().user_data::<ShellUserData<R, SD>>().unwrap();
match request {
zxdg_shell_v6::Request::Destroy => {
// all is handled by destructor
@ -95,8 +93,8 @@ where
return;
}
id.implement_closure(
xdg_surface_implementation::<U, R, SD>,
Some(destroy_surface::<U, R, SD>),
xdg_surface_implementation::<R, SD>,
Some(destroy_surface::<R, SD>),
XdgSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: surface.clone(),
@ -205,22 +203,18 @@ fn implement_positioner(
* xdg_surface
*/
struct XdgSurfaceUserData<U, R, SD> {
shell_data: ShellData<U, R, SD>,
struct XdgSurfaceUserData<R, SD> {
shell_data: ShellData<R, SD>,
wl_surface: wl_surface::WlSurface,
shell: zxdg_shell_v6::ZxdgShellV6,
}
fn destroy_surface<U, R, SD>(surface: zxdg_surface_v6::ZxdgSurfaceV6)
fn destroy_surface<R, SD>(surface: zxdg_surface_v6::ZxdgSurfaceV6)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = surface
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.unwrap();
let data = surface.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a
@ -242,17 +236,16 @@ where
.expect("xdg_surface exists but surface has not shell_surface role?!");
}
fn xdg_surface_implementation<U, R, SD>(
fn xdg_surface_implementation<R, SD>(
request: zxdg_surface_v6::Request,
xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
) where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = xdg_surface
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.user_data::<XdgSurfaceUserData<R, SD>>()
.unwrap();
match request {
zxdg_surface_v6::Request::Destroy => {
@ -272,8 +265,8 @@ fn xdg_surface_implementation<U, R, SD>(
})
.expect("xdg_surface exists but surface has not shell_surface role?!");
let toplevel = id.implement_closure(
toplevel_implementation::<U, R, SD>,
Some(destroy_toplevel::<U, R, SD>),
toplevel_implementation::<R, SD>,
Some(destroy_toplevel::<R, SD>),
ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
@ -303,10 +296,7 @@ fn xdg_surface_implementation<U, R, SD>(
.user_data::<RefCell<PositionerState>>()
.unwrap();
let parent_data = parent
.as_ref()
.user_data::<XdgSurfaceUserData<U, R, SD>>()
.unwrap();
let parent_data = parent.as_ref().user_data::<XdgSurfaceUserData<R, SD>>().unwrap();
data.shell_data
.compositor_token
.with_role_data::<XdgSurfaceRole, _, _>(&data.wl_surface, |data| {
@ -317,8 +307,8 @@ fn xdg_surface_implementation<U, R, SD>(
})
.expect("xdg_surface exists but surface has not shell_surface role?!");
let popup = id.implement_closure(
popup_implementation::<U, R, SD>,
Some(destroy_popup::<U, R, SD>),
popup_implementation::<R, SD>,
Some(destroy_popup::<R, SD>),
ShellSurfaceUserData {
shell_data: data.shell_data.clone(),
wl_surface: data.wl_surface.clone(),
@ -376,24 +366,23 @@ fn xdg_surface_implementation<U, R, SD>(
* xdg_toplevel
*/
pub struct ShellSurfaceUserData<U, R, SD> {
pub(crate) shell_data: ShellData<U, R, SD>,
pub struct ShellSurfaceUserData<R, SD> {
pub(crate) shell_data: ShellData<R, SD>,
pub(crate) wl_surface: wl_surface::WlSurface,
pub(crate) shell: zxdg_shell_v6::ZxdgShellV6,
pub(crate) xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6,
}
// Utility functions allowing to factor out a lot of the upcoming logic
fn with_surface_toplevel_data<U, R, SD, F>(toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F)
fn with_surface_toplevel_data<R, SD, F>(toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
F: FnOnce(&mut ToplevelState),
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
data.shell_data
.compositor_token
@ -404,17 +393,16 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
pub fn send_toplevel_configure<U, R, SD>(
pub fn send_toplevel_configure<R, SD>(
resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
configure: ToplevelConfigure,
) where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let (width, height) = configure.size.unwrap_or((0, 0));
// convert the Vec<State> (which is really a Vec<u32>) into Vec<u8>
@ -436,12 +424,12 @@ pub fn send_toplevel_configure<U, R, SD>(
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>(
fn make_toplevel_handle<R: 'static, SD: 'static>(
resource: &zxdg_toplevel_v6::ZxdgToplevelV6,
) -> super::ToplevelSurface<U, R, SD> {
) -> super::ToplevelSurface<R, SD> {
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
super::ToplevelSurface {
wl_surface: data.wl_surface.clone(),
@ -451,40 +439,39 @@ fn make_toplevel_handle<U: 'static, R: 'static, SD: 'static>(
}
}
fn toplevel_implementation<U, R, SD>(
fn toplevel_implementation<R, SD>(
request: zxdg_toplevel_v6::Request,
toplevel: zxdg_toplevel_v6::ZxdgToplevelV6,
) where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
match request {
zxdg_toplevel_v6::Request::Destroy => {
// all it done by the destructor
}
zxdg_toplevel_v6::Request::SetParent { parent } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.parent = parent.map(|toplevel_surface_parent| {
let parent_data = toplevel_surface_parent
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
parent_data.wl_surface.clone()
})
});
}
zxdg_toplevel_v6::Request::SetTitle { title } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.title = title;
});
}
zxdg_toplevel_v6::Request::SetAppId { app_id } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.app_id = app_id;
});
}
@ -520,12 +507,12 @@ fn toplevel_implementation<U, R, SD>(
});
}
zxdg_toplevel_v6::Request::SetMaxSize { width, height } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.max_size = (width, height);
});
}
zxdg_toplevel_v6::Request::SetMinSize { width, height } => {
with_surface_toplevel_data::<U, R, SD, _>(&toplevel, |toplevel_data| {
with_surface_toplevel_data::<R, SD, _>(&toplevel, |toplevel_data| {
toplevel_data.max_size = (width, height);
});
}
@ -561,15 +548,14 @@ fn toplevel_implementation<U, R, SD>(
}
}
fn destroy_toplevel<U, R, SD>(toplevel: zxdg_toplevel_v6::ZxdgToplevelV6)
fn destroy_toplevel<R, SD>(toplevel: zxdg_toplevel_v6::ZxdgToplevelV6)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = toplevel
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
@ -597,15 +583,14 @@ where
* xdg_popup
*/
pub(crate) fn send_popup_configure<U, R, SD>(resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure)
pub(crate) fn send_popup_configure<R, SD>(resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
let (x, y) = configure.position;
let (width, height) = configure.size;
@ -619,12 +604,12 @@ where
.expect("xdg_toplevel exists but surface has not shell_surface role?!");
}
fn make_popup_handle<U: 'static, R: 'static, SD: 'static>(
fn make_popup_handle<R: 'static, SD: 'static>(
resource: &zxdg_popup_v6::ZxdgPopupV6,
) -> super::PopupSurface<U, R, SD> {
) -> super::PopupSurface<R, SD> {
let data = resource
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.user_data::<ShellSurfaceUserData<R, SD>>()
.unwrap();
super::PopupSurface {
wl_surface: data.wl_surface.clone(),
@ -634,16 +619,12 @@ fn make_popup_handle<U: 'static, R: 'static, SD: 'static>(
}
}
fn popup_implementation<U, R, SD>(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::ZxdgPopupV6)
fn popup_implementation<R, SD>(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::ZxdgPopupV6)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = popup
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.unwrap();
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
match request {
zxdg_popup_v6::Request::Destroy => {
// all is handled by our destructor
@ -661,16 +642,12 @@ where
}
}
fn destroy_popup<U, R, SD>(popup: zxdg_popup_v6::ZxdgPopupV6)
fn destroy_popup<R, SD>(popup: zxdg_popup_v6::ZxdgPopupV6)
where
U: 'static,
R: Role<XdgSurfaceRole> + 'static,
SD: 'static,
{
let data = popup
.as_ref()
.user_data::<ShellSurfaceUserData<U, R, SD>>()
.unwrap();
let data = popup.as_ref().user_data::<ShellSurfaceUserData<R, SD>>().unwrap();
if !data.wl_surface.as_ref().is_alive() {
// the wl_surface is destroyed, this means the client is not
// trying to change the role but it's a cleanup (possibly a