From d819e15e29412db193c388665d75ded91c9f73e3 Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Tue, 13 Jun 2017 16:46:31 +0200 Subject: [PATCH] compositor: Handler is now parametred by user data --- src/compositor/global.rs | 2 +- src/compositor/handlers.rs | 22 +++++++++++++--------- src/compositor/mod.rs | 23 +++++++++++++++++------ 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/compositor/global.rs b/src/compositor/global.rs index 43df315..42045ce 100644 --- a/src/compositor/global.rs +++ b/src/compositor/global.rs @@ -3,7 +3,7 @@ use super::{CompositorHandler, Handler as UserHandler}; use wayland_server::{Client, EventLoopHandle, GlobalHandler}; use wayland_server::protocol::{wl_compositor, wl_subcompositor}; -impl GlobalHandler for CompositorHandler +impl> GlobalHandler for CompositorHandler where U: Send + 'static, H: Send + 'static { diff --git a/src/compositor/handlers.rs b/src/compositor/handlers.rs index 13b218d..b9dc4bc 100644 --- a/src/compositor/handlers.rs +++ b/src/compositor/handlers.rs @@ -2,7 +2,7 @@ use super::{CompositorHandler, Damage, Handler as UserHandler, Rectangle, Rectan SubsurfaceAttributes}; use super::region::RegionData; use super::tree::{Location, SurfaceData}; -use wayland_server::{Client, Destroy, EventLoopHandle, Resource}; +use wayland_server::{Client, Destroy, EventLoopHandle, Resource, Liveness}; use wayland_server::protocol::{wl_buffer, wl_callback, wl_compositor, wl_output, wl_region, wl_subcompositor, wl_subsurface, wl_surface}; @@ -16,7 +16,7 @@ struct CompositorDestructor { impl wl_compositor::Handler for CompositorHandler where U: Default + Send + 'static, - H: UserHandler + Send + 'static + H: UserHandler + Send + 'static { fn create_surface(&mut self, evqh: &mut EventLoopHandle, _: &Client, _: &wl_compositor::WlCompositor, id: wl_surface::WlSurface) { @@ -34,7 +34,7 @@ impl wl_compositor::Handler for CompositorHandler unsafe impl ::wayland_server::Handler for CompositorHandler where U: Default + Send + 'static, - H: UserHandler + Send + 'static + H: UserHandler + Send + 'static { unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &wl_compositor::WlCompositor, opcode: u32, @@ -48,7 +48,7 @@ unsafe impl ::wayland_server::Handler for Com * wl_surface */ -impl wl_surface::Handler for CompositorHandler { +impl> wl_surface::Handler for CompositorHandler { fn attach(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, buffer: Option<&wl_buffer::WlBuffer>, x: i32, y: i32) { trace!(self.log, "Attaching buffer to surface."); @@ -74,7 +74,8 @@ impl wl_surface::Handler for CompositorHandler { fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface, callback: wl_callback::WlCallback) { trace!(self.log, "Frame surface callback."); - UserHandler::frame(&mut self.handler, evlh, client, surface, callback); + let token = self.get_token(); + UserHandler::frame(&mut self.handler, evlh, client, surface, callback, token); } fn set_opaque_region(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, region: Option<&wl_region::WlRegion>) { @@ -94,7 +95,8 @@ impl wl_surface::Handler for CompositorHandler { } fn commit(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface) { trace!(self.log, "Commit surface callback."); - UserHandler::commit(&mut self.handler, evlh, client, surface); + let token = self.get_token(); + UserHandler::commit(&mut self.handler, evlh, client, surface, token); } fn set_buffer_transform(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, transform: wl_output::Transform) { @@ -127,7 +129,7 @@ impl wl_surface::Handler for CompositorHandler { } } -unsafe impl ::wayland_server::Handler for CompositorHandler { +unsafe impl> ::wayland_server::Handler for CompositorHandler { unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, resource: &wl_surface::WlSurface, opcode: u32, args: *const ::wayland_server::sys::wl_argument) @@ -303,8 +305,10 @@ impl Destroy for CompositorDestructor { subsurface.set_user_data(::std::ptr::null_mut()); unsafe { let surface = Box::from_raw(ptr as *mut wl_surface::WlSurface); - SurfaceData::::with_data(&*surface, |d| d.subsurface_attributes = None); - SurfaceData::::unset_parent(&surface); + if surface.status() == Liveness::Alive { + SurfaceData::::with_data(&*surface, |d| d.subsurface_attributes = None); + SurfaceData::::unset_parent(&surface); + } } } } diff --git a/src/compositor/mod.rs b/src/compositor/mod.rs index 927401c..5d6539f 100644 --- a/src/compositor/mod.rs +++ b/src/compositor/mod.rs @@ -47,7 +47,7 @@ //! } //! //! // Implement the handler trait for this sub-handler -//! impl compositor::Handler for MyHandler { +//! impl compositor::Handler for MyHandler { //! // See the trait documentation for its implementation //! // A default implementation for each method is provided, that does nothing //! } @@ -259,14 +259,25 @@ impl Default for RegionAttributes { /// This token can be cloned at will, and is the entry-point to /// access data associated with the wl_surface and wl_region managed /// by the `CompositorGlobal` that provided it. -#[derive(Copy,Clone)] pub struct CompositorToken { hid: usize, _data: ::std::marker::PhantomData<*mut U>, _handler: ::std::marker::PhantomData<*mut H>, } -impl CompositorToken { +unsafe impl Send for CompositorToken {} +unsafe impl Sync for CompositorToken {} + +// we implement them manually because #[derive(..)] would require +// U: Clone and H: Clone ... +impl Copy for CompositorToken {} +impl Clone for CompositorToken { + fn clone(&self) -> CompositorToken { + *self + } +} + +impl + Send + 'static> CompositorToken { /// Access the data of a surface /// /// The closure will be called with the contents of the data associated with this surface. @@ -434,7 +445,7 @@ impl CompositorHandler { /// are forwarded directly to a handler implementing this trait that you must provide /// at creation of the `CompositorHandler`. #[allow(unused_variables)] -pub trait Handler { +pub trait Handler : Sized{ /// The double-buffered state has been validated by the client /// /// At this point, the pending state that has been accumulated in the `SurfaceAttributes` associated @@ -442,7 +453,7 @@ pub trait Handler { /// /// See [`wayland_server::protocol::wl_surface::Handler::commit`](https://docs.rs/wayland-server/*/wayland_server/protocol/wl_surface/trait.Handler.html#method.commit) /// for more details - fn commit(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface) {} + fn commit(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface, token: CompositorToken) {} /// The client asks to be notified when would be a good time to update the contents of this surface /// /// You must keep the provided `WlCallback` and trigger it at the appropriate time by calling @@ -451,6 +462,6 @@ pub trait Handler { /// See [`wayland_server::protocol::wl_surface::Handler::frame`](https://docs.rs/wayland-server/*/wayland_server/protocol/wl_surface/trait.Handler.html#method.frame) /// for more details fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface, - callback: wl_callback::WlCallback) { + callback: wl_callback::WlCallback, token: CompositorToken) { } }