diff --git a/Cargo.toml b/Cargo.toml index 615d5b1..ef2e3d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,9 +11,9 @@ edition = "2018" members = [ "anvil" ] [dependencies] -wayland-server = { version = "0.21.6", optional = true } -wayland-commons = { version = "0.21.1", optional = true } -wayland-sys = { version = "0.21.6", optional = true } +wayland-server = { version = "0.23", optional = true } +wayland-commons = { version = "0.23", optional = true } +wayland-sys = { version = "0.23", optional = true } calloop = "0.4.2" nix = "0.11" xkbcommon = "0.2.1" @@ -21,7 +21,7 @@ tempfile = "2.1.5" slog = "2.1.1" slog-stdlog = "3.0.2" libloading = "0.4.0" -wayland-client = { version = "0.21.1", features = ["egl"], optional = true } +wayland-client = { version = "0.23", features = ["egl"], optional = true } winit = { version = "0.18.0", optional = true } drm = { version = "^0.3.4", optional = true } gbm = { version = "^0.5.0", optional = true, default-features = false, features = ["drm-support"] } @@ -30,7 +30,7 @@ input = { version = "0.4.1", optional = true } udev = { version = "0.2.0", optional = true } dbus = { version = "0.6.1", optional = true } systemd = { version = "^0.2.0", optional = true } -wayland-protocols = { version = "0.21.3", features = ["unstable_protocols", "server"], optional = true } +wayland-protocols = { version = "0.23", features = ["unstable_protocols", "server"], optional = true } image = { version = "0.17.0", optional = true } error-chain = "0.11.0" lazy_static = "1.0.0" @@ -55,7 +55,7 @@ backend_udev = ["udev"] backend_session_logind = ["dbus", "systemd", "backend_session"] renderer_gl = ["gl_generator"] renderer_glium = ["renderer_gl", "glium"] -native_lib = ["wayland_frontend", "wayland-sys", "wayland-server/native_lib", "wayland-protocols/native_server"] +native_lib = ["wayland_frontend", "wayland-sys", "wayland-server/native_lib"] wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols"] xwayland = ["wayland_frontend"] diff --git a/anvil/Cargo.toml b/anvil/Cargo.toml index dfa9de7..e666cfd 100644 --- a/anvil/Cargo.toml +++ b/anvil/Cargo.toml @@ -12,7 +12,7 @@ slog-term = "2.3" slog-async = "2.2" rand = "0.3" glium = { version = "0.19.0", default-features = false } -wayland-server = "0.21" +wayland-server = "0.23" xkbcommon = "0.2.1" [dependencies.smithay] diff --git a/src/backend/session/direct.rs b/src/backend/session/direct.rs index 8fe6364..2e75998 100644 --- a/src/backend/session/direct.rs +++ b/src/backend/session/direct.rs @@ -45,14 +45,14 @@ //! for notifications are the [`Libinput`](input::Libinput) context or the [`Device`](::backend::drm::Device). use super::{AsErrno, Session, SessionNotifier, SessionObserver}; -use calloop::{signals::Signals, LoopHandle, Source}; +use calloop::{ + signals::{Signal, Signals}, + LoopHandle, Source, +}; use nix::{ fcntl::{self, open, OFlag}, libc::c_int, - sys::{ - signal::{self, Signal}, - stat::{dev_t, fstat, major, minor, Mode}, - }, + sys::stat::{dev_t, fstat, major, minor, Mode}, unistd::{close, dup}, Error as NixError, Result as NixResult, }; @@ -257,7 +257,7 @@ impl DirectSession { } else { tty::__libc_current_sigrtmin() };*/ - let signal = signal::SIGUSR2; + let signal = ::nix::sys::signal::SIGUSR2; let mode = tty::VtMode { mode: tty::VT_PROCESS, @@ -270,7 +270,7 @@ impl DirectSession { tty::vt_set_mode(tty, &mode).chain_err(|| ErrorKind::FailedToTakeControlOfTTY(vt_num))?; } - Ok((vt_num, old_keyboard_mode, signal)) + Ok((vt_num, old_keyboard_mode, Signal::SIGUSR2)) } /// Get the number of the virtual terminal used by this session diff --git a/src/wayland/compositor/handlers.rs b/src/wayland/compositor/handlers.rs index 62def3a..b4ca2aa 100644 --- a/src/wayland/compositor/handlers.rs +++ b/src/wayland/compositor/handlers.rs @@ -2,7 +2,7 @@ use std::{cell::RefCell, rc::Rc, sync::Mutex}; use wayland_server::{ protocol::{wl_compositor, wl_region, wl_subcompositor, wl_subsurface, wl_surface}, - DisplayToken, NewResource, Resource, + NewResource, Resource, }; use super::{ @@ -17,30 +17,28 @@ use super::{ pub(crate) fn implement_compositor( compositor: NewResource, - token: DisplayToken, log: ::slog::Logger, implem: Rc>, -) -> Resource +) -> wl_compositor::WlCompositor where U: Default + 'static, R: Default + 'static, - Impl: FnMut(SurfaceEvent, Resource, CompositorToken) + 'static, + Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken) + 'static, { - let my_token = token.clone(); - compositor.implement_nonsend( + compositor.implement_closure( move |request, _compositor| match request { wl_compositor::Request::CreateSurface { id } => { trace!(log, "Creating a new wl_surface."); - implement_surface(id, &token, log.clone(), implem.clone()); + implement_surface(id, log.clone(), implem.clone()); } wl_compositor::Request::CreateRegion { id } => { trace!(log, "Creating a new wl_region."); - implement_region(id, &token); + implement_region(id); } + _ => unreachable!(), }, None::, (), - &my_token, ) } @@ -51,13 +49,13 @@ where // Internal implementation data of surfaces pub(crate) struct SurfaceImplem { log: ::slog::Logger, - implem: Rc, CompositorToken)>>, + implem: Rc)>>, } impl SurfaceImplem { fn make(log: ::slog::Logger, implem: Rc>) -> SurfaceImplem where - Impl: FnMut(SurfaceEvent, Resource, CompositorToken) + 'static, + Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken) + 'static, { SurfaceImplem { log, implem } } @@ -68,11 +66,7 @@ where U: 'static, R: 'static, { - fn receive_surface_request( - &mut self, - req: wl_surface::Request, - surface: Resource, - ) { + fn receive_surface_request(&mut self, req: wl_surface::Request, surface: wl_surface::WlSurface) { match req { wl_surface::Request::Attach { buffer, x, y } => { SurfaceData::::with_data(&surface, |d| { @@ -91,14 +85,14 @@ where } wl_surface::Request::SetOpaqueRegion { region } => { let attributes = region.map(|r| { - let attributes_mutex = r.user_data::>().unwrap(); + let attributes_mutex = r.as_ref().user_data::>().unwrap(); attributes_mutex.lock().unwrap().clone() }); SurfaceData::::with_data(&surface, |d| d.opaque_region = attributes); } wl_surface::Request::SetInputRegion { region } => { let attributes = region.map(|r| { - let attributes_mutex = r.user_data::>().unwrap(); + let attributes_mutex = r.as_ref().user_data::>().unwrap(); attributes_mutex.lock().unwrap().clone() }); SurfaceData::::with_data(&surface, |d| d.input_region = attributes); @@ -122,29 +116,28 @@ where wl_surface::Request::Destroy => { // All is already handled by our destructor } + _ => unreachable!(), } } } fn implement_surface( surface: NewResource, - token: &DisplayToken, log: ::slog::Logger, implem: Rc>, -) -> Resource +) -> wl_surface::WlSurface where U: Default + 'static, R: Default + 'static, - Impl: FnMut(SurfaceEvent, Resource, CompositorToken) + 'static, + Impl: FnMut(SurfaceEvent, wl_surface::WlSurface, CompositorToken) + 'static, { - let surface = surface.implement_nonsend( + let surface = surface.implement_closure( { let mut implem = SurfaceImplem::make(log, implem); move |req, surface| implem.receive_surface_request(req, surface) }, Some(|surface| SurfaceData::::cleanup(&surface)), SurfaceData::::new(), - token, ); surface } @@ -153,8 +146,8 @@ where * wl_region */ -fn region_implem(request: wl_region::Request, region: Resource) { - let attributes_mutex = region.user_data::>().unwrap(); +fn region_implem(request: wl_region::Request, region: wl_region::WlRegion) { + let attributes_mutex = region.as_ref().user_data::>().unwrap(); let mut guard = attributes_mutex.lock().unwrap(); match request { wl_region::Request::Add { x, y, width, height } => guard @@ -166,18 +159,15 @@ fn region_implem(request: wl_region::Request, region: Resource { // all is handled by our destructor } + _ => unreachable!(), } } -fn implement_region( - region: NewResource, - token: &DisplayToken, -) -> Resource { - region.implement_nonsend( +fn implement_region(region: NewResource) -> wl_region::WlRegion { + region.implement_closure( region_implem, None::, Mutex::new(RegionAttributes::default()), - token, ) } @@ -187,30 +177,28 @@ fn implement_region( pub(crate) fn implement_subcompositor( subcompositor: NewResource, - token: DisplayToken, -) -> Resource +) -> wl_subcompositor::WlSubcompositor where R: RoleType + Role + 'static, U: 'static, { - let my_token = token.clone(); - subcompositor.implement_nonsend( - move |request, subcompositor: Resource<_>| match request { + subcompositor.implement_closure( + move |request, subcompositor| match request { wl_subcompositor::Request::GetSubsurface { id, surface, parent } => { if let Err(()) = SurfaceData::::set_parent(&surface, &parent) { - subcompositor.post_error( + subcompositor.as_ref().post_error( wl_subcompositor::Error::BadSurface as u32, "Surface already has a role.".into(), ); return; } - implement_subsurface::(id, surface.clone(), &token); + implement_subsurface::(id, surface.clone()); } wl_subcompositor::Request::Destroy => {} + _ => unreachable!(), }, None::, (), - &my_token, ) } @@ -218,27 +206,26 @@ where * wl_subsurface */ -fn with_subsurface_attributes(subsurface: &Resource, f: F) +fn with_subsurface_attributes(subsurface: &wl_subsurface::WlSubsurface, f: F) where F: FnOnce(&mut SubsurfaceRole), U: 'static, R: RoleType + Role + 'static, { - let surface = subsurface.user_data::>().unwrap(); + let surface = subsurface.as_ref().user_data::().unwrap(); SurfaceData::::with_role_data::(surface, |d| f(d)) .expect("The surface does not have a subsurface role while it has a wl_subsurface?!"); } fn implement_subsurface( subsurface: NewResource, - surface: Resource, - token: &DisplayToken, -) -> Resource + surface: wl_surface::WlSurface, +) -> wl_subsurface::WlSubsurface where U: 'static, R: RoleType + Role + 'static, { - subsurface.implement_nonsend( + subsurface.implement_closure( |request, subsurface| { match request { wl_subsurface::Request::SetPosition { x, y } => { @@ -247,18 +234,18 @@ where }) } wl_subsurface::Request::PlaceAbove { sibling } => { - let surface = subsurface.user_data::>().unwrap(); + let surface = subsurface.as_ref().user_data::().unwrap(); if let Err(()) = SurfaceData::::reorder(surface, Location::After, &sibling) { - subsurface.post_error( + subsurface.as_ref().post_error( wl_subsurface::Error::BadSurface as u32, "Provided surface is not a sibling or parent.".into(), ) } } wl_subsurface::Request::PlaceBelow { sibling } => { - let surface = subsurface.user_data::>().unwrap(); + let surface = subsurface.as_ref().user_data::().unwrap(); if let Err(()) = SurfaceData::::reorder(surface, Location::Before, &sibling) { - subsurface.post_error( + subsurface.as_ref().post_error( wl_subsurface::Error::BadSurface as u32, "Provided surface is not a sibling or parent.".into(), ) @@ -277,21 +264,21 @@ where wl_subsurface::Request::Destroy => { // Our destructor already handles it } + _ => unreachable!(), } }, Some(|subsurface| destroy_subsurface::(&subsurface)), surface, - token, ) } -fn destroy_subsurface(subsurface: &Resource) +fn destroy_subsurface(subsurface: &wl_subsurface::WlSubsurface) where U: 'static, R: RoleType + Role + 'static, { - let surface = subsurface.user_data::>().unwrap(); - if surface.is_alive() { + let surface = subsurface.as_ref().user_data::().unwrap(); + if surface.as_ref().is_alive() { SurfaceData::::unset_parent(&surface); } } diff --git a/src/wayland/compositor/mod.rs b/src/wayland/compositor/mod.rs index 84b3718..92850d8 100644 --- a/src/wayland/compositor/mod.rs +++ b/src/wayland/compositor/mod.rs @@ -137,7 +137,7 @@ pub struct SurfaceAttributes { /// You are free to set this field to `None` to avoid processing it several /// times. It'll be set to `Some(...)` if the user attaches a buffer (or `NULL`) to /// the surface. - pub buffer: Option, (i32, i32))>>, + pub buffer: Option>, /// Scale of the contents of the buffer, for higher-resolution contents. /// /// If it matches the one of the output displaying this surface, no change @@ -272,7 +272,7 @@ impl CompositorToken { /// /// 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 with_surface_data(&self, surface: &Resource, f: F) -> T + pub fn with_surface_data(&self, surface: &WlSurface, f: F) -> T where F: FnOnce(&mut SurfaceAttributes) -> T, { @@ -301,14 +301,9 @@ where /// /// If the surface not managed by the `CompositorGlobal` that provided this token, this /// will panic (having more than one compositor is not supported). - pub fn with_surface_tree_upward( - &self, - surface: &Resource, - initial: T, - f: F, - ) -> Result<(), ()> + pub fn with_surface_tree_upward(&self, surface: &WlSurface, initial: T, f: F) -> Result<(), ()> where - F: FnMut(&Resource, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction, + F: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction, { SurfaceData::::map_tree(surface, initial, f, false); Ok(()) @@ -321,14 +316,9 @@ where /// supposed to be drawn: top-most first. /// /// Behavior is the same as [`with_surface_tree_upward`](CompositorToken::with_surface_tree_upward). - pub fn with_surface_tree_downward( - &self, - surface: &Resource, - initial: T, - f: F, - ) -> Result<(), ()> + pub fn with_surface_tree_downward(&self, surface: &WlSurface, initial: T, f: F) -> Result<(), ()> where - F: FnMut(&Resource, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction, + F: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction, { SurfaceData::::map_tree(surface, initial, f, true); Ok(()) @@ -340,7 +330,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: &Resource) -> Option> { + pub fn get_parent(&self, surface: &WlSurface) -> Option { SurfaceData::::get_parent(surface) } @@ -348,7 +338,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_children(&self, surface: &Resource) -> Vec> { + pub fn get_children(&self, surface: &WlSurface) -> Vec { SurfaceData::::get_children(surface) } } @@ -358,7 +348,7 @@ impl CompositorToken { /// /// 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: &Resource) -> bool { + pub fn has_a_role(&self, surface: &WlSurface) -> bool { SurfaceData::::has_a_role(surface) } @@ -366,7 +356,7 @@ impl CompositorToken { /// /// 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_role(&self, surface: &Resource) -> bool + pub fn has_role(&self, surface: &WlSurface) -> bool where R: Role, { @@ -379,7 +369,7 @@ impl CompositorToken { /// /// 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 give_role(&self, surface: &Resource) -> Result<(), ()> + pub fn give_role(&self, surface: &WlSurface) -> Result<(), ()> where R: Role, RoleData: Default, @@ -393,11 +383,7 @@ impl CompositorToken { /// /// 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 give_role_with( - &self, - surface: &Resource, - data: RoleData, - ) -> Result<(), RoleData> + pub fn give_role_with(&self, surface: &WlSurface, data: RoleData) -> Result<(), RoleData> where R: Role, { @@ -410,7 +396,7 @@ impl CompositorToken { /// /// 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 with_role_data(&self, surface: &Resource, f: F) -> Result + pub fn with_role_data(&self, surface: &WlSurface, f: F) -> Result where R: Role, F: FnOnce(&mut RoleData) -> T, @@ -424,7 +410,7 @@ impl CompositorToken { /// /// 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 remove_role(&self, surface: &Resource) -> Result + pub fn remove_role(&self, surface: &WlSurface) -> Result where R: Role, { @@ -435,8 +421,8 @@ impl CompositorToken { /// /// If the region is not managed by the `CompositorGlobal` that provided this token, this /// will panic (having more than one compositor is not supported). - pub fn get_region_attributes(&self, region: &Resource) -> RegionAttributes { - match region.user_data::>() { + pub fn get_region_attributes(&self, region: &wl_region::WlRegion) -> RegionAttributes { + match region.as_ref().user_data::>() { Some(mutex) => mutex.lock().unwrap().clone(), None => panic!("Accessing the data of foreign regions is not supported."), } @@ -465,25 +451,17 @@ where L: Into>, U: Default + 'static, R: Default + RoleType + Role + 'static, - Impl: FnMut(SurfaceEvent, Resource, CompositorToken) + 'static, + Impl: FnMut(SurfaceEvent, WlSurface, CompositorToken) + 'static, { let log = crate::slog_or_stdlog(logger).new(o!("smithay_module" => "compositor_handler")); let implem = Rc::new(RefCell::new(implem)); - let comp_token = display.get_token(); - let sub_token = display.get_token(); - let compositor = display.create_global(4, move |new_compositor, _version| { - self::handlers::implement_compositor::( - new_compositor, - comp_token.clone(), - log.clone(), - implem.clone(), - ); + self::handlers::implement_compositor::(new_compositor, log.clone(), implem.clone()); }); let subcompositor = display.create_global(1, move |new_subcompositor, _version| { - self::handlers::implement_subcompositor::(new_subcompositor, sub_token.clone()); + self::handlers::implement_subcompositor::(new_subcompositor); }); (CompositorToken::make(), compositor, subcompositor) diff --git a/src/wayland/compositor/tree.rs b/src/wayland/compositor/tree.rs index 8c4b50b..f3f99da 100644 --- a/src/wayland/compositor/tree.rs +++ b/src/wayland/compositor/tree.rs @@ -19,8 +19,8 @@ use wayland_server::{protocol::wl_surface::WlSurface, Resource}; /// have a failure case to forbid this. Note that if any node in such a graph does not /// have a parent, then the graph is a tree and this node is its root. pub struct SurfaceData { - parent: Option>, - children: Vec>, + parent: Option, + children: Vec, role: R, attributes: SurfaceAttributes, } @@ -56,25 +56,30 @@ where U: 'static, R: 'static, { - /// Cleans the `user_data` of that surface, must be called when it is destroyed - pub fn cleanup(surface: &Resource) { - let my_data_mutex = surface.user_data::>>().unwrap(); + /// 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::>>().unwrap(); let mut my_data = my_data_mutex.lock().unwrap(); if let Some(old_parent) = my_data.parent.take() { - if !old_parent.equals(surface) { + if !old_parent.as_ref().equals(surface.as_ref()) { // We had a parent that is not ourselves, lets unregister ourselves from it - let old_parent_mutex = old_parent.user_data::>>().unwrap(); + let old_parent_mutex = old_parent + .as_ref() + .user_data::>>() + .unwrap(); let mut old_parent_guard = old_parent_mutex.lock().unwrap(); - old_parent_guard.children.retain(|c| !c.equals(surface)); + old_parent_guard + .children + .retain(|c| !c.as_ref().equals(surface.as_ref())); } } // orphan all our children for child in &my_data.children { // don't do anything if this child is ourselves - if child.equals(surface) { + if child.as_ref().equals(surface.as_ref()) { continue; } - let child_mutex = child.user_data::>>().unwrap(); + let child_mutex = child.as_ref().user_data::>>().unwrap(); let mut child_guard = child_mutex.lock().unwrap(); child_guard.parent = None; } @@ -82,32 +87,32 @@ where } impl SurfaceData { - pub fn has_a_role(surface: &Resource) -> bool { - debug_assert!(surface.is_alive()); - let data_mutex = surface.user_data::>>().unwrap(); + pub fn has_a_role(surface: &WlSurface) -> bool { + debug_assert!(surface.as_ref().is_alive()); + let data_mutex = surface.as_ref().user_data::>>().unwrap(); let data_guard = data_mutex.lock().unwrap(); ::has_role(&data_guard.role) } /// Check whether a surface has a given role - pub fn has_role(surface: &Resource) -> bool + pub fn has_role(surface: &WlSurface) -> bool where R: Role, { - debug_assert!(surface.is_alive()); - let data_mutex = surface.user_data::>>().unwrap(); + debug_assert!(surface.as_ref().is_alive()); + let data_mutex = surface.as_ref().user_data::>>().unwrap(); let data_guard = data_mutex.lock().unwrap(); >::has(&data_guard.role) } /// Register that this surface has a role, fails if it already has one - pub fn give_role(surface: &Resource) -> Result<(), ()> + pub fn give_role(surface: &WlSurface) -> Result<(), ()> where R: Role, RoleData: Default, { - debug_assert!(surface.is_alive()); - let data_mutex = surface.user_data::>>().unwrap(); + debug_assert!(surface.as_ref().is_alive()); + let data_mutex = surface.as_ref().user_data::>>().unwrap(); let mut data_guard = data_mutex.lock().unwrap(); >::set(&mut data_guard.role) } @@ -115,12 +120,12 @@ impl SurfaceData { /// Register that this surface has a role with given data /// /// Fails if it already has one and returns the data - pub fn give_role_with(surface: &Resource, data: RoleData) -> Result<(), RoleData> + pub fn give_role_with(surface: &WlSurface, data: RoleData) -> Result<(), RoleData> where R: Role, { - debug_assert!(surface.is_alive()); - let data_mutex = surface.user_data::>>().unwrap(); + debug_assert!(surface.as_ref().is_alive()); + let data_mutex = surface.as_ref().user_data::>>().unwrap(); let mut data_guard = data_mutex.lock().unwrap(); >::set_with(&mut data_guard.role, data) } @@ -129,24 +134,24 @@ impl SurfaceData { /// /// It is a noop if this surface already didn't have one, but fails if /// the role was "subsurface", it must be removed by the `unset_parent` method. - pub fn remove_role(surface: &Resource) -> Result + pub fn remove_role(surface: &WlSurface) -> Result where R: Role, { - debug_assert!(surface.is_alive()); - let data_mutex = surface.user_data::>>().unwrap(); + debug_assert!(surface.as_ref().is_alive()); + let data_mutex = surface.as_ref().user_data::>>().unwrap(); let mut data_guard = data_mutex.lock().unwrap(); >::unset(&mut data_guard.role) } /// Access to the role data - pub fn with_role_data(surface: &Resource, f: F) -> Result + pub fn with_role_data(surface: &WlSurface, f: F) -> Result where R: Role, F: FnOnce(&mut RoleData) -> T, { - debug_assert!(surface.is_alive()); - let data_mutex = surface.user_data::>>().unwrap(); + debug_assert!(surface.as_ref().is_alive()); + let data_mutex = surface.as_ref().user_data::>>().unwrap(); let mut data_guard = data_mutex.lock().unwrap(); let data = >::data_mut(&mut data_guard.role)?; Ok(f(data)) @@ -158,13 +163,13 @@ impl + 'static> SurfaceData /// /// if this surface already has a role, does nothing and fails, otherwise /// its role is now to be a subsurface - pub fn set_parent(child: &Resource, parent: &Resource) -> Result<(), ()> { - debug_assert!(child.is_alive()); - debug_assert!(parent.is_alive()); + pub fn set_parent(child: &WlSurface, parent: &WlSurface) -> Result<(), ()> { + debug_assert!(child.as_ref().is_alive()); + debug_assert!(parent.as_ref().is_alive()); // change child's parent { - let child_mutex = child.user_data::>>().unwrap(); + let child_mutex = child.as_ref().user_data::>>().unwrap(); let mut child_guard = child_mutex.lock().unwrap(); // if surface already has a role, it cannot become a subsurface >::set(&mut child_guard.role)?; @@ -174,7 +179,7 @@ impl + 'static> SurfaceData // register child to new parent // double scoping is to be robust to have a child be its own parent { - let parent_mutex = parent.user_data::>>().unwrap(); + let parent_mutex = parent.as_ref().user_data::>>().unwrap(); let mut parent_guard = parent_mutex.lock().unwrap(); parent_guard.children.push(child.clone()) } @@ -184,10 +189,10 @@ impl + 'static> SurfaceData /// Remove a pre-existing parent of this child /// /// Does nothing if it has no parent - pub fn unset_parent(child: &Resource) { - debug_assert!(child.is_alive()); + pub fn unset_parent(child: &WlSurface) { + debug_assert!(child.as_ref().is_alive()); let old_parent = { - let child_mutex = child.user_data::>>().unwrap(); + let child_mutex = child.as_ref().user_data::>>().unwrap(); let mut child_guard = child_mutex.lock().unwrap(); let old_parent = child_guard.parent.take(); if old_parent.is_some() { @@ -199,22 +204,27 @@ impl + 'static> SurfaceData }; // unregister from our parent if let Some(old_parent) = old_parent { - let parent_mutex = old_parent.user_data::>>().unwrap(); + let parent_mutex = old_parent + .as_ref() + .user_data::>>() + .unwrap(); let mut parent_guard = parent_mutex.lock().unwrap(); - parent_guard.children.retain(|c| !c.equals(child)); + parent_guard + .children + .retain(|c| !c.as_ref().equals(child.as_ref())); } } /// Retrieve the parent surface (if any) of this surface - pub fn get_parent(child: &Resource) -> Option> { - let child_mutex = child.user_data::>>().unwrap(); + pub fn get_parent(child: &WlSurface) -> Option { + let child_mutex = child.as_ref().user_data::>>().unwrap(); let child_guard = child_mutex.lock().unwrap(); child_guard.parent.as_ref().cloned() } /// Retrieve the parent surface (if any) of this surface - pub fn get_children(child: &Resource) -> Vec> { - let child_mutex = child.user_data::>>().unwrap(); + pub fn get_children(child: &WlSurface) -> Vec { + let child_mutex = child.as_ref().user_data::>>().unwrap(); let child_guard = child_mutex.lock().unwrap(); child_guard.children.to_vec() } @@ -222,31 +232,27 @@ impl + 'static> SurfaceData /// Reorders a surface relative to one of its sibling /// /// Fails if `relative_to` is not a sibling or parent of `surface`. - pub fn reorder( - surface: &Resource, - to: Location, - relative_to: &Resource, - ) -> Result<(), ()> { + pub fn reorder(surface: &WlSurface, to: Location, relative_to: &WlSurface) -> Result<(), ()> { let parent = { - let data_mutex = surface.user_data::>>().unwrap(); + let data_mutex = surface.as_ref().user_data::>>().unwrap(); let data_guard = data_mutex.lock().unwrap(); data_guard.parent.as_ref().cloned().unwrap() }; - if parent.equals(relative_to) { + if parent.as_ref().equals(relative_to.as_ref()) { // TODO: handle positioning relative to parent return Ok(()); } - fn index_of(surface: &Resource, slice: &[Resource]) -> Option { + fn index_of(surface: &WlSurface, slice: &[WlSurface]) -> Option { for (i, s) in slice.iter().enumerate() { - if s.equals(surface) { + if s.as_ref().equals(surface.as_ref()) { return Some(i); } } None } - let parent_mutex = parent.user_data::>>().unwrap(); + let parent_mutex = parent.as_ref().user_data::>>().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(surface, &parent_guard.children) { @@ -271,11 +277,12 @@ impl SurfaceData { /// /// 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(surface: &Resource, f: F) -> T + pub fn with_data(surface: &WlSurface, f: F) -> T where F: FnOnce(&mut SurfaceAttributes) -> T, { let data_mutex = surface + .as_ref() .user_data::>>() .expect("Accessing the data of foreign surfaces is not supported."); let mut data_guard = data_mutex.lock().unwrap(); @@ -290,27 +297,27 @@ impl SurfaceData { /// /// The callback returns whether the traversal should continue or not. Returning /// false will cause an early-stopping. - pub fn map_tree(root: &Resource, initial: T, mut f: F, reverse: bool) + pub fn map_tree(root: &WlSurface, initial: T, mut f: F, reverse: bool) where - F: FnMut(&Resource, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction, + F: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction, { // helper function for recursion fn map( - surface: &Resource, - root: &Resource, + surface: &WlSurface, + root: &WlSurface, initial: &T, f: &mut F, reverse: bool, ) -> bool where - F: FnMut(&Resource, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction, + F: FnMut(&WlSurface, &mut SurfaceAttributes, &mut R, &T) -> TraversalAction, { // stop if we met the root, so to not deadlock/inifinte loop - if surface.equals(root) { + if surface.as_ref().equals(root.as_ref()) { return true; } - let data_mutex = surface.user_data::>>().unwrap(); + let data_mutex = surface.as_ref().user_data::>>().unwrap(); let mut data_guard = data_mutex.lock().unwrap(); let data_guard = &mut *data_guard; // call the callback on ourselves @@ -337,7 +344,7 @@ impl SurfaceData { } } - let data_mutex = root.user_data::>>().unwrap(); + let data_mutex = root.as_ref().user_data::>>().unwrap(); let mut data_guard = data_mutex.lock().unwrap(); let data_guard = &mut *data_guard; // call the callback on ourselves diff --git a/src/wayland/data_device/data_source.rs b/src/wayland/data_device/data_source.rs index b1d4522..cee8b4a 100644 --- a/src/wayland/data_device/data_source.rs +++ b/src/wayland/data_device/data_source.rs @@ -17,10 +17,10 @@ pub struct SourceMetadata { pub dnd_action: DndAction, } -pub(crate) fn implement_data_source(src: NewResource) -> Resource { - src.implement( +pub(crate) fn implement_data_source(src: NewResource) -> WlDataSource { + src.implement_closure( |req, me| { - let data: &Mutex = me.user_data().unwrap(); + let data: &Mutex = me.as_ref().user_data().unwrap(); let mut guard = data.lock().unwrap(); match req { Request::Offer { mime_type } => guard.mime_types.push(mime_type), @@ -28,6 +28,7 @@ pub(crate) fn implement_data_source(src: NewResource) -> Resource< guard.dnd_action = DndAction::from_bits_truncate(dnd_actions); } Request::Destroy => {} + _ => unreachable!(), } }, None::, @@ -40,10 +41,10 @@ pub(crate) fn implement_data_source(src: NewResource) -> Resource< /// Access the metadata of a data source pub fn with_source_metadata T>( - source: &Resource, + source: &WlDataSource, f: F, ) -> Result { - match source.user_data::>() { + match source.as_ref().user_data::>() { Some(data) => Ok(f(&data.lock().unwrap())), None => Err(()), } diff --git a/src/wayland/data_device/dnd_grab.rs b/src/wayland/data_device/dnd_grab.rs index 4be6aeb..f7ea05d 100644 --- a/src/wayland/data_device/dnd_grab.rs +++ b/src/wayland/data_device/dnd_grab.rs @@ -16,12 +16,12 @@ use crate::wayland::{ use super::{with_source_metadata, DataDeviceData, DnDIconRole, SeatData}; pub(crate) struct DnDGrab { - data_source: Option>, - current_focus: Option>, - pending_offers: Vec>, + data_source: Option, + current_focus: Option, + pending_offers: Vec, offer_data: Option>>, - icon: Option>, - origin: Resource, + icon: Option, + origin: wl_surface::WlSurface, callback: Arc>, token: CompositorToken, seat: Seat, @@ -29,10 +29,10 @@ pub(crate) struct DnDGrab { impl + 'static> DnDGrab { pub(crate) fn new( - source: Option>, - origin: Resource, + source: Option, + origin: wl_surface::WlSurface, seat: Seat, - icon: Option>, + icon: Option, token: CompositorToken, callback: Arc>, ) -> DnDGrab { @@ -55,7 +55,7 @@ impl + 'static> PointerGrab for DnDGrab { &mut self, _handle: &mut PointerInnerHandle<'_>, location: (f64, f64), - focus: Option<(Resource, (f64, f64))>, + focus: Option<(wl_surface::WlSurface, (f64, f64))>, serial: u32, time: u32, ) { @@ -71,10 +71,10 @@ impl + 'static> PointerGrab for DnDGrab { // focus changed, we need to make a leave if appropriate if let Some(surface) = self.current_focus.take() { // only leave if there is a data source or we are on the original client - if self.data_source.is_some() || self.origin.same_client_as(&surface) { + if self.data_source.is_some() || self.origin.as_ref().same_client_as(&surface.as_ref()) { for device in &seat_data.known_devices { - if device.same_client_as(&surface) { - device.send(wl_data_device::Event::Leave); + if device.as_ref().same_client_as(&surface.as_ref()) { + device.leave(); } } // disable the offers @@ -87,7 +87,7 @@ impl + 'static> PointerGrab for DnDGrab { } if let Some((surface, (sx, sy))) = focus { // early return if the surface is no longer valid - let client = match surface.client() { + let client = match surface.as_ref().client() { Some(c) => c, None => return, }; @@ -103,16 +103,17 @@ impl + 'static> PointerGrab for DnDGrab { for device in seat_data .known_devices .iter() - .filter(|d| d.same_client_as(&surface)) + .filter(|d| d.as_ref().same_client_as(&surface.as_ref())) { let action_choice = device + .as_ref() .user_data::() .unwrap() .action_choice .clone(); // create a data offer let offer = client - .create_resource::(device.version()) + .create_resource::(device.as_ref().version()) .map(|offer| { implement_dnd_data_offer( offer, @@ -123,38 +124,24 @@ impl + 'static> PointerGrab for DnDGrab { }) .unwrap(); // advertize the offer to the client - device.send(wl_data_device::Event::DataOffer { id: offer.clone() }); + device.data_offer(&offer); with_source_metadata(source, |meta| { for mime_type in meta.mime_types.iter().cloned() { - offer.send(wl_data_offer::Event::Offer { mime_type }) + offer.offer(mime_type); } - offer.send(wl_data_offer::Event::SourceActions { - source_actions: meta.dnd_action.to_raw(), - }); + offer.source_actions(meta.dnd_action.to_raw()); }) .unwrap(); - device.send(wl_data_device::Event::Enter { - serial, - x: x - sx, - y: y - sy, - surface: surface.clone(), - id: Some(offer.clone()), - }); + device.enter(serial, &surface, x - sx, y - sy, Some(&offer)); self.pending_offers.push(offer); } self.offer_data = Some(offer_data); } else { // only send if we are on a surface of the same client - if self.origin.same_client_as(&surface) { + if self.origin.as_ref().same_client_as(&surface.as_ref()) { for device in &seat_data.known_devices { - if device.same_client_as(&surface) { - device.send(wl_data_device::Event::Enter { - serial, - x: x - sx, - y: y - sy, - surface: surface.clone(), - id: None, - }); + if device.as_ref().same_client_as(&surface.as_ref()) { + device.enter(serial, &surface, x - sx, y - sy, None); } } } @@ -162,14 +149,10 @@ impl + 'static> PointerGrab for DnDGrab { self.current_focus = Some(surface); } else { // make a move - if self.data_source.is_some() || self.origin.same_client_as(&surface) { + if self.data_source.is_some() || self.origin.as_ref().same_client_as(&surface.as_ref()) { for device in &seat_data.known_devices { - if device.same_client_as(&surface) { - device.send(wl_data_device::Event::Motion { - time, - x: x - sx, - y: y - sy, - }); + if device.as_ref().same_client_as(&surface.as_ref()) { + device.motion(time, x - sx, y - sy); } } } @@ -201,13 +184,13 @@ impl + 'static> PointerGrab for DnDGrab { false }; if let Some(ref surface) = self.current_focus { - if self.data_source.is_some() || self.origin.same_client_as(&surface) { + if self.data_source.is_some() || self.origin.as_ref().same_client_as(&surface.as_ref()) { for device in &seat_data.known_devices { - if device.same_client_as(surface) { + if device.as_ref().same_client_as(surface.as_ref()) { if validated { - device.send(wl_data_device::Event::Drop); + device.drop(); } else { - device.send(wl_data_device::Event::Leave); + device.leave(); } } } @@ -222,14 +205,14 @@ impl + 'static> PointerGrab for DnDGrab { } } if let Some(ref source) = self.data_source { - source.send(wl_data_source::Event::DndDropPerformed); + source.dnd_drop_performed(); if !validated { - source.send(wl_data_source::Event::Cancelled); + source.cancelled(); } } (&mut *self.callback.lock().unwrap())(super::DataDeviceEvent::DnDDropped); if let Some(icon) = self.icon.take() { - if icon.is_alive() { + if icon.as_ref().is_alive() { self.token.remove_role::(&icon).unwrap(); } } @@ -254,12 +237,12 @@ struct OfferData { fn implement_dnd_data_offer( offer: NewResource, - source: Resource, + source: wl_data_source::WlDataSource, offer_data: Arc>, action_choice: Arc DndAction + Send + 'static>>, -) -> Resource { +) -> wl_data_offer::WlDataOffer { use self::wl_data_offer::Request; - offer.implement( + offer.implement_closure( move |req, offer| { let mut data = offer_data.lock().unwrap(); match req { @@ -278,40 +261,40 @@ fn implement_dnd_data_offer( // check if the source and associated mime type is still valid let valid = with_source_metadata(&source, |meta| meta.mime_types.contains(&mime_type)) .unwrap_or(false) - && source.is_alive() + && source.as_ref().is_alive() && data.active; if valid { - source.send(wl_data_source::Event::Send { mime_type, fd }); + source.send(mime_type, fd); } let _ = ::nix::unistd::close(fd); } Request::Destroy => {} Request::Finish => { if !data.active { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidFinish as u32, "Cannot finish a data offer that is no longer active.".into(), ); } if !data.accepted { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidFinish as u32, "Cannot finish a data offer that has not been accepted.".into(), ); } if !data.dropped { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidFinish as u32, "Cannot finish a data offer that has not been dropped.".into(), ); } if data.chosen_action.is_empty() { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidFinish as u32, "Cannot finish a data offer with no valid action.".into(), ); } - source.send(wl_data_source::Event::DndFinished); + source.dnd_finished(); data.active = false; } Request::SetActions { @@ -320,7 +303,7 @@ fn implement_dnd_data_offer( } => { let preferred_action = DndAction::from_bits_truncate(preferred_action); if ![DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&preferred_action) { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidAction as u32, "Invalid preferred action.".into(), ); @@ -334,13 +317,10 @@ fn implement_dnd_data_offer( debug_assert!( [DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action) ); - offer.send(wl_data_offer::Event::Action { - dnd_action: data.chosen_action.to_raw(), - }); - source.send(wl_data_source::Event::Action { - dnd_action: data.chosen_action.to_raw(), - }); + offer.action(data.chosen_action.to_raw()); + source.action(data.chosen_action.to_raw()); } + _ => unreachable!(), } }, None::, diff --git a/src/wayland/data_device/mod.rs b/src/wayland/data_device/mod.rs index 6100898..f88be7d 100644 --- a/src/wayland/data_device/mod.rs +++ b/src/wayland/data_device/mod.rs @@ -83,17 +83,17 @@ pub use self::server_dnd_grab::ServerDndEvent; /// Events that are generated by interactions of the clients with the data device pub enum DataDeviceEvent { /// A client has set the selection - NewSelection(Option>), + NewSelection(Option), /// A client started a drag'n'drop as response to a user pointer action DnDStarted { /// The data source provided by the client /// /// If it is `None`, this means the DnD is restricted to surfaces of the /// same client and the client will manage data transfert by itself. - source: Option>, + source: Option, /// The icon the client requested to be used to be associated with the cursor icon /// during the drag'n'drop. - icon: Option>, + icon: Option, }, /// The drag'n'drop action was finished by the user releasing the buttons /// @@ -116,12 +116,12 @@ pub struct DnDIconRole; enum Selection { Empty, - Client(Resource), + Client(wl_data_source::WlDataSource), Compositor(SourceMetadata), } struct SeatData { - known_devices: Vec>, + known_devices: Vec, selection: Selection, log: ::slog::Logger, current_focus: Option, @@ -146,7 +146,7 @@ impl SeatData { // first sanitize the selection, reseting it to null if the client holding // it dropped it let cleanup = if let Selection::Client(ref data_source) = self.selection { - !data_source.is_alive() + !data_source.as_ref().is_alive() } else { false }; @@ -159,25 +159,25 @@ impl SeatData { // send an empty selection for dd in &self.known_devices { // skip data devices not belonging to our client - if dd.client().map(|c| !c.equals(client)).unwrap_or(true) { + if dd.as_ref().client().map(|c| !c.equals(client)).unwrap_or(true) { continue; } - dd.send(wl_data_device::Event::Selection { id: None }); + dd.selection(None); } } Selection::Client(ref data_source) => { for dd in &self.known_devices { // skip data devices not belonging to our client - if dd.client().map(|c| !c.equals(client)).unwrap_or(true) { + if dd.as_ref().client().map(|c| !c.equals(client)).unwrap_or(true) { continue; } let source = data_source.clone(); let log = self.log.clone(); // create a corresponding data offer let offer = client - .create_resource::(dd.version()) + .create_resource::(dd.as_ref().version()) .unwrap() - .implement( + .implement_closure( move |req, _offer| match req { wl_data_offer::Request::Receive { fd, mime_type } => { // check if the source and associated mime type is still valid @@ -185,12 +185,12 @@ impl SeatData { meta.mime_types.contains(&mime_type) }) .unwrap_or(false) - && source.is_alive(); + && source.as_ref().is_alive(); if !valid { // deny the receive debug!(log, "Denying a wl_data_offer.receive with invalid source."); } else { - source.send(wl_data_source::Event::Send { mime_type, fd }); + source.send(mime_type, fd); } let _ = ::nix::unistd::close(fd); } @@ -200,30 +200,35 @@ impl SeatData { (), ); // advertize the offer to the client - dd.send(wl_data_device::Event::DataOffer { id: offer.clone() }); + dd.data_offer(&offer); with_source_metadata(data_source, |meta| { for mime_type in meta.mime_types.iter().cloned() { - offer.send(wl_data_offer::Event::Offer { mime_type }) + offer.offer(mime_type); } }) .unwrap(); - dd.send(wl_data_device::Event::Selection { id: Some(offer) }); + dd.selection(Some(&offer)); } } Selection::Compositor(ref meta) => { for dd in &self.known_devices { // skip data devices not belonging to our client - if dd.client().map(|c| !c.equals(client)).unwrap_or(true) { + if dd.as_ref().client().map(|c| !c.equals(client)).unwrap_or(true) { continue; } let log = self.log.clone(); let offer_meta = meta.clone(); - let callback = dd.user_data::().unwrap().callback.clone(); + let callback = dd + .as_ref() + .user_data::() + .unwrap() + .callback + .clone(); // create a corresponding data offer let offer = client - .create_resource::(dd.version()) + .create_resource::(dd.as_ref().version()) .unwrap() - .implement( + .implement_closure( move |req, _offer| match req { wl_data_offer::Request::Receive { fd, mime_type } => { // check if the associated mime type is valid @@ -244,11 +249,11 @@ impl SeatData { (), ); // advertize the offer to the client - dd.send(wl_data_device::Event::DataOffer { id: offer.clone() }); + dd.data_offer(&offer); for mime_type in meta.mime_types.iter().cloned() { - offer.send(wl_data_offer::Event::Offer { mime_type }) + offer.offer(mime_type); } - dd.send(wl_data_device::Event::Selection { id: Some(offer) }); + dd.selection(Some(&offer)); } } } @@ -379,7 +384,7 @@ fn implement_ddm( action_choice: Arc>, token: CompositorToken, log: ::slog::Logger, -) -> Resource +) -> wl_data_device_manager::WlDataDeviceManager where F: FnMut(DndAction, DndAction) -> DndAction + Send + 'static, C: FnMut(DataDeviceEvent) + Send + 'static, @@ -387,7 +392,7 @@ where U: 'static, { use self::wl_data_device_manager::Request; - new_ddm.implement( + new_ddm.implement_closure( move |req, _ddm| match req { Request::CreateDataSource { id } => { self::data_source::implement_data_source(id); @@ -412,6 +417,7 @@ where error!(log, "Unmanaged seat given to a data device."); } }, + _ => unreachable!(), }, None::, (), @@ -430,7 +436,7 @@ fn implement_data_device( action_choice: Arc>, token: CompositorToken, log: ::slog::Logger, -) -> Resource +) -> wl_data_device::WlDataDevice where F: FnMut(DndAction, DndAction) -> DndAction + Send + 'static, C: FnMut(DataDeviceEvent) + Send + 'static, @@ -442,7 +448,7 @@ where callback: callback.clone(), action_choice, }; - new_dd.implement( + new_dd.implement_closure( move |req, dd| match req { Request::StartDrag { source, @@ -455,7 +461,7 @@ where if pointer.has_grab(serial) { if let Some(ref icon) = icon { if token.give_role::(icon).is_err() { - dd.post_error( + dd.as_ref().post_error( wl_data_device::Error::Role as u32, "Given surface already has an other role".into(), ); @@ -486,6 +492,7 @@ where Request::SetSelection { source, serial: _ } => { if let Some(keyboard) = seat.get_keyboard() { if dd + .as_ref() .client() .as_ref() .map(|c| keyboard.has_focus(c)) @@ -511,8 +518,9 @@ where .lock() .unwrap() .known_devices - .retain(|ndd| ndd.is_alive() && (!ndd.equals(&dd))) + .retain(|ndd| ndd.as_ref().is_alive() && (!ndd.as_ref().equals(&dd.as_ref()))) } + _ => unreachable!(), }, None::, dd_data, diff --git a/src/wayland/data_device/server_dnd_grab.rs b/src/wayland/data_device/server_dnd_grab.rs index ef45c03..009ce6f 100644 --- a/src/wayland/data_device/server_dnd_grab.rs +++ b/src/wayland/data_device/server_dnd_grab.rs @@ -37,8 +37,8 @@ pub enum ServerDndEvent { pub(crate) struct ServerDnDGrab { metadata: super::SourceMetadata, - current_focus: Option>, - pending_offers: Vec>, + current_focus: Option, + pending_offers: Vec, offer_data: Option>>, seat: Seat, callback: Arc>, @@ -69,7 +69,7 @@ where &mut self, _handle: &mut PointerInnerHandle<'_>, location: (f64, f64), - focus: Option<(Resource, (f64, f64))>, + focus: Option<(wl_surface::WlSurface, (f64, f64))>, serial: u32, time: u32, ) { @@ -85,8 +85,8 @@ where // focus changed, we need to make a leave if appropriate if let Some(surface) = self.current_focus.take() { for device in &seat_data.known_devices { - if device.same_client_as(&surface) { - device.send(wl_data_device::Event::Leave); + if device.as_ref().same_client_as(&surface.as_ref()) { + device.leave(); } } // disable the offers @@ -98,7 +98,7 @@ where } if let Some((surface, (sx, sy))) = focus { // early return if the surface is no longer valid - let client = match surface.client() { + let client = match surface.as_ref().client() { Some(c) => c, None => return, }; @@ -113,16 +113,17 @@ where for device in seat_data .known_devices .iter() - .filter(|d| d.same_client_as(&surface)) + .filter(|d| d.as_ref().same_client_as(&surface.as_ref())) { let action_choice = device + .as_ref() .user_data::() .unwrap() .action_choice .clone(); // create a data offer let offer = client - .create_resource::(device.version()) + .create_resource::(device.as_ref().version()) .map(|offer| { implement_dnd_data_offer( offer, @@ -134,20 +135,12 @@ where }) .unwrap(); // advertize the offer to the client - device.send(wl_data_device::Event::DataOffer { id: offer.clone() }); + device.data_offer(&offer); for mime_type in self.metadata.mime_types.iter().cloned() { - offer.send(wl_data_offer::Event::Offer { mime_type }) + offer.offer(mime_type); } - offer.send(wl_data_offer::Event::SourceActions { - source_actions: self.metadata.dnd_action.to_raw(), - }); - device.send(wl_data_device::Event::Enter { - serial, - x: x - sx, - y: y - sy, - surface: surface.clone(), - id: Some(offer.clone()), - }); + offer.source_actions(self.metadata.dnd_action.to_raw()); + device.enter(serial, &surface, x - sx, y - sy, Some(&offer)); self.pending_offers.push(offer); } self.offer_data = Some(offer_data); @@ -155,12 +148,8 @@ where } else { // make a move for device in &seat_data.known_devices { - if device.same_client_as(&surface) { - device.send(wl_data_device::Event::Motion { - time, - x: x - sx, - y: y - sy, - }); + if device.as_ref().same_client_as(&surface.as_ref()) { + device.motion(time, x - sx, y - sy); } } } @@ -192,11 +181,11 @@ where }; if let Some(ref surface) = self.current_focus { for device in &seat_data.known_devices { - if device.same_client_as(surface) { + if device.as_ref().same_client_as(surface.as_ref()) { if validated { - device.send(wl_data_device::Event::Drop); + device.drop(); } else { - device.send(wl_data_device::Event::Leave); + device.leave(); } } } @@ -239,12 +228,12 @@ fn implement_dnd_data_offer( offer_data: Arc>, callback: Arc>, action_choice: Arc DndAction + Send + 'static>>, -) -> Resource +) -> wl_data_offer::WlDataOffer where C: FnMut(ServerDndEvent) + Send + 'static, { use self::wl_data_offer::Request; - offer.implement( + offer.implement_closure( move |req, offer| { let mut data = offer_data.lock().unwrap(); match req { @@ -264,25 +253,25 @@ where Request::Destroy => {} Request::Finish => { if !data.active { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidFinish as u32, "Cannot finish a data offer that is no longer active.".into(), ); } if !data.accepted { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidFinish as u32, "Cannot finish a data offer that has not been accepted.".into(), ); } if !data.dropped { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidFinish as u32, "Cannot finish a data offer that has not been dropped.".into(), ); } if data.chosen_action.is_empty() { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidFinish as u32, "Cannot finish a data offer with no valid action.".into(), ); @@ -296,7 +285,7 @@ where } => { let preferred_action = DndAction::from_bits_truncate(preferred_action); if ![DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&preferred_action) { - offer.post_error( + offer.as_ref().post_error( wl_data_offer::Error::InvalidAction as u32, "Invalid preferred action.".into(), ); @@ -308,11 +297,10 @@ where debug_assert!( [DndAction::Move, DndAction::Copy, DndAction::Ask].contains(&data.chosen_action) ); - offer.send(wl_data_offer::Event::Action { - dnd_action: data.chosen_action.to_raw(), - }); + offer.action(data.chosen_action.to_raw()); (&mut *callback.lock().unwrap())(ServerDndEvent::Action(data.chosen_action)); } + _ => unreachable!(), } }, None::, diff --git a/src/wayland/output/mod.rs b/src/wayland/output/mod.rs index 51e0f70..3ffd49a 100644 --- a/src/wayland/output/mod.rs +++ b/src/wayland/output/mod.rs @@ -94,7 +94,7 @@ pub struct PhysicalProperties { struct Inner { name: String, log: ::slog::Logger, - instances: Vec>, + instances: Vec, physical: PhysicalProperties, location: (i32, i32), transform: Transform, @@ -105,7 +105,7 @@ struct Inner { } impl Inner { - fn new_global(&mut self, output: Resource) { + fn new_global(&mut self, output: WlOutput) { trace!(self.log, "New global instantiated."); if self.modes.is_empty() { @@ -127,32 +127,27 @@ impl Inner { if Some(mode) == self.preferred_mode { flags |= WMode::Preferred; } - output.send(Event::Mode { - flags, - width: mode.width, - height: mode.height, - refresh: mode.refresh, - }); + output.mode(flags, mode.width, mode.height, mode.refresh); } - if output.version() >= 2 { - output.send(Event::Scale { factor: self.scale }); - output.send(Event::Done); + if output.as_ref().version() >= 2 { + output.scale(self.scale); + output.done(); } self.instances.push(output); } - fn send_geometry(&self, output: &Resource) { - output.send(Event::Geometry { - x: self.location.0, - y: self.location.1, - physical_width: self.physical.width, - physical_height: self.physical.height, - subpixel: self.physical.subpixel, - make: self.physical.make.clone(), - model: self.physical.model.clone(), - transform: self.transform, - }); + fn send_geometry(&self, output: &WlOutput) { + output.geometry( + self.location.0, + self.location.1, + self.physical.width, + self.physical.height, + self.physical.subpixel, + self.physical.make.clone(), + self.physical.model.clone(), + self.transform, + ); } } @@ -199,14 +194,15 @@ impl Output { let output = Output { inner: inner.clone() }; let global = display.create_global(3, move |new_output: NewResource<_>, _version| { - let output = new_output.implement( - |req, _| { - // this will break if new variants are added :) - let Request::Release = req; - }, - Some(|output: Resource| { - let inner = output.user_data::>>().unwrap(); - inner.lock().unwrap().instances.retain(|o| !o.equals(&output)); + let output = new_output.implement_closure( + |_, _| {}, + Some(|output: WlOutput| { + let inner = output.as_ref().user_data::>>().unwrap(); + inner + .lock() + .unwrap() + .instances + .retain(|o| !o.as_ref().equals(&output.as_ref())); }), inner.clone(), ); @@ -285,34 +281,29 @@ impl Output { } for output in &inner.instances { if let Some(mode) = new_mode { - output.send(Event::Mode { - flags, - width: mode.width, - height: mode.height, - refresh: mode.refresh, - }); + output.mode(flags, mode.width, mode.height, mode.refresh); } if new_transform.is_some() { inner.send_geometry(output); } if let Some(scale) = new_scale { - if output.version() >= 2 { - output.send(Event::Scale { factor: scale }); + if output.as_ref().version() >= 2 { + output.scale(scale); } } - if output.version() >= 2 { - output.send(Event::Done); + if output.as_ref().version() >= 2 { + output.done(); } } } /// Check is given [`wl_output`](WlOutput) instance is managed by this [`Output`]. - pub fn owns(&self, output: &Resource) -> bool { + pub fn owns(&self, output: &WlOutput) -> bool { self.inner .lock() .unwrap() .instances .iter() - .any(|o| o.equals(output)) + .any(|o| o.as_ref().equals(output.as_ref())) } } diff --git a/src/wayland/seat/keyboard.rs b/src/wayland/seat/keyboard.rs index 5ac432f..cdc8d12 100644 --- a/src/wayland/seat/keyboard.rs +++ b/src/wayland/seat/keyboard.rs @@ -104,15 +104,15 @@ impl<'a> Default for XkbConfig<'a> { } struct KbdInternal { - known_kbds: Vec>, - focus: Option>, + known_kbds: Vec, + focus: Option, pressed_keys: Vec, mods_state: ModifiersState, keymap: xkb::Keymap, state: xkb::State, repeat_rate: i32, repeat_delay: i32, - focus_hook: Box>)>, + focus_hook: Box)>, } // This is OK because all parts of `xkb` will remain on the @@ -124,7 +124,7 @@ impl KbdInternal { xkb_config: XkbConfig<'_>, repeat_rate: i32, repeat_delay: i32, - focus_hook: Box>)>, + focus_hook: Box)>, ) -> Result { // we create a new contex for each keyboard because libxkbcommon is actually NOT threadsafe // so confining it inside the KbdInternal allows us to use Rusts mutability rules to make @@ -205,11 +205,11 @@ impl KbdInternal { fn with_focused_kbds(&self, mut f: F) where - F: FnMut(&Resource, &Resource), + F: FnMut(&WlKeyboard, &WlSurface), { if let Some(ref surface) = self.focus { for kbd in &self.known_kbds { - if kbd.same_client_as(surface) { + if kbd.as_ref().same_client_as(surface.as_ref()) { f(kbd, surface); } } @@ -235,7 +235,7 @@ pub(crate) fn create_keyboard_handler( focus_hook: F, ) -> Result where - F: FnMut(Option<&Resource>) + 'static, + F: FnMut(Option<&WlSurface>) + 'static, { let log = logger.new(o!("smithay_module" => "xkbcommon_handler")); info!(log, "Initializing a xkbcommon handler with keymap query"; @@ -332,20 +332,9 @@ impl KeyboardHandle { }; guard.with_focused_kbds(|kbd, _| { if let Some((dep, la, lo, gr)) = modifiers { - kbd.send(Event::Modifiers { - serial, - mods_depressed: dep, - mods_latched: la, - mods_locked: lo, - group: gr, - }); + kbd.modifiers(serial, dep, la, lo, gr); } - kbd.send(Event::Key { - serial, - time, - key: keycode, - state: wl_state, - }); + kbd.key(serial, time, keycode, wl_state); }); if guard.focus.is_some() { trace!(self.arc.logger, "Input forwarded to client"); @@ -360,22 +349,19 @@ impl KeyboardHandle { /// will be sent a [`wl_keyboard::Event::Leave`](wayland_server::protocol::wl_keyboard::Event::Leave) /// event, and if the new focus is not `None`, /// a [`wl_keyboard::Event::Enter`](wayland_server::protocol::wl_keyboard::Event::Enter) event will be sent. - pub fn set_focus(&self, focus: Option<&Resource>, serial: u32) { + pub fn set_focus(&self, focus: Option<&WlSurface>, serial: u32) { let mut guard = self.arc.internal.lock().unwrap(); let same = guard .focus .as_ref() - .and_then(|f| focus.map(|s| s.equals(f))) + .and_then(|f| focus.map(|s| s.as_ref().equals(f.as_ref()))) .unwrap_or(false); if !same { // unset old focus guard.with_focused_kbds(|kbd, s| { - kbd.send(Event::Leave { - serial, - surface: s.clone(), - }); + kbd.leave(serial, &s); }); // set new focus @@ -383,18 +369,8 @@ impl KeyboardHandle { let (dep, la, lo, gr) = guard.serialize_modifiers(); let keys = guard.serialize_pressed_keys(); guard.with_focused_kbds(|kbd, surface| { - kbd.send(Event::Modifiers { - serial, - mods_depressed: dep, - mods_latched: la, - mods_locked: lo, - group: gr, - }); - kbd.send(Event::Enter { - serial, - surface: surface.clone(), - keys: keys.clone(), - }); + kbd.modifiers(serial, dep, la, lo, gr); + kbd.enter(serial, &surface, keys.clone()); }); { let KbdInternal { @@ -422,7 +398,7 @@ impl KeyboardHandle { .unwrap() .focus .as_ref() - .and_then(|f| f.client()) + .and_then(|f| f.as_ref().client()) .map(|c| c.equals(client)) .unwrap_or(false) } @@ -432,18 +408,18 @@ impl KeyboardHandle { /// The keymap will automatically be sent to it /// /// This should be done first, before anything else is done with this keyboard. - pub(crate) fn new_kbd(&self, kbd: Resource) { + pub(crate) fn new_kbd(&self, kbd: WlKeyboard) { trace!(self.arc.logger, "Sending keymap to client"); // prepare a tempfile with the keymap, to send it to the client let ret = tempfile().and_then(|mut f| { f.write_all(self.arc.keymap.as_bytes())?; f.flush()?; - kbd.send(Event::Keymap { - format: KeymapFormat::XkbV1, - fd: f.as_raw_fd(), - size: self.arc.keymap.as_bytes().len() as u32, - }); + kbd.keymap( + KeymapFormat::XkbV1, + f.as_raw_fd(), + self.arc.keymap.as_bytes().len() as u32, + ); Ok(()) }); @@ -456,11 +432,8 @@ impl KeyboardHandle { }; let mut guard = self.arc.internal.lock().unwrap(); - if kbd.version() >= 4 { - kbd.send(Event::RepeatInfo { - rate: guard.repeat_rate, - delay: guard.repeat_delay, - }); + if kbd.as_ref().version() >= 4 { + kbd.repeat_info(guard.repeat_rate, guard.repeat_delay); } guard.known_kbds.push(kbd); } @@ -471,7 +444,7 @@ impl KeyboardHandle { guard.repeat_delay = delay; guard.repeat_rate = rate; for kbd in &guard.known_kbds { - kbd.send(Event::RepeatInfo { rate, delay }); + kbd.repeat_info(rate, delay); } } } @@ -479,26 +452,27 @@ impl KeyboardHandle { pub(crate) fn implement_keyboard( new_keyboard: NewResource, handle: Option<&KeyboardHandle>, -) -> Resource { +) -> WlKeyboard { let destructor = match handle { Some(h) => { let arc = h.arc.clone(); - Some(move |keyboard: Resource<_>| { + Some(move |keyboard: WlKeyboard| { arc.internal .lock() .unwrap() .known_kbds - .retain(|k| !k.equals(&keyboard)) + .retain(|k| !k.as_ref().equals(&keyboard.as_ref())) }) } None => None, }; - new_keyboard.implement( + new_keyboard.implement_closure( |request, _keyboard| { match request { Request::Release => { // Our destructors already handle it } + _ => unreachable!(), } }, destructor, diff --git a/src/wayland/seat/mod.rs b/src/wayland/seat/mod.rs index b8f3506..b4781cd 100644 --- a/src/wayland/seat/mod.rs +++ b/src/wayland/seat/mod.rs @@ -67,7 +67,7 @@ use wayland_server::{ struct Inner { pointer: Option, keyboard: Option, - known_seats: Vec>, + known_seats: Vec, } pub(crate) struct SeatArc { @@ -92,7 +92,7 @@ impl Inner { fn send_all_caps(&self) { let capabilities = self.compute_caps(); for seat in &self.known_seats { - seat.send(wl_seat::Event::Capabilities { capabilities }); + seat.capabilities(capabilities); } } } @@ -148,22 +148,21 @@ impl Seat { let global = display.create_global(5, move |new_seat, _version| { let seat = implement_seat(new_seat, arc.clone(), token.clone()); let mut inner = arc.inner.lock().unwrap(); - if seat.version() >= 2 { - seat.send(wl_seat::Event::Name { - name: arc.name.clone(), - }); + if seat.as_ref().version() >= 2 { + seat.name(arc.name.clone()); } - seat.send(wl_seat::Event::Capabilities { - capabilities: inner.compute_caps(), - }); + seat.capabilities(inner.compute_caps()); inner.known_seats.push(seat); }); (seat, global) } /// Attempt to retrieve a [`Seat`] from an existing resource - pub fn from_resource(seat: &Resource) -> Option { - seat.user_data::>().cloned().map(|arc| Seat { arc }) + pub fn from_resource(seat: &wl_seat::WlSeat) -> Option { + seat.as_ref() + .user_data::>() + .cloned() + .map(|arc| Seat { arc }) } /// Acces the `UserDataMap` associated with this `Seat` @@ -287,7 +286,7 @@ impl Seat { mut focus_hook: F, ) -> Result where - F: FnMut(&Seat, Option<&Resource>) + 'static, + F: FnMut(&Seat, Option<&wl_surface::WlSurface>) + 'static, { let me = self.clone(); let mut inner = self.arc.inner.lock().unwrap(); @@ -326,9 +325,9 @@ impl Seat { } /// Checks whether a given [`WlSeat`](wl_seat::WlSeat) is associated with this [`Seat`] - pub fn owns(&self, seat: &Resource) -> bool { + pub fn owns(&self, seat: &wl_seat::WlSeat) -> bool { let inner = self.arc.inner.lock().unwrap(); - inner.known_seats.iter().any(|s| s.equals(seat)) + inner.known_seats.iter().any(|s| s.as_ref().equals(seat.as_ref())) } } @@ -342,15 +341,15 @@ fn implement_seat( new_seat: NewResource, arc: Arc, token: CompositorToken, -) -> Resource +) -> wl_seat::WlSeat where R: Role + 'static, U: 'static, { let dest_arc = arc.clone(); - new_seat.implement( + new_seat.implement_closure( move |request, seat| { - let arc = seat.user_data::>().unwrap(); + let arc = seat.as_ref().user_data::>().unwrap(); let inner = arc.inner.lock().unwrap(); match request { wl_seat::Request::GetPointer { id } => { @@ -376,15 +375,16 @@ where wl_seat::Request::Release => { // Our destructors already handle it } + _ => unreachable!(), } }, - Some(move |seat| { + Some(move |seat: wl_seat::WlSeat| { dest_arc .inner .lock() .unwrap() .known_seats - .retain(|s| !s.equals(&seat)); + .retain(|s| !s.as_ref().equals(&seat.as_ref())); }), arc, ) diff --git a/src/wayland/seat/pointer.rs b/src/wayland/seat/pointer.rs index 8aba91e..354a22d 100644 --- a/src/wayland/seat/pointer.rs +++ b/src/wayland/seat/pointer.rs @@ -24,7 +24,7 @@ pub enum CursorImageStatus { /// The compositor should draw its cursor Default, /// The cursor should be drawn using this surface as an image - Image(Resource), + Image(WlSurface), } enum GrabStatus { @@ -34,13 +34,13 @@ enum GrabStatus { } struct PointerInternal { - known_pointers: Vec>, - focus: Option<(Resource, (f64, f64))>, - pending_focus: Option<(Resource, (f64, f64))>, + known_pointers: Vec, + focus: Option<(WlSurface, (f64, f64))>, + pending_focus: Option<(WlSurface, (f64, f64))>, location: (f64, f64), grab: GrabStatus, pressed_buttons: Vec, - image_callback: Box, + image_callback: Box, } impl PointerInternal { @@ -60,7 +60,7 @@ impl PointerInternal { // don't remove the role, we are just re-binding the same surface } _ => { - if surface.is_alive() { + if surface.as_ref().is_alive() { token.remove_role::(&surface).unwrap(); } } @@ -82,11 +82,11 @@ impl PointerInternal { fn with_focused_pointers(&self, mut f: F) where - F: FnMut(&Resource, &Resource), + F: FnMut(&WlPointer, &WlSurface), { if let Some((ref focus, _)) = self.focus { for ptr in &self.known_pointers { - if ptr.same_client_as(focus) { + if ptr.as_ref().same_client_as(focus.as_ref()) { f(ptr, focus) } } @@ -131,7 +131,7 @@ pub struct PointerHandle { } impl PointerHandle { - pub(crate) fn new_pointer(&self, pointer: Resource) { + pub(crate) fn new_pointer(&self, pointer: WlPointer) { let mut guard = self.inner.lock().unwrap(); guard.known_pointers.push(pointer); } @@ -180,7 +180,7 @@ impl PointerHandle { pub fn motion( &self, location: (f64, f64), - focus: Option<(Resource, (f64, f64))>, + focus: Option<(WlSurface, (f64, f64))>, serial: u32, time: u32, ) { @@ -204,6 +204,7 @@ impl PointerHandle { ButtonState::Released => { inner.pressed_buttons.retain(|b| *b != button); } + _ => unreachable!(), } inner.with_grab(|mut handle, grab| { grab.button(&mut handle, button, state, serial, time); @@ -235,13 +236,13 @@ impl PointerHandle { /// When your grab ends (either as you requested it or if it was forcefully cancelled by the server), /// the struct implementing this trait will be dropped. As such you should put clean-up logic in the destructor, /// rather than trying to guess when the grab will end. -pub trait PointerGrab: Send + Sync { +pub trait PointerGrab { /// A motion was reported fn motion( &mut self, handle: &mut PointerInnerHandle<'_>, location: (f64, f64), - focus: Option<(Resource, (f64, f64))>, + focus: Option<(WlSurface, (f64, f64))>, serial: u32, time: u32, ); @@ -284,7 +285,7 @@ impl<'a> PointerInnerHandle<'a> { } /// Access the current focus of this pointer - pub fn current_focus(&self) -> Option<&(Resource, (f64, f64))> { + pub fn current_focus(&self) -> Option<&(WlSurface, (f64, f64))> { self.inner.focus.as_ref() } @@ -315,7 +316,7 @@ impl<'a> PointerInnerHandle<'a> { pub fn motion( &mut self, (x, y): (f64, f64), - focus: Option<(Resource, (f64, f64))>, + focus: Option<(WlSurface, (f64, f64))>, serial: u32, time: u32, ) { @@ -324,19 +325,16 @@ impl<'a> PointerInnerHandle<'a> { self.inner.location = (x, y); if let Some((ref current_focus, _)) = self.inner.focus { if let Some((ref surface, _)) = focus { - if current_focus.equals(surface) { + if current_focus.as_ref().equals(surface.as_ref()) { leave = false; } } } if leave { self.inner.with_focused_pointers(|pointer, surface| { - pointer.send(Event::Leave { - serial, - surface: surface.clone(), - }); - if pointer.version() >= 5 { - pointer.send(Event::Frame); + pointer.leave(serial, &surface); + if pointer.as_ref().version() >= 5 { + pointer.frame(); } }); self.inner.focus = None; @@ -351,26 +349,17 @@ impl<'a> PointerInnerHandle<'a> { self.inner.focus = Some((surface.clone(), (sx, sy))); if entered { self.inner.with_focused_pointers(|pointer, surface| { - pointer.send(Event::Enter { - serial, - surface: surface.clone(), - surface_x: x - sx, - surface_y: y - sy, - }); - if pointer.version() >= 5 { - pointer.send(Event::Frame); + pointer.enter(serial, &surface, x - sx, y - sy); + if pointer.as_ref().version() >= 5 { + pointer.frame(); } }) } else { // we were on top of a surface and remained on it self.inner.with_focused_pointers(|pointer, _| { - pointer.send(Event::Motion { - time, - surface_x: x - sx, - surface_y: y - sy, - }); - if pointer.version() >= 5 { - pointer.send(Event::Frame); + pointer.motion(time, x - sx, y - sy); + if pointer.as_ref().version() >= 5 { + pointer.frame(); } }) } @@ -383,14 +372,9 @@ impl<'a> PointerInnerHandle<'a> { /// objects matching with the currently focused surface. pub fn button(&self, button: u32, state: ButtonState, serial: u32, time: u32) { self.inner.with_focused_pointers(|pointer, _| { - pointer.send(Event::Button { - serial, - time, - button, - state, - }); - if pointer.version() >= 5 { - pointer.send(Event::Frame); + pointer.button(serial, time, button, state); + if pointer.as_ref().version() >= 5 { + pointer.frame(); } }) } @@ -403,52 +387,32 @@ impl<'a> PointerInnerHandle<'a> { self.inner.with_focused_pointers(|pointer, _| { // axis if details.axis.0 != 0.0 { - pointer.send(Event::Axis { - time: details.time, - axis: Axis::HorizontalScroll, - value: details.axis.0, - }); + pointer.axis(details.time, Axis::HorizontalScroll, details.axis.0); } if details.axis.1 != 0.0 { - pointer.send(Event::Axis { - time: details.time, - axis: Axis::VerticalScroll, - value: details.axis.1, - }); + pointer.axis(details.time, Axis::VerticalScroll, details.axis.1); } - if pointer.version() >= 5 { + if pointer.as_ref().version() >= 5 { // axis source if let Some(source) = details.source { - pointer.send(Event::AxisSource { axis_source: source }); + pointer.axis_source(source); } // axis discrete if details.discrete.0 != 0 { - pointer.send(Event::AxisDiscrete { - axis: Axis::HorizontalScroll, - discrete: details.discrete.0, - }); + pointer.axis_discrete(Axis::HorizontalScroll, details.discrete.0); } if details.discrete.1 != 0 { - pointer.send(Event::AxisDiscrete { - axis: Axis::VerticalScroll, - discrete: details.discrete.1, - }); + pointer.axis_discrete(Axis::VerticalScroll, details.discrete.1); } // stop if details.stop.0 { - pointer.send(Event::AxisStop { - time: details.time, - axis: Axis::HorizontalScroll, - }); + pointer.axis_stop(details.time, Axis::HorizontalScroll); } if details.stop.1 { - pointer.send(Event::AxisStop { - time: details.time, - axis: Axis::VerticalScroll, - }); + pointer.axis_stop(details.time, Axis::VerticalScroll); } // frame - pointer.send(Event::Frame); + pointer.frame(); } }); } @@ -511,6 +475,7 @@ impl AxisFrame { Axis::VerticalScroll => { self.discrete.1 = steps; } + _ => unreachable!(), }; self } @@ -525,6 +490,7 @@ impl AxisFrame { Axis::VerticalScroll => { self.axis.1 = value; } + _ => unreachable!(), }; self } @@ -541,6 +507,7 @@ impl AxisFrame { Axis::VerticalScroll => { self.stop.1 = true; } + _ => unreachable!(), }; self } @@ -561,24 +528,24 @@ pub(crate) fn implement_pointer( new_pointer: NewResource, handle: Option<&PointerHandle>, token: CompositorToken, -) -> Resource +) -> WlPointer where R: Role + 'static, U: 'static, { let inner = handle.map(|h| h.inner.clone()); let destructor = match inner.clone() { - Some(inner) => Some(move |pointer: Resource<_>| { + Some(inner) => Some(move |pointer: WlPointer| { inner .lock() .unwrap() .known_pointers - .retain(|p| !p.equals(&pointer)) + .retain(|p| !p.as_ref().equals(&pointer.as_ref())) }), None => None, }; - new_pointer.implement( - move |request, pointer| { + new_pointer.implement_closure( + move |request, pointer: WlPointer| { match request { Request::SetCursor { serial: _, @@ -596,7 +563,7 @@ where .. } = *guard; if let Some((ref focus, _)) = *focus { - if focus.same_client_as(&pointer) { + if focus.as_ref().same_client_as(&pointer.as_ref()) { match surface { Some(surface) => { let role_data = CursorImageRole { @@ -608,7 +575,7 @@ where if token.with_role_data(&surface, |data| *data = role_data).is_err() && token.give_role_with(&surface, role_data).is_err() { - pointer.post_error( + pointer.as_ref().post_error( wl_pointer::Error::Role as u32, "Given wl_surface has another role.".into(), ); @@ -627,6 +594,7 @@ where Request::Release => { // Our destructors already handle it } + _ => unreachable!(), } }, destructor, @@ -646,7 +614,7 @@ impl PointerGrab for DefaultGrab { &mut self, handle: &mut PointerInnerHandle<'_>, location: (f64, f64), - focus: Option<(Resource, (f64, f64))>, + focus: Option<(WlSurface, (f64, f64))>, serial: u32, time: u32, ) { @@ -681,8 +649,8 @@ impl PointerGrab for DefaultGrab { // In case the user maintains several simultaneous clicks, release // the grab once all are released. struct ClickGrab { - current_focus: Option<(Resource, (f64, f64))>, - pending_focus: Option<(Resource, (f64, f64))>, + current_focus: Option<(WlSurface, (f64, f64))>, + pending_focus: Option<(WlSurface, (f64, f64))>, } impl PointerGrab for ClickGrab { @@ -690,7 +658,7 @@ impl PointerGrab for ClickGrab { &mut self, handle: &mut PointerInnerHandle<'_>, location: (f64, f64), - focus: Option<(Resource, (f64, f64))>, + focus: Option<(WlSurface, (f64, f64))>, serial: u32, time: u32, ) { diff --git a/src/wayland/shell/legacy/mod.rs b/src/wayland/shell/legacy/mod.rs index c994f9a..3615447 100644 --- a/src/wayland/shell/legacy/mod.rs +++ b/src/wayland/shell/legacy/mod.rs @@ -98,8 +98,8 @@ pub struct ShellSurfaceRole { /// A handle to a shell surface pub struct ShellSurface { - wl_surface: Resource, - shell_surface: Resource, + wl_surface: wl_surface::WlSurface, + shell_surface: wl_shell_surface::WlShellSurface, token: CompositorToken, _d: ::std::marker::PhantomData, } @@ -112,18 +112,18 @@ where { /// Is the shell surface referred by this handle still alive? pub fn alive(&self) -> bool { - self.shell_surface.is_alive() && self.wl_surface.is_alive() + self.shell_surface.as_ref().is_alive() && self.wl_surface.as_ref().is_alive() } /// Do this handle and the other one actually refer to the same shell surface? pub fn equals(&self, other: &Self) -> bool { - self.shell_surface.equals(&other.shell_surface) + self.shell_surface.as_ref().equals(&other.shell_surface.as_ref()) } /// Access the underlying `wl_surface` of this toplevel surface /// /// Returns `None` if the toplevel surface actually no longer exists. - pub fn get_surface(&self) -> Option<&Resource> { + pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> { if self.alive() { Some(&self.wl_surface) } else { @@ -153,7 +153,7 @@ where } }); if let Ok(true) = ret { - self.shell_surface.send(wl_shell_surface::Event::Ping { serial }); + self.shell_surface.ping(serial); Ok(()) } else { Err(()) @@ -162,16 +162,12 @@ where /// Send a configure event to this toplevel surface to suggest it a new configuration pub fn send_configure(&self, size: (u32, u32), edges: wl_shell_surface::Resize) { - self.shell_surface.send(wl_shell_surface::Event::Configure { - edges, - width: size.0 as i32, - height: size.1 as i32, - }) + self.shell_surface.configure(edges, size.0 as i32, size.1 as i32) } /// Signal a popup surface that it has lost focus pub fn send_popup_done(&self) { - self.shell_surface.send(wl_shell_surface::Event::PopupDone) + self.shell_surface.popup_done() } /// Access the user data you associated to this surface @@ -195,7 +191,7 @@ pub enum ShellSurfaceKind { /// and as such should only be visible in their parent window is, and on top of it. Transient { /// The surface considered as parent - parent: Resource, + parent: wl_surface::WlSurface, /// Location relative to the parent location: (i32, i32), /// Wether this window should be marked as inactive @@ -208,7 +204,7 @@ pub enum ShellSurfaceKind { /// Framerate (relevant only for driver fullscreen) framerate: u32, /// Requested output if any - output: Option>, + output: Option, }, /// A popup surface /// @@ -216,7 +212,7 @@ pub enum ShellSurfaceKind { /// contexts. Popup { /// The parent surface of this popup - parent: Resource, + parent: wl_surface::WlSurface, /// The serial of the input event triggering the creation of this /// popup serial: u32, @@ -226,7 +222,7 @@ pub enum ShellSurfaceKind { location: (i32, i32), /// Seat associated this the input that triggered the creation of the /// popup. Used to define when the "popup done" event is sent. - seat: Resource, + seat: wl_seat::WlSeat, }, /// A maximized surface /// @@ -234,7 +230,7 @@ pub enum ShellSurfaceKind { /// while keeping any relevant desktop-environment interface visible. Maximized { /// Requested output for maximization - output: Option>, + output: Option, }, } @@ -264,7 +260,7 @@ pub enum ShellRequest { /// Serial of the implicit grab that initiated the move serial: u32, /// Seat associated with the move - seat: Resource, + seat: wl_seat::WlSeat, }, /// Start of an interactive resize /// @@ -275,7 +271,7 @@ pub enum ShellRequest { /// Serial of the implicit grab that initiated the resize serial: u32, /// Seat associated with the resize - seat: Resource, + seat: wl_seat::WlSeat, /// Direction of the resize edges: wl_shell_surface::Resize, }, @@ -331,21 +327,13 @@ where let implementation = Rc::new(RefCell::new(implementation)); - let dtoken = display.get_token(); - let state = Arc::new(Mutex::new(ShellState { known_surfaces: Vec::new(), })); let state2 = state.clone(); let global = display.create_global(1, move |shell, _version| { - self::wl_handlers::implement_shell( - shell, - dtoken.clone(), - ctoken, - implementation.clone(), - state2.clone(), - ); + self::wl_handlers::implement_shell(shell, ctoken, implementation.clone(), state2.clone()); }); (state, global) diff --git a/src/wayland/shell/legacy/wl_handlers.rs b/src/wayland/shell/legacy/wl_handlers.rs index b39bd80..bad99d7 100644 --- a/src/wayland/shell/legacy/wl_handlers.rs +++ b/src/wayland/shell/legacy/wl_handlers.rs @@ -6,7 +6,7 @@ use std::{ use wayland_server::{ protocol::{wl_shell, wl_shell_surface, wl_surface}, - DisplayToken, NewResource, Resource, + NewResource, Resource, }; use crate::wayland::compositor::{roles::Role, CompositorToken}; @@ -15,7 +15,6 @@ use super::{ShellRequest, ShellState, ShellSurface, ShellSurfaceKind, ShellSurfa pub(crate) fn implement_shell( shell: NewResource, - dtoken: DisplayToken, ctoken: CompositorToken, implementation: Rc>, state: Arc>>, @@ -25,10 +24,12 @@ pub(crate) fn implement_shell( R: Role> + 'static, Impl: FnMut(ShellRequest) + 'static, { - let dtoken2 = dtoken.clone(); - shell.implement_nonsend( - move |req, shell: Resource<_>| { - let wl_shell::Request::GetShellSurface { id, surface } = req; + shell.implement_closure( + move |req, shell| { + let (id, surface) = match req { + wl_shell::Request::GetShellSurface { id, surface } => (id, surface), + _ => unreachable!(), + }; let role_data = ShellSurfaceRole { title: "".into(), class: "".into(), @@ -36,17 +37,13 @@ pub(crate) fn implement_shell( user_data: Default::default(), }; if ctoken.give_role_with(&surface, role_data).is_err() { - shell.post_error(wl_shell::Error::Role as u32, "Surface already has a role.".into()); + shell + .as_ref() + .post_error(wl_shell::Error::Role as u32, "Surface already has a role.".into()); return; } - let shell_surface = implement_shell_surface( - id, - surface, - implementation.clone(), - dtoken.clone(), - ctoken, - state.clone(), - ); + let shell_surface = + implement_shell_surface(id, surface, implementation.clone(), ctoken, state.clone()); state .lock() .unwrap() @@ -59,12 +56,11 @@ pub(crate) fn implement_shell( }, None::, (), - &dtoken2, ); } fn make_handle( - shell_surface: &Resource, + shell_surface: &wl_shell_surface::WlShellSurface, token: CompositorToken, ) -> ShellSurface where @@ -73,6 +69,7 @@ where SD: 'static, { let data = shell_surface + .as_ref() .user_data::>() .unwrap(); ShellSurface { @@ -84,18 +81,17 @@ where } pub(crate) struct ShellSurfaceUserData { - surface: Resource, + surface: wl_surface::WlSurface, state: Arc>>, } fn implement_shell_surface( shell_surface: NewResource, - surface: Resource, + surface: wl_surface::WlSurface, implementation: Rc>, - dtoken: DisplayToken, ctoken: CompositorToken, state: Arc>>, -) -> Resource +) -> wl_shell_surface::WlShellSurface where U: 'static, SD: 'static, @@ -103,9 +99,10 @@ where Impl: FnMut(ShellRequest) + 'static, { use self::wl_shell_surface::Request; - shell_surface.implement_nonsend( - move |req, shell_surface: Resource<_>| { + shell_surface.implement_closure( + move |req, shell_surface| { let data = shell_surface + .as_ref() .user_data::>() .unwrap(); let mut user_impl = implementation.borrow_mut(); @@ -193,15 +190,16 @@ where .with_role_data(&data.surface, |data| data.class = class_) .expect("wl_shell_surface exists but surface has not shell_surface role?!"); } + _ => unreachable!(), } }, - Some(|shell_surface: Resource<_>| { + Some(|shell_surface: wl_shell_surface::WlShellSurface| { let data = shell_surface + .as_ref() .user_data::>() .unwrap(); data.state.lock().unwrap().cleanup_surfaces(); }), ShellSurfaceUserData { surface, state }, - &dtoken, ) } diff --git a/src/wayland/shell/xdg/mod.rs b/src/wayland/shell/xdg/mod.rs index 5ac3ee2..88792c6 100644 --- a/src/wayland/shell/xdg/mod.rs +++ b/src/wayland/shell/xdg/mod.rs @@ -103,7 +103,7 @@ use wayland_protocols::{ }; use wayland_server::{ protocol::{wl_output, wl_seat, wl_surface}, - Display, DisplayToken, Global, Resource, + Display, Global, Resource, }; // handlers for the xdg_shell protocol @@ -204,7 +204,7 @@ pub struct ToplevelState { /// /// If this surface has a parent, it should be hidden /// or displayed, brought up at the same time as it. - pub parent: Option>, + pub parent: Option, /// Title of this shell surface pub title: String, /// App id for this shell surface @@ -238,7 +238,7 @@ impl Clone for ToplevelState { /// The pending state of a popup surface pub struct PopupState { /// Parent of this popup surface - pub parent: Option>, + pub parent: Option, /// The positioner specifying how this tooltip should /// be placed relative to its parent. pub positioner: PositionerState, @@ -262,7 +262,6 @@ impl Default for XdgSurfacePendingState { pub(crate) struct ShellData { log: ::slog::Logger, compositor_token: CompositorToken, - display_token: DisplayToken, user_impl: Rc)>>, shell_state: Arc>>, } @@ -272,7 +271,6 @@ impl Clone for ShellData { ShellData { log: self.log.clone(), compositor_token: self.compositor_token, - display_token: self.display_token.clone(), user_impl: self.user_impl.clone(), shell_state: self.shell_state.clone(), } @@ -305,7 +303,6 @@ where let shell_data = ShellData { log: log.new(o!("smithay_module" => "xdg_shell_handler")), - display_token: display.get_token(), compositor_token: ctoken, user_impl: Rc::new(RefCell::new(implementation)), shell_state: shell_state.clone(), @@ -355,8 +352,8 @@ where */ enum ShellClientKind { - Xdg(Resource), - ZxdgV6(Resource), + Xdg(xdg_wm_base::XdgWmBase), + ZxdgV6(zxdg_shell_v6::ZxdgShellV6), } pub(crate) struct ShellClientData { @@ -396,8 +393,8 @@ where /// Is the shell client represented by this handle still connected? pub fn alive(&self) -> bool { match self.kind { - ShellClientKind::Xdg(ref s) => s.is_alive(), - ShellClientKind::ZxdgV6(ref s) => s.is_alive(), + ShellClientKind::Xdg(ref s) => s.as_ref().is_alive(), + ShellClientKind::ZxdgV6(ref s) => s.as_ref().is_alive(), } } @@ -405,8 +402,10 @@ where /// same shell client pub fn equals(&self, other: &Self) -> bool { match (&self.kind, &other.kind) { - (&ShellClientKind::Xdg(ref s1), &ShellClientKind::Xdg(ref s2)) => s1.equals(s2), - (&ShellClientKind::ZxdgV6(ref s1), &ShellClientKind::ZxdgV6(ref s2)) => s1.equals(s2), + (&ShellClientKind::Xdg(ref s1), &ShellClientKind::Xdg(ref s2)) => s1.as_ref().equals(s2.as_ref()), + (&ShellClientKind::ZxdgV6(ref s1), &ShellClientKind::ZxdgV6(ref s2)) => { + s1.as_ref().equals(s2.as_ref()) + } _ => false, } } @@ -427,6 +426,7 @@ where match self.kind { ShellClientKind::Xdg(ref shell) => { let user_data = shell + .as_ref() .user_data::>() .unwrap(); let mut guard = user_data.client_data.lock().unwrap(); @@ -434,10 +434,11 @@ where return Err(()); } guard.pending_ping = serial; - shell.send(xdg_wm_base::Event::Ping { serial }); + shell.ping(serial); } ShellClientKind::ZxdgV6(ref shell) => { let user_data = shell + .as_ref() .user_data::>() .unwrap(); let mut guard = user_data.client_data.lock().unwrap(); @@ -445,7 +446,7 @@ where return Err(()); } guard.pending_ping = serial; - shell.send(zxdg_shell_v6::Event::Ping { serial }); + shell.ping(serial); } } Ok(()) @@ -462,6 +463,7 @@ where match self.kind { ShellClientKind::Xdg(ref shell) => { let data = shell + .as_ref() .user_data::>() .unwrap(); let mut guard = data.client_data.lock().unwrap(); @@ -469,6 +471,7 @@ where } ShellClientKind::ZxdgV6(ref shell) => { let data = shell + .as_ref() .user_data::>() .unwrap(); let mut guard = data.client_data.lock().unwrap(); @@ -479,13 +482,13 @@ where } pub(crate) enum ToplevelKind { - Xdg(Resource), - ZxdgV6(Resource), + Xdg(xdg_toplevel::XdgToplevel), + ZxdgV6(zxdg_toplevel_v6::ZxdgToplevelV6), } /// A handle to a toplevel surface pub struct ToplevelSurface { - wl_surface: Resource, + wl_surface: wl_surface::WlSurface, shell_surface: ToplevelKind, token: CompositorToken, _shell_data: ::std::marker::PhantomData, @@ -500,15 +503,15 @@ where /// Is the toplevel surface referred by this handle still alive? pub fn alive(&self) -> bool { let shell_alive = match self.shell_surface { - ToplevelKind::Xdg(ref s) => s.is_alive(), - ToplevelKind::ZxdgV6(ref s) => s.is_alive(), + ToplevelKind::Xdg(ref s) => s.as_ref().is_alive(), + ToplevelKind::ZxdgV6(ref s) => s.as_ref().is_alive(), }; - shell_alive && self.wl_surface.is_alive() + shell_alive && self.wl_surface.as_ref().is_alive() } /// Do this handle and the other one actually refer to the same toplevel surface? pub fn equals(&self, other: &Self) -> bool { - self.alive() && other.alive() && self.wl_surface.equals(&other.wl_surface) + self.alive() && other.alive() && self.wl_surface.as_ref().equals(&other.wl_surface.as_ref()) } /// Retrieve the shell client owning this toplevel surface @@ -522,12 +525,14 @@ where let shell = match self.shell_surface { ToplevelKind::Xdg(ref s) => { let data = s + .as_ref() .user_data::>() .unwrap(); ShellClientKind::Xdg(data.wm_base.clone()) } ToplevelKind::ZxdgV6(ref s) => { let data = s + .as_ref() .user_data::>() .unwrap(); ShellClientKind::ZxdgV6(data.shell.clone()) @@ -574,18 +579,20 @@ where match self.shell_surface { ToplevelKind::Xdg(ref s) => { let data = s + .as_ref() .user_data::>() .unwrap(); - data.xdg_surface.post_error( + data.xdg_surface.as_ref().post_error( xdg_surface::Error::NotConstructed as u32, "Surface has not been configured yet.".into(), ); } ToplevelKind::ZxdgV6(ref s) => { let data = s + .as_ref() .user_data::>() .unwrap(); - data.xdg_surface.post_error( + data.xdg_surface.as_ref().post_error( zxdg_surface_v6::Error::NotConstructed as u32, "Surface has not been configured yet.".into(), ); @@ -598,15 +605,15 @@ where /// Send a "close" event to the client pub fn send_close(&self) { match self.shell_surface { - ToplevelKind::Xdg(ref s) => s.send(xdg_toplevel::Event::Close), - ToplevelKind::ZxdgV6(ref s) => s.send(zxdg_toplevel_v6::Event::Close), + ToplevelKind::Xdg(ref s) => s.close(), + ToplevelKind::ZxdgV6(ref s) => s.close(), } } /// Access the underlying `wl_surface` of this toplevel surface /// /// Returns `None` if the toplevel surface actually no longer exists. - pub fn get_surface(&self) -> Option<&Resource> { + pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> { if self.alive() { Some(&self.wl_surface) } else { @@ -632,8 +639,8 @@ where } pub(crate) enum PopupKind { - Xdg(Resource), - ZxdgV6(Resource), + Xdg(xdg_popup::XdgPopup), + ZxdgV6(zxdg_popup_v6::ZxdgPopupV6), } /// A handle to a popup surface @@ -641,7 +648,7 @@ pub(crate) enum PopupKind { /// This is an unified abstraction over the popup surfaces /// of both `wl_shell` and `xdg_shell`. pub struct PopupSurface { - wl_surface: Resource, + wl_surface: wl_surface::WlSurface, shell_surface: PopupKind, token: CompositorToken, _shell_data: ::std::marker::PhantomData, @@ -656,15 +663,15 @@ where /// Is the popup surface referred by this handle still alive? pub fn alive(&self) -> bool { let shell_alive = match self.shell_surface { - PopupKind::Xdg(ref p) => p.is_alive(), - PopupKind::ZxdgV6(ref p) => p.is_alive(), + PopupKind::Xdg(ref p) => p.as_ref().is_alive(), + PopupKind::ZxdgV6(ref p) => p.as_ref().is_alive(), }; - shell_alive && self.wl_surface.is_alive() + shell_alive && self.wl_surface.as_ref().is_alive() } /// Do this handle and the other one actually refer to the same popup surface? pub fn equals(&self, other: &Self) -> bool { - self.alive() && other.alive() && self.wl_surface.equals(&other.wl_surface) + self.alive() && other.alive() && self.wl_surface.as_ref().equals(&other.wl_surface.as_ref()) } /// Retrieve the shell client owning this popup surface @@ -678,12 +685,14 @@ where let shell = match self.shell_surface { PopupKind::Xdg(ref p) => { let data = p + .as_ref() .user_data::>() .unwrap(); ShellClientKind::Xdg(data.wm_base.clone()) } PopupKind::ZxdgV6(ref p) => { let data = p + .as_ref() .user_data::>() .unwrap(); ShellClientKind::ZxdgV6(data.shell.clone()) @@ -734,18 +743,20 @@ where match self.shell_surface { PopupKind::Xdg(ref s) => { let data = s + .as_ref() .user_data::>() .unwrap(); - data.xdg_surface.post_error( + data.xdg_surface.as_ref().post_error( xdg_surface::Error::NotConstructed as u32, "Surface has not been configured yet.".into(), ); } PopupKind::ZxdgV6(ref s) => { let data = s + .as_ref() .user_data::>() .unwrap(); - data.xdg_surface.post_error( + data.xdg_surface.as_ref().post_error( zxdg_surface_v6::Error::NotConstructed as u32, "Surface has not been configured yet.".into(), ); @@ -761,15 +772,15 @@ where /// the pointer has left the area of popup grab if there was a grab. pub fn send_popup_done(&self) { match self.shell_surface { - PopupKind::Xdg(ref p) => p.send(xdg_popup::Event::PopupDone), - PopupKind::ZxdgV6(ref p) => p.send(zxdg_popup_v6::Event::PopupDone), + PopupKind::Xdg(ref p) => p.popup_done(), + PopupKind::ZxdgV6(ref p) => p.popup_done(), } } /// Access the underlying `wl_surface` of this toplevel surface /// /// Returns `None` if the toplevel surface actually no longer exists. - pub fn get_surface(&self) -> Option<&Resource> { + pub fn get_surface(&self) -> Option<&wl_surface::WlSurface> { if self.alive() { Some(&self.wl_surface) } else { @@ -867,7 +878,7 @@ pub enum XdgRequest { /// the surface surface: ToplevelSurface, /// the seat associated to this move - seat: Resource, + seat: wl_seat::WlSeat, /// the grab serial serial: u32, }, @@ -876,7 +887,7 @@ pub enum XdgRequest { /// The surface surface: ToplevelSurface, /// The seat associated with this resize - seat: Resource, + seat: wl_seat::WlSeat, /// The grab serial serial: u32, /// Specification of which part of the window's border is being dragged @@ -890,7 +901,7 @@ pub enum XdgRequest { /// The surface surface: PopupSurface, /// The seat to grab - seat: Resource, + seat: wl_seat::WlSeat, /// The grab serial serial: u32, }, @@ -909,7 +920,7 @@ pub enum XdgRequest { /// The surface surface: ToplevelSurface, /// The output (if any) on which the fullscreen is requested - output: Option>, + output: Option, }, /// A toplevel surface request to stop being fullscreen UnFullscreen { @@ -929,7 +940,7 @@ pub enum XdgRequest { /// The surface surface: ToplevelSurface, /// The seat associated with this input grab - seat: Resource, + seat: wl_seat::WlSeat, /// the grab serial serial: u32, /// location of the menu request diff --git a/src/wayland/shell/xdg/xdg_handlers.rs b/src/wayland/shell/xdg/xdg_handlers.rs index 9fe17b4..d1d5ada 100644 --- a/src/wayland/shell/xdg/xdg_handlers.rs +++ b/src/wayland/shell/xdg/xdg_handlers.rs @@ -4,7 +4,7 @@ use crate::wayland::compositor::{roles::*, CompositorToken}; use wayland_protocols::xdg_shell::server::{ xdg_popup, xdg_positioner, xdg_surface, xdg_toplevel, xdg_wm_base, }; -use wayland_server::{protocol::wl_surface, DisplayToken, NewResource, Resource}; +use wayland_server::{protocol::wl_surface, NewResource, Resource}; use crate::utils::Rectangle; @@ -17,20 +17,19 @@ use super::{ pub(crate) fn implement_wm_base( shell: NewResource, shell_data: &ShellData, -) -> Resource +) -> xdg_wm_base::XdgWmBase where U: 'static, R: Role + 'static, SD: Default + 'static, { - let shell = shell.implement_nonsend( + let shell = shell.implement_closure( wm_implementation::, None::, ShellUserData { shell_data: shell_data.clone(), client_data: Mutex::new(make_shell_client_data::()), }, - &shell_data.display_token, ); let mut user_impl = shell_data.user_impl.borrow_mut(); (&mut *user_impl)(XdgRequest::NewClient { @@ -49,7 +48,7 @@ pub(crate) struct ShellUserData { } pub(crate) fn make_shell_client( - resource: &Resource, + resource: &xdg_wm_base::XdgWmBase, token: CompositorToken, ) -> ShellClient { ShellClient { @@ -59,19 +58,19 @@ pub(crate) fn make_shell_client( } } -fn wm_implementation(request: xdg_wm_base::Request, shell: Resource) +fn wm_implementation(request: xdg_wm_base::Request, shell: xdg_wm_base::XdgWmBase) where U: 'static, R: Role + 'static, SD: 'static, { - let data = shell.user_data::>().unwrap(); + let data = shell.as_ref().user_data::>().unwrap(); match request { xdg_wm_base::Request::Destroy => { // all is handled by destructor } xdg_wm_base::Request::CreatePositioner { id } => { - implement_positioner(id, &data.shell_data.display_token); + implement_positioner(id); } xdg_wm_base::Request::GetXdgSurface { id, surface } => { let role_data = XdgSurfaceRole { @@ -86,13 +85,13 @@ where .give_role_with(&surface, role_data) .is_err() { - shell.post_error( + shell.as_ref().post_error( xdg_wm_base::Error::Role as u32, "Surface already has a role.".into(), ); return; } - id.implement_nonsend( + id.implement_closure( xdg_surface_implementation::, Some(destroy_surface::), XdgSurfaceUserData { @@ -100,7 +99,6 @@ where wl_surface: surface, wm_base: shell.clone(), }, - &data.shell_data.display_token, ); } xdg_wm_base::Request::Pong { serial } => { @@ -120,6 +118,7 @@ where }); } } + _ => unreachable!(), } } @@ -129,11 +128,13 @@ where fn implement_positioner( positioner: NewResource, - token: &DisplayToken, -) -> Resource { - positioner.implement_nonsend( - |request, positioner: Resource<_>| { - let mutex = positioner.user_data::>().unwrap(); +) -> xdg_positioner::XdgPositioner { + positioner.implement_closure( + |request, positioner| { + let mutex = positioner + .as_ref() + .user_data::>() + .unwrap(); let mut state = mutex.borrow_mut(); match request { xdg_positioner::Request::Destroy => { @@ -141,7 +142,7 @@ fn implement_positioner( } xdg_positioner::Request::SetSize { width, height } => { if width < 1 || height < 1 { - positioner.post_error( + positioner.as_ref().post_error( xdg_positioner::Error::InvalidInput as u32, "Invalid size for positioner.".into(), ); @@ -151,7 +152,7 @@ fn implement_positioner( } xdg_positioner::Request::SetAnchorRect { x, y, width, height } => { if width < 1 || height < 1 { - positioner.post_error( + positioner.as_ref().post_error( xdg_positioner::Error::InvalidInput as u32, "Invalid size for positioner's anchor rectangle.".into(), ); @@ -175,11 +176,11 @@ fn implement_positioner( xdg_positioner::Request::SetOffset { x, y } => { state.offset = (x, y); } + _ => unreachable!(), } }, None::, RefCell::new(PositionerState::new()), - token, ) } @@ -189,18 +190,21 @@ fn implement_positioner( struct XdgSurfaceUserData { shell_data: ShellData, - wl_surface: Resource, - wm_base: Resource, + wl_surface: wl_surface::WlSurface, + wm_base: xdg_wm_base::XdgWmBase, } -fn destroy_surface(surface: Resource) +fn destroy_surface(surface: xdg_surface::XdgSurface) where U: 'static, R: Role + 'static, SD: 'static, { - let data = surface.user_data::>().unwrap(); - if !data.wl_surface.is_alive() { + let data = surface + .as_ref() + .user_data::>() + .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 // disconnecting client), ignore the protocol check. @@ -212,7 +216,7 @@ where if let XdgSurfacePendingState::None = rdata.pending_state { // all is good } else { - data.wm_base.post_error( + data.wm_base.as_ref().post_error( xdg_wm_base::Error::Role as u32, "xdg_surface was destroyed before its role object".into(), ); @@ -221,15 +225,16 @@ where .expect("xdg_surface exists but surface has not shell_surface role?!"); } -fn xdg_surface_implementation( - request: xdg_surface::Request, - xdg_surface: Resource, -) where +fn xdg_surface_implementation(request: xdg_surface::Request, xdg_surface: xdg_surface::XdgSurface) +where U: 'static, R: Role + 'static, SD: 'static, { - let data = xdg_surface.user_data::>().unwrap(); + let data = xdg_surface + .as_ref() + .user_data::>() + .unwrap(); match request { xdg_surface::Request::Destroy => { // all is handled by our destructor @@ -247,7 +252,7 @@ fn xdg_surface_implementation( }); }) .expect("xdg_surface exists but surface has not shell_surface role?!"); - let toplevel = id.implement_nonsend( + let toplevel = id.implement_closure( toplevel_implementation::, Some(destroy_toplevel::), ShellSurfaceUserData { @@ -256,7 +261,6 @@ fn xdg_surface_implementation( xdg_surface: xdg_surface.clone(), wm_base: data.wm_base.clone(), }, - &data.shell_data.display_token, ); data.shell_data @@ -275,10 +279,16 @@ fn xdg_surface_implementation( parent, positioner, } => { - let positioner_data = positioner.user_data::>().unwrap(); + let positioner_data = positioner + .as_ref() + .user_data::>() + .unwrap(); let parent_surface = parent.map(|parent| { - let parent_data = parent.user_data::>().unwrap(); + let parent_data = parent + .as_ref() + .user_data::>() + .unwrap(); parent_data.wl_surface.clone() }); data.shell_data @@ -290,7 +300,7 @@ fn xdg_surface_implementation( }); }) .expect("xdg_surface exists but surface has not shell_surface role?!"); - let popup = id.implement_nonsend( + let popup = id.implement_closure( xg_popup_implementation::, Some(destroy_popup::), ShellSurfaceUserData { @@ -299,7 +309,6 @@ fn xdg_surface_implementation( xdg_surface: xdg_surface.clone(), wm_base: data.wm_base.clone(), }, - &data.shell_data.display_token, ); data.shell_data @@ -334,7 +343,7 @@ fn xdg_surface_implementation( }); if !found { // client responded to a non-existing configure - data.wm_base.post_error( + data.wm_base.as_ref().post_error( xdg_wm_base::Error::InvalidSurfaceState as u32, format!("Wrong configure serial: {}", serial), ); @@ -343,6 +352,7 @@ fn xdg_surface_implementation( }) .expect("xdg_surface exists but surface has not shell_surface role?!"); } + _ => unreachable!(), } } @@ -352,15 +362,15 @@ fn xdg_surface_implementation( pub(crate) struct ShellSurfaceUserData { pub(crate) shell_data: ShellData, - pub(crate) wl_surface: Resource, - pub(crate) wm_base: Resource, - pub(crate) xdg_surface: Resource, + 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( shell_data: &ShellData, - toplevel: &Resource, + toplevel: &xdg_toplevel::XdgToplevel, f: F, ) where U: 'static, @@ -368,7 +378,10 @@ fn with_surface_toplevel_data( SD: 'static, F: FnOnce(&mut ToplevelState), { - let toplevel_data = toplevel.user_data::>().unwrap(); + let toplevel_data = toplevel + .as_ref() + .user_data::>() + .unwrap(); shell_data .compositor_token .with_role_data::(&toplevel_data.wl_surface, |data| match data.pending_state { @@ -378,15 +391,16 @@ fn with_surface_toplevel_data( .expect("xdg_toplevel exists but surface has not shell_surface role?!"); } -pub fn send_toplevel_configure( - resource: &Resource, - configure: ToplevelConfigure, -) where +pub fn send_toplevel_configure(resource: &xdg_toplevel::XdgToplevel, configure: ToplevelConfigure) +where U: 'static, R: Role + 'static, SD: 'static, { - let data = resource.user_data::>().unwrap(); + let data = resource + .as_ref() + .user_data::>() + .unwrap(); let (width, height) = configure.size.unwrap_or((0, 0)); // convert the Vec (which is really a Vec) into Vec let states = { @@ -398,12 +412,8 @@ pub fn send_toplevel_configure( unsafe { Vec::from_raw_parts(ptr as *mut u8, len * 4, cap * 4) } }; let serial = configure.serial; - resource.send(xdg_toplevel::Event::Configure { - width, - height, - states, - }); - data.xdg_surface.send(xdg_surface::Event::Configure { serial }); + resource.configure(width, height, states); + data.xdg_surface.configure(serial); // Add the configure as pending data.shell_data .compositor_token @@ -412,9 +422,12 @@ pub fn send_toplevel_configure( } fn make_toplevel_handle( - resource: &Resource, + resource: &xdg_toplevel::XdgToplevel, ) -> super::ToplevelSurface { - let data = resource.user_data::>().unwrap(); + let data = resource + .as_ref() + .user_data::>() + .unwrap(); super::ToplevelSurface { wl_surface: data.wl_surface.clone(), shell_surface: ToplevelKind::Xdg(resource.clone()), @@ -423,15 +436,16 @@ fn make_toplevel_handle( } } -fn toplevel_implementation( - request: xdg_toplevel::Request, - toplevel: Resource, -) where +fn toplevel_implementation(request: xdg_toplevel::Request, toplevel: xdg_toplevel::XdgToplevel) +where U: 'static, R: Role + 'static, SD: 'static, { - let data = toplevel.user_data::>().unwrap(); + let data = toplevel + .as_ref() + .user_data::>() + .unwrap(); match request { xdg_toplevel::Request::Destroy => { // all it done by the destructor @@ -440,6 +454,7 @@ fn toplevel_implementation( with_surface_toplevel_data(&data.shell_data, &toplevel, |toplevel_data| { toplevel_data.parent = parent.map(|toplevel_surface_parent| { toplevel_surface_parent + .as_ref() .user_data::>() .unwrap() .wl_surface @@ -525,17 +540,21 @@ fn toplevel_implementation( let mut user_impl = data.shell_data.user_impl.borrow_mut(); (&mut *user_impl)(XdgRequest::Minimize { surface: handle }); } + _ => unreachable!(), } } -fn destroy_toplevel(toplevel: Resource) +fn destroy_toplevel(toplevel: xdg_toplevel::XdgToplevel) where U: 'static, R: Role + 'static, SD: 'static, { - let data = toplevel.user_data::>().unwrap(); - if !data.wl_surface.is_alive() { + let data = toplevel + .as_ref() + .user_data::>() + .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 // disconnecting client), ignore the protocol check. @@ -561,20 +580,21 @@ where * xdg_popup */ -pub(crate) fn send_popup_configure( - resource: &Resource, - configure: PopupConfigure, -) where +pub(crate) fn send_popup_configure(resource: &xdg_popup::XdgPopup, configure: PopupConfigure) +where U: 'static, R: Role + 'static, SD: 'static, { - let data = resource.user_data::>().unwrap(); + let data = resource + .as_ref() + .user_data::>() + .unwrap(); let (x, y) = configure.position; let (width, height) = configure.size; let serial = configure.serial; - resource.send(xdg_popup::Event::Configure { x, y, width, height }); - data.xdg_surface.send(xdg_surface::Event::Configure { serial }); + resource.configure(x, y, width, height); + data.xdg_surface.configure(serial); // Add the configure as pending data.shell_data .compositor_token @@ -583,9 +603,12 @@ pub(crate) fn send_popup_configure( } fn make_popup_handle( - resource: &Resource, + resource: &xdg_popup::XdgPopup, ) -> super::PopupSurface { - let data = resource.user_data::>().unwrap(); + let data = resource + .as_ref() + .user_data::>() + .unwrap(); super::PopupSurface { wl_surface: data.wl_surface.clone(), shell_surface: PopupKind::Xdg(resource.clone()), @@ -594,13 +617,16 @@ fn make_popup_handle( } } -fn xg_popup_implementation(request: xdg_popup::Request, popup: Resource) +fn xg_popup_implementation(request: xdg_popup::Request, popup: xdg_popup::XdgPopup) where U: 'static, R: Role + 'static, SD: 'static, { - let data = popup.user_data::>().unwrap(); + let data = popup + .as_ref() + .user_data::>() + .unwrap(); match request { xdg_popup::Request::Destroy => { // all is handled by our destructor @@ -614,17 +640,21 @@ where serial, }); } + _ => unreachable!(), } } -fn destroy_popup(popup: Resource) +fn destroy_popup(popup: xdg_popup::XdgPopup) where U: 'static, R: Role + 'static, SD: 'static, { - let data = popup.user_data::>().unwrap(); - if !data.wl_surface.is_alive() { + let data = popup + .as_ref() + .user_data::>() + .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 // disconnecting client), ignore the protocol check. diff --git a/src/wayland/shell/xdg/zxdgv6_handlers.rs b/src/wayland/shell/xdg/zxdgv6_handlers.rs index a62f436..3812e16 100644 --- a/src/wayland/shell/xdg/zxdgv6_handlers.rs +++ b/src/wayland/shell/xdg/zxdgv6_handlers.rs @@ -7,7 +7,7 @@ use wayland_protocols::{ }, xdg_shell::server::{xdg_positioner, xdg_toplevel}, }; -use wayland_server::{protocol::wl_surface, DisplayToken, NewResource, Resource}; +use wayland_server::{protocol::wl_surface, NewResource, Resource}; use crate::utils::Rectangle; @@ -20,20 +20,19 @@ use super::{ pub(crate) fn implement_shell( shell: NewResource, shell_data: &ShellData, -) -> Resource +) -> zxdg_shell_v6::ZxdgShellV6 where U: 'static, R: Role + 'static, SD: Default + 'static, { - let shell = shell.implement_nonsend( + let shell = shell.implement_closure( shell_implementation::, None::, ShellUserData { shell_data: shell_data.clone(), client_data: Mutex::new(make_shell_client_data::()), }, - &shell_data.display_token, ); let mut user_impl = shell_data.user_impl.borrow_mut(); (&mut *user_impl)(XdgRequest::NewClient { @@ -52,7 +51,7 @@ pub(crate) struct ShellUserData { } pub(crate) fn make_shell_client( - resource: &Resource, + resource: &zxdg_shell_v6::ZxdgShellV6, token: CompositorToken, ) -> ShellClient { ShellClient { @@ -62,21 +61,19 @@ pub(crate) fn make_shell_client( } } -fn shell_implementation( - request: zxdg_shell_v6::Request, - shell: Resource, -) where +fn shell_implementation(request: zxdg_shell_v6::Request, shell: zxdg_shell_v6::ZxdgShellV6) +where U: 'static, R: Role + 'static, SD: 'static, { - let data = shell.user_data::>().unwrap(); + let data = shell.as_ref().user_data::>().unwrap(); match request { zxdg_shell_v6::Request::Destroy => { // all is handled by destructor } zxdg_shell_v6::Request::CreatePositioner { id } => { - implement_positioner(id, &data.shell_data.display_token); + implement_positioner(id); } zxdg_shell_v6::Request::GetXdgSurface { id, surface } => { let role_data = XdgSurfaceRole { @@ -91,13 +88,13 @@ fn shell_implementation( .give_role_with(&surface, role_data) .is_err() { - shell.post_error( + shell.as_ref().post_error( zxdg_shell_v6::Error::Role as u32, "Surface already has a role.".into(), ); return; } - id.implement_nonsend( + id.implement_closure( xdg_surface_implementation::, Some(destroy_surface::), XdgSurfaceUserData { @@ -105,7 +102,6 @@ fn shell_implementation( wl_surface: surface.clone(), shell: shell.clone(), }, - &data.shell_data.display_token, ); } zxdg_shell_v6::Request::Pong { serial } => { @@ -125,6 +121,7 @@ fn shell_implementation( }); } } + _ => unreachable!(), } } @@ -134,11 +131,13 @@ fn shell_implementation( fn implement_positioner( positioner: NewResource, - token: &DisplayToken, -) -> Resource { - positioner.implement_nonsend( - |request, positioner: Resource<_>| { - let mutex = positioner.user_data::>().unwrap(); +) -> zxdg_positioner_v6::ZxdgPositionerV6 { + positioner.implement_closure( + |request, positioner| { + let mutex = positioner + .as_ref() + .user_data::>() + .unwrap(); let mut state = mutex.borrow_mut(); match request { zxdg_positioner_v6::Request::Destroy => { @@ -146,7 +145,7 @@ fn implement_positioner( } zxdg_positioner_v6::Request::SetSize { width, height } => { if width < 1 || height < 1 { - positioner.post_error( + positioner.as_ref().post_error( zxdg_positioner_v6::Error::InvalidInput as u32, "Invalid size for positioner.".into(), ); @@ -156,7 +155,7 @@ fn implement_positioner( } zxdg_positioner_v6::Request::SetAnchorRect { x, y, width, height } => { if width < 1 || height < 1 { - positioner.post_error( + positioner.as_ref().post_error( zxdg_positioner_v6::Error::InvalidInput as u32, "Invalid size for positioner's anchor rectangle.".into(), ); @@ -168,7 +167,7 @@ fn implement_positioner( if let Some(anchor) = zxdg_anchor_to_xdg(anchor) { state.anchor_edges = anchor; } else { - positioner.post_error( + positioner.as_ref().post_error( zxdg_positioner_v6::Error::InvalidInput as u32, "Invalid anchor for positioner.".into(), ); @@ -178,7 +177,7 @@ fn implement_positioner( if let Some(gravity) = zxdg_gravity_to_xdg(gravity) { state.gravity = gravity; } else { - positioner.post_error( + positioner.as_ref().post_error( zxdg_positioner_v6::Error::InvalidInput as u32, "Invalid gravity for positioner.".into(), ); @@ -194,11 +193,11 @@ fn implement_positioner( zxdg_positioner_v6::Request::SetOffset { x, y } => { state.offset = (x, y); } + _ => unreachable!(), } }, None::, RefCell::new(PositionerState::new()), - token, ) } @@ -208,18 +207,21 @@ fn implement_positioner( struct XdgSurfaceUserData { shell_data: ShellData, - wl_surface: Resource, - shell: Resource, + wl_surface: wl_surface::WlSurface, + shell: zxdg_shell_v6::ZxdgShellV6, } -fn destroy_surface(surface: Resource) +fn destroy_surface(surface: zxdg_surface_v6::ZxdgSurfaceV6) where U: 'static, R: Role + 'static, SD: 'static, { - let data = surface.user_data::>().unwrap(); - if !data.wl_surface.is_alive() { + let data = surface + .as_ref() + .user_data::>() + .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 // disconnecting client), ignore the protocol check. @@ -231,7 +233,7 @@ where if let XdgSurfacePendingState::None = rdata.pending_state { // all is good } else { - data.shell.post_error( + data.shell.as_ref().post_error( zxdg_shell_v6::Error::Role as u32, "xdg_surface was destroyed before its role object".into(), ); @@ -242,13 +244,16 @@ where fn xdg_surface_implementation( request: zxdg_surface_v6::Request, - xdg_surface: Resource, + xdg_surface: zxdg_surface_v6::ZxdgSurfaceV6, ) where U: 'static, R: Role + 'static, SD: 'static, { - let data = xdg_surface.user_data::>().unwrap(); + let data = xdg_surface + .as_ref() + .user_data::>() + .unwrap(); match request { zxdg_surface_v6::Request::Destroy => { // all is handled by our destructor @@ -266,7 +271,7 @@ fn xdg_surface_implementation( }); }) .expect("xdg_surface exists but surface has not shell_surface role?!"); - let toplevel = id.implement_nonsend( + let toplevel = id.implement_closure( toplevel_implementation::, Some(destroy_toplevel::), ShellSurfaceUserData { @@ -275,7 +280,6 @@ fn xdg_surface_implementation( shell: data.shell.clone(), xdg_surface: xdg_surface.clone(), }, - &data.shell_data.display_token, ); data.shell_data @@ -294,9 +298,15 @@ fn xdg_surface_implementation( parent, positioner, } => { - let positioner_data = positioner.user_data::>().unwrap(); + let positioner_data = positioner + .as_ref() + .user_data::>() + .unwrap(); - let parent_data = parent.user_data::>().unwrap(); + let parent_data = parent + .as_ref() + .user_data::>() + .unwrap(); data.shell_data .compositor_token .with_role_data::(&data.wl_surface, |data| { @@ -306,7 +316,7 @@ fn xdg_surface_implementation( }); }) .expect("xdg_surface exists but surface has not shell_surface role?!"); - let popup = id.implement_nonsend( + let popup = id.implement_closure( popup_implementation::, Some(destroy_popup::), ShellSurfaceUserData { @@ -315,7 +325,6 @@ fn xdg_surface_implementation( shell: data.shell.clone(), xdg_surface: xdg_surface.clone(), }, - &data.shell_data.display_token, ); data.shell_data @@ -350,7 +359,7 @@ fn xdg_surface_implementation( }); if !found { // client responded to a non-existing configure - data.shell.post_error( + data.shell.as_ref().post_error( zxdg_shell_v6::Error::InvalidSurfaceState as u32, format!("Wrong configure serial: {}", serial), ); @@ -359,6 +368,7 @@ fn xdg_surface_implementation( }) .expect("xdg_surface exists but surface has not shell_surface role?!"); } + _ => unreachable!(), } } @@ -368,20 +378,23 @@ fn xdg_surface_implementation( pub struct ShellSurfaceUserData { pub(crate) shell_data: ShellData, - pub(crate) wl_surface: Resource, - pub(crate) shell: Resource, - pub(crate) xdg_surface: Resource, + 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(toplevel: &Resource, f: F) +fn with_surface_toplevel_data(toplevel: &zxdg_toplevel_v6::ZxdgToplevelV6, f: F) where U: 'static, R: Role + 'static, SD: 'static, F: FnOnce(&mut ToplevelState), { - let data = toplevel.user_data::>().unwrap(); + let data = toplevel + .as_ref() + .user_data::>() + .unwrap(); data.shell_data .compositor_token .with_role_data::(&data.wl_surface, |data| match data.pending_state { @@ -392,14 +405,17 @@ where } pub fn send_toplevel_configure( - resource: &Resource, + resource: &zxdg_toplevel_v6::ZxdgToplevelV6, configure: ToplevelConfigure, ) where U: 'static, R: Role + 'static, SD: 'static, { - let data = resource.user_data::>().unwrap(); + let data = resource + .as_ref() + .user_data::>() + .unwrap(); let (width, height) = configure.size.unwrap_or((0, 0)); // convert the Vec (which is really a Vec) into Vec let states = { @@ -411,13 +427,8 @@ pub fn send_toplevel_configure( unsafe { Vec::from_raw_parts(ptr as *mut u8, len * 4, cap * 4) } }; let serial = configure.serial; - resource.send(zxdg_toplevel_v6::Event::Configure { - width, - height, - states, - }); - data.xdg_surface - .send(zxdg_surface_v6::Event::Configure { serial }); + resource.configure(width, height, states); + data.xdg_surface.configure(serial); // Add the configure as pending data.shell_data .compositor_token @@ -426,9 +437,12 @@ pub fn send_toplevel_configure( } fn make_toplevel_handle( - resource: &Resource, + resource: &zxdg_toplevel_v6::ZxdgToplevelV6, ) -> super::ToplevelSurface { - let data = resource.user_data::>().unwrap(); + let data = resource + .as_ref() + .user_data::>() + .unwrap(); super::ToplevelSurface { wl_surface: data.wl_surface.clone(), shell_surface: ToplevelKind::ZxdgV6(resource.clone()), @@ -439,13 +453,16 @@ fn make_toplevel_handle( fn toplevel_implementation( request: zxdg_toplevel_v6::Request, - toplevel: Resource, + toplevel: zxdg_toplevel_v6::ZxdgToplevelV6, ) where U: 'static, R: Role + 'static, SD: 'static, { - let data = toplevel.user_data::>().unwrap(); + let data = toplevel + .as_ref() + .user_data::>() + .unwrap(); match request { zxdg_toplevel_v6::Request::Destroy => { // all it done by the destructor @@ -454,6 +471,7 @@ fn toplevel_implementation( with_surface_toplevel_data::(&toplevel, |toplevel_data| { toplevel_data.parent = parent.map(|toplevel_surface_parent| { let parent_data = toplevel_surface_parent + .as_ref() .user_data::>() .unwrap(); parent_data.wl_surface.clone() @@ -539,17 +557,21 @@ fn toplevel_implementation( let mut user_impl = data.shell_data.user_impl.borrow_mut(); (&mut *user_impl)(XdgRequest::Minimize { surface: handle }); } + _ => unreachable!(), } } -fn destroy_toplevel(toplevel: Resource) +fn destroy_toplevel(toplevel: zxdg_toplevel_v6::ZxdgToplevelV6) where U: 'static, R: Role + 'static, SD: 'static, { - let data = toplevel.user_data::>().unwrap(); - if !data.wl_surface.is_alive() { + let data = toplevel + .as_ref() + .user_data::>() + .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 // disconnecting client), ignore the protocol check. @@ -575,21 +597,21 @@ where * xdg_popup */ -pub(crate) fn send_popup_configure( - resource: &Resource, - configure: PopupConfigure, -) where +pub(crate) fn send_popup_configure(resource: &zxdg_popup_v6::ZxdgPopupV6, configure: PopupConfigure) +where U: 'static, R: Role + 'static, SD: 'static, { - let data = resource.user_data::>().unwrap(); + let data = resource + .as_ref() + .user_data::>() + .unwrap(); let (x, y) = configure.position; let (width, height) = configure.size; let serial = configure.serial; - resource.send(zxdg_popup_v6::Event::Configure { x, y, width, height }); - data.xdg_surface - .send(zxdg_surface_v6::Event::Configure { serial }); + resource.configure(x, y, width, height); + data.xdg_surface.configure(serial); // Add the configure as pending data.shell_data .compositor_token @@ -598,9 +620,12 @@ pub(crate) fn send_popup_configure( } fn make_popup_handle( - resource: &Resource, + resource: &zxdg_popup_v6::ZxdgPopupV6, ) -> super::PopupSurface { - let data = resource.user_data::>().unwrap(); + let data = resource + .as_ref() + .user_data::>() + .unwrap(); super::PopupSurface { wl_surface: data.wl_surface.clone(), shell_surface: PopupKind::ZxdgV6(resource.clone()), @@ -609,15 +634,16 @@ fn make_popup_handle( } } -fn popup_implementation( - request: zxdg_popup_v6::Request, - popup: Resource, -) where +fn popup_implementation(request: zxdg_popup_v6::Request, popup: zxdg_popup_v6::ZxdgPopupV6) +where U: 'static, R: Role + 'static, SD: 'static, { - let data = popup.user_data::>().unwrap(); + let data = popup + .as_ref() + .user_data::>() + .unwrap(); match request { zxdg_popup_v6::Request::Destroy => { // all is handled by our destructor @@ -631,17 +657,21 @@ fn popup_implementation( serial, }); } + _ => unreachable!(), } } -fn destroy_popup(popup: Resource) +fn destroy_popup(popup: zxdg_popup_v6::ZxdgPopupV6) where U: 'static, R: Role + 'static, SD: 'static, { - let data = popup.user_data::>().unwrap(); - if !data.wl_surface.is_alive() { + let data = popup + .as_ref() + .user_data::>() + .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 // disconnecting client), ignore the protocol check. @@ -674,6 +704,7 @@ fn zxdg_edges_to_xdg(e: zxdg_toplevel_v6::ResizeEdge) -> xdg_toplevel::ResizeEdg zxdg_toplevel_v6::ResizeEdge::TopRight => xdg_toplevel::ResizeEdge::TopRight, zxdg_toplevel_v6::ResizeEdge::BottomLeft => xdg_toplevel::ResizeEdge::BottomLeft, zxdg_toplevel_v6::ResizeEdge::BottomRight => xdg_toplevel::ResizeEdge::BottomRight, + _ => unreachable!(), } } diff --git a/src/wayland/shm/mod.rs b/src/wayland/shm/mod.rs index e0f0506..147457e 100644 --- a/src/wayland/shm/mod.rs +++ b/src/wayland/shm/mod.rs @@ -44,8 +44,7 @@ //! # extern crate wayland_server; //! # extern crate smithay; //! # use wayland_server::protocol::wl_buffer::WlBuffer; -//! # use wayland_server::Resource; -//! # fn wrap(buffer: &Resource) { +//! # fn wrap(buffer: &WlBuffer) { //! use smithay::wayland::shm::{with_buffer_contents, BufferData, BufferAccessError}; //! //! let content = with_buffer_contents(&buffer, @@ -82,7 +81,7 @@ use self::pool::{Pool, ResizeError}; use std::{rc::Rc, sync::Arc}; use wayland_server::{ protocol::{wl_buffer, wl_shm, wl_shm_pool}, - Display, DisplayToken, Global, NewResource, Resource, + Display, Global, NewResource, Resource, }; mod pool; @@ -95,7 +94,6 @@ mod pool; pub struct ShmGlobalData { formats: Rc>, log: ::slog::Logger, - token: DisplayToken, } /// Create a new SHM global advertizing given supported formats. @@ -123,22 +121,20 @@ where let data = ShmGlobalData { formats: Rc::new(formats), log: log.new(o!("smithay_module" => "shm_handler")), - token: display.get_token(), }; display.create_global::(1, move |shm_new: NewResource<_>, _version| { - let shm = shm_new.implement_nonsend( + let shm = shm_new.implement_closure( { let mut data = data.clone(); move |req, shm| data.receive_shm_message(req, shm) }, None::, (), - &data.token, ); // send the formats - for f in &data.formats[..] { - shm.send(wl_shm::Event::Format { format: *f }); + for &f in &data.formats[..] { + shm.format(f); } }) } @@ -167,14 +163,11 @@ pub enum BufferAccessError { /// /// If the buffer is not managed by the provided `ShmGlobal`, the closure is not called /// and this method will return `Err(())` (this will be the case for an EGL buffer for example). -pub fn with_buffer_contents( - buffer: &Resource, - f: F, -) -> Result +pub fn with_buffer_contents(buffer: &wl_buffer::WlBuffer, f: F) -> Result where F: FnOnce(&[u8], BufferData) -> T, { - let data = match buffer.user_data::() { + let data = match buffer.as_ref().user_data::() { Some(d) => d, None => return Err(BufferAccessError::NotManaged), }; @@ -183,19 +176,24 @@ where Ok(t) => Ok(t), Err(()) => { // SIGBUS error occurred - buffer.post_error(wl_shm::Error::InvalidFd as u32, "Bad pool size.".into()); + buffer + .as_ref() + .post_error(wl_shm::Error::InvalidFd as u32, "Bad pool size.".into()); Err(BufferAccessError::BadMap) } } } impl ShmGlobalData { - fn receive_shm_message(&mut self, request: wl_shm::Request, shm: Resource) { + fn receive_shm_message(&mut self, request: wl_shm::Request, shm: wl_shm::WlShm) { use self::wl_shm::{Error, Request}; - let Request::CreatePool { id: pool, fd, size } = request; + let (pool, fd, size) = match request { + Request::CreatePool { id: pool, fd, size } => (pool, fd, size), + _ => unreachable!(), + }; if size <= 0 { - shm.post_error( + shm.as_ref().post_error( Error::InvalidFd as u32, "Invalid size for a new wl_shm_pool.".into(), ); @@ -204,7 +202,7 @@ impl ShmGlobalData { let mmap_pool = match Pool::new(fd, size as usize, self.log.clone()) { Ok(p) => p, Err(()) => { - shm.post_error( + shm.as_ref().post_error( wl_shm::Error::InvalidFd as u32, format!("Failed mmap of fd {}.", fd), ); @@ -212,14 +210,13 @@ impl ShmGlobalData { } }; let arc_pool = Arc::new(mmap_pool); - pool.implement_nonsend( + pool.implement_closure( { let mut data = self.clone(); move |req, pool| data.receive_pool_message(req, pool) }, None::, arc_pool, - &self.token, ); } } @@ -245,14 +242,10 @@ struct InternalBufferData { } impl ShmGlobalData { - fn receive_pool_message( - &mut self, - request: wl_shm_pool::Request, - pool: Resource, - ) { + fn receive_pool_message(&mut self, request: wl_shm_pool::Request, pool: wl_shm_pool::WlShmPool) { use self::wl_shm_pool::Request; - let arc_pool = pool.user_data::>().unwrap(); + let arc_pool = pool.as_ref().user_data::>().unwrap(); match request { Request::CreateBuffer { @@ -264,7 +257,7 @@ impl ShmGlobalData { format, } => { if !self.formats.contains(&format) { - pool.post_error( + pool.as_ref().post_error( wl_shm::Error::InvalidFormat as u32, format!("SHM format {:?} is not supported.", format), ); @@ -280,29 +273,23 @@ impl ShmGlobalData { format, }, }; - buffer.implement_nonsend( - |req, _| { - // this will break if a variant is added to wl_buffer::Request - let wl_buffer::Request::Destroy = req; - }, - None::, - data, - &self.token, - ); + buffer.implement_closure(|_, _| {}, None::, data); } Request::Resize { size } => match arc_pool.resize(size) { Ok(()) => {} Err(ResizeError::InvalidSize) => { - pool.post_error( + pool.as_ref().post_error( wl_shm::Error::InvalidFd as u32, "Invalid new size for a wl_shm_pool.".into(), ); } Err(ResizeError::MremapFailed) => { - pool.post_error(wl_shm::Error::InvalidFd as u32, "mremap failed.".into()); + pool.as_ref() + .post_error(wl_shm::Error::InvalidFd as u32, "mremap failed.".into()); } }, Request::Destroy => {} + _ => unreachable!(), } } }