compositor: Handler is now parametred by user data

This commit is contained in:
Victor Berger 2017-06-13 16:46:31 +02:00
parent afd9ca5656
commit d819e15e29
3 changed files with 31 additions and 16 deletions

View File

@ -3,7 +3,7 @@ use super::{CompositorHandler, Handler as UserHandler};
use wayland_server::{Client, EventLoopHandle, GlobalHandler}; use wayland_server::{Client, EventLoopHandle, GlobalHandler};
use wayland_server::protocol::{wl_compositor, wl_subcompositor}; use wayland_server::protocol::{wl_compositor, wl_subcompositor};
impl<U: Default, H: UserHandler> GlobalHandler<wl_compositor::WlCompositor> for CompositorHandler<U, H> impl<U: Default, H: UserHandler<U>> GlobalHandler<wl_compositor::WlCompositor> for CompositorHandler<U, H>
where U: Send + 'static, where U: Send + 'static,
H: Send + 'static H: Send + 'static
{ {

View File

@ -2,7 +2,7 @@ use super::{CompositorHandler, Damage, Handler as UserHandler, Rectangle, Rectan
SubsurfaceAttributes}; SubsurfaceAttributes};
use super::region::RegionData; use super::region::RegionData;
use super::tree::{Location, SurfaceData}; 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, use wayland_server::protocol::{wl_buffer, wl_callback, wl_compositor, wl_output, wl_region,
wl_subcompositor, wl_subsurface, wl_surface}; wl_subcompositor, wl_subsurface, wl_surface};
@ -16,7 +16,7 @@ struct CompositorDestructor<U> {
impl<U, H> wl_compositor::Handler for CompositorHandler<U, H> impl<U, H> wl_compositor::Handler for CompositorHandler<U, H>
where U: Default + Send + 'static, where U: Default + Send + 'static,
H: UserHandler + Send + 'static H: UserHandler<U> + Send + 'static
{ {
fn create_surface(&mut self, evqh: &mut EventLoopHandle, _: &Client, _: &wl_compositor::WlCompositor, fn create_surface(&mut self, evqh: &mut EventLoopHandle, _: &Client, _: &wl_compositor::WlCompositor,
id: wl_surface::WlSurface) { id: wl_surface::WlSurface) {
@ -34,7 +34,7 @@ impl<U, H> wl_compositor::Handler for CompositorHandler<U, H>
unsafe impl<U, H> ::wayland_server::Handler<wl_compositor::WlCompositor> for CompositorHandler<U, H> unsafe impl<U, H> ::wayland_server::Handler<wl_compositor::WlCompositor> for CompositorHandler<U, H>
where U: Default + Send + 'static, where U: Default + Send + 'static,
H: UserHandler + Send + 'static H: UserHandler<U> + Send + 'static
{ {
unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client,
resource: &wl_compositor::WlCompositor, opcode: u32, resource: &wl_compositor::WlCompositor, opcode: u32,
@ -48,7 +48,7 @@ unsafe impl<U, H> ::wayland_server::Handler<wl_compositor::WlCompositor> for Com
* wl_surface * wl_surface
*/ */
impl<U, H: UserHandler> wl_surface::Handler for CompositorHandler<U, H> { impl<U, H: UserHandler<U>> wl_surface::Handler for CompositorHandler<U, H> {
fn attach(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface, fn attach(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface,
buffer: Option<&wl_buffer::WlBuffer>, x: i32, y: i32) { buffer: Option<&wl_buffer::WlBuffer>, x: i32, y: i32) {
trace!(self.log, "Attaching buffer to surface."); trace!(self.log, "Attaching buffer to surface.");
@ -74,7 +74,8 @@ impl<U, H: UserHandler> wl_surface::Handler for CompositorHandler<U, H> {
fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface, fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface,
callback: wl_callback::WlCallback) { callback: wl_callback::WlCallback) {
trace!(self.log, "Frame surface callback."); 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, fn set_opaque_region(&mut self, _: &mut EventLoopHandle, _: &Client, surface: &wl_surface::WlSurface,
region: Option<&wl_region::WlRegion>) { region: Option<&wl_region::WlRegion>) {
@ -94,7 +95,8 @@ impl<U, H: UserHandler> wl_surface::Handler for CompositorHandler<U, H> {
} }
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) {
trace!(self.log, "Commit surface callback."); 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, fn set_buffer_transform(&mut self, _: &mut EventLoopHandle, _: &Client,
surface: &wl_surface::WlSurface, transform: wl_output::Transform) { surface: &wl_surface::WlSurface, transform: wl_output::Transform) {
@ -127,7 +129,7 @@ impl<U, H: UserHandler> wl_surface::Handler for CompositorHandler<U, H> {
} }
} }
unsafe impl<U, H: UserHandler> ::wayland_server::Handler<wl_surface::WlSurface> for CompositorHandler<U, H> { unsafe impl<U, H: UserHandler<U>> ::wayland_server::Handler<wl_surface::WlSurface> for CompositorHandler<U, H> {
unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client, unsafe fn message(&mut self, evq: &mut EventLoopHandle, client: &Client,
resource: &wl_surface::WlSurface, opcode: u32, resource: &wl_surface::WlSurface, opcode: u32,
args: *const ::wayland_server::sys::wl_argument) args: *const ::wayland_server::sys::wl_argument)
@ -303,8 +305,10 @@ impl<U> Destroy<wl_subsurface::WlSubsurface> for CompositorDestructor<U> {
subsurface.set_user_data(::std::ptr::null_mut()); subsurface.set_user_data(::std::ptr::null_mut());
unsafe { unsafe {
let surface = Box::from_raw(ptr as *mut wl_surface::WlSurface); let surface = Box::from_raw(ptr as *mut wl_surface::WlSurface);
SurfaceData::<U>::with_data(&*surface, |d| d.subsurface_attributes = None); if surface.status() == Liveness::Alive {
SurfaceData::<U>::unset_parent(&surface); SurfaceData::<U>::with_data(&*surface, |d| d.subsurface_attributes = None);
SurfaceData::<U>::unset_parent(&surface);
}
} }
} }
} }

View File

@ -47,7 +47,7 @@
//! } //! }
//! //!
//! // Implement the handler trait for this sub-handler //! // Implement the handler trait for this sub-handler
//! impl compositor::Handler for MyHandler { //! impl compositor::Handler<MyData> for MyHandler {
//! // See the trait documentation for its implementation //! // See the trait documentation for its implementation
//! // A default implementation for each method is provided, that does nothing //! // 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 /// This token can be cloned at will, and is the entry-point to
/// access data associated with the wl_surface and wl_region managed /// access data associated with the wl_surface and wl_region managed
/// by the `CompositorGlobal` that provided it. /// by the `CompositorGlobal` that provided it.
#[derive(Copy,Clone)]
pub struct CompositorToken<U, H> { pub struct CompositorToken<U, H> {
hid: usize, hid: usize,
_data: ::std::marker::PhantomData<*mut U>, _data: ::std::marker::PhantomData<*mut U>,
_handler: ::std::marker::PhantomData<*mut H>, _handler: ::std::marker::PhantomData<*mut H>,
} }
impl<U: Send + 'static, H: Handler + Send + 'static> CompositorToken<U, H> { unsafe impl<U: Send, H: Send> Send for CompositorToken<U, H> {}
unsafe impl<U: Send, H: Send> Sync for CompositorToken<U, H> {}
// we implement them manually because #[derive(..)] would require
// U: Clone and H: Clone ...
impl<U, H> Copy for CompositorToken<U, H> {}
impl<U, H> Clone for CompositorToken<U, H> {
fn clone(&self) -> CompositorToken<U, H> {
*self
}
}
impl<U: Send + 'static, H: Handler<U> + Send + 'static> CompositorToken<U, H> {
/// Access the data of a surface /// Access the data of a surface
/// ///
/// The closure will be called with the contents of the data associated with this surface. /// The closure will be called with the contents of the data associated with this surface.
@ -434,7 +445,7 @@ impl<U, H> CompositorHandler<U, H> {
/// are forwarded directly to a handler implementing this trait that you must provide /// are forwarded directly to a handler implementing this trait that you must provide
/// at creation of the `CompositorHandler`. /// at creation of the `CompositorHandler`.
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait Handler { pub trait Handler<U> : Sized{
/// The double-buffered state has been validated by the client /// The double-buffered state has been validated by the client
/// ///
/// At this point, the pending state that has been accumulated in the `SurfaceAttributes` associated /// 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) /// 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 /// 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<U, Self>) {}
/// The client asks to be notified when would be a good time to update the contents of this surface /// 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 /// 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) /// 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 /// for more details
fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface, fn frame(&mut self, evlh: &mut EventLoopHandle, client: &Client, surface: &wl_surface::WlSurface,
callback: wl_callback::WlCallback) { callback: wl_callback::WlCallback, token: CompositorToken<U, Self>) {
} }
} }