From ba6bef3e858a31ebab42e1922cf2ccfca3ed398c Mon Sep 17 00:00:00 2001 From: Victor Berger Date: Thu, 1 Jul 2021 22:23:13 +0200 Subject: [PATCH] wayland.shell.legacy: review docs & API --- anvil/src/shell.rs | 2 +- src/wayland/mod.rs | 5 + src/wayland/shell/legacy/mod.rs | 19 ++-- src/wayland/shell/legacy/wl_handlers.rs | 133 ++++++++++++++---------- 4 files changed, 97 insertions(+), 62 deletions(-) diff --git a/anvil/src/shell.rs b/anvil/src/shell.rs index dad6d0d..0663d31 100644 --- a/anvil/src/shell.rs +++ b/anvil/src/shell.rs @@ -642,7 +642,7 @@ pub fn init_shell(display: Rc>, log: ::sl let shell_output_map = output_map.clone(); let (wl_shell_state, _) = wl_shell_init( &mut *display.borrow_mut(), - move |req: ShellRequest| { + move |req: ShellRequest, _dispatch_data| { match req { ShellRequest::SetKind { surface, diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index ad90e24..2c613e7 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -11,6 +11,11 @@ //! `destroy()` method on the associated `Global`. If you don't plan to //! destroy the global at all, you don't need to bother keeping the //! `Global` around. +//! +//! Some of these modules require you to provide a callback that is invoked for some +//! client requests that your logic needs to handle. In most cases these callback +//! are given as input an enum specifying the event that occured, as well as the +//! [`DispatchData`](wayland_server::DispatchData) from `wayland_server`. use std::sync::atomic::{AtomicUsize, Ordering}; diff --git a/src/wayland/shell/legacy/mod.rs b/src/wayland/shell/legacy/mod.rs index 625f2b1..a87f04f 100644 --- a/src/wayland/shell/legacy/mod.rs +++ b/src/wayland/shell/legacy/mod.rs @@ -24,6 +24,8 @@ //! ### Initialization //! //! To initialize this handler, simple use the [`wl_shell_init`] function provided in this module. +//! You need to provide a closure that will be invoked whenever some action is required from you, +//! are represented by the [`ShellRequest`] enum. //! //! ```no_run //! # extern crate wayland_server; @@ -34,7 +36,7 @@ //! let (shell_state, _) = wl_shell_init( //! &mut display, //! // your implementation -//! |event: ShellRequest| { /* ... */ }, +//! |event: ShellRequest, dispatch_data| { /* handle the shell requests here */ }, //! None // put a logger if you want //! ); //! @@ -51,7 +53,7 @@ use crate::wayland::{compositor, Serial}; use wayland_server::{ protocol::{wl_output, wl_seat, wl_shell, wl_shell_surface, wl_surface}, - Display, Filter, Global, + DispatchData, Display, Filter, Global, }; use super::PingError; @@ -75,17 +77,18 @@ pub struct ShellSurface { shell_surface: wl_shell_surface::WlShellSurface, } +impl std::cmp::PartialEq for ShellSurface { + fn eq(&self, other: &Self) -> bool { + self.shell_surface == other.shell_surface + } +} + impl ShellSurface { /// Is the shell surface referred by this handle still alive? pub fn alive(&self) -> bool { 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.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. @@ -273,7 +276,7 @@ pub fn wl_shell_init( ) -> (Arc>, Global) where L: Into>, - Impl: FnMut(ShellRequest) + 'static, + Impl: FnMut(ShellRequest, DispatchData<'_>) + 'static, { let _log = crate::slog_or_fallback(logger); diff --git a/src/wayland/shell/legacy/wl_handlers.rs b/src/wayland/shell/legacy/wl_handlers.rs index f540125..b5a568e 100644 --- a/src/wayland/shell/legacy/wl_handlers.rs +++ b/src/wayland/shell/legacy/wl_handlers.rs @@ -7,7 +7,7 @@ use std::{ use wayland_server::{ protocol::{wl_shell, wl_shell_surface, wl_surface}, - Filter, Main, + DispatchData, Filter, Main, }; static WL_SHELL_SURFACE_ROLE: &str = "wl_shell_surface"; @@ -22,9 +22,9 @@ pub(crate) fn implement_shell( implementation: Rc>, state: Arc>, ) where - Impl: FnMut(ShellRequest) + 'static, + Impl: FnMut(ShellRequest, DispatchData<'_>) + 'static, { - shell.quick_assign(move |shell, req, _data| { + shell.quick_assign(move |shell, req, data| { let (id, surface) = match req { wl_shell::Request::GetShellSurface { id, surface } => (id, surface), _ => unreachable!(), @@ -52,9 +52,12 @@ pub(crate) fn implement_shell( .known_surfaces .push(make_handle(&shell_surface)); let mut imp = implementation.borrow_mut(); - (&mut *imp)(ShellRequest::NewShellSurface { - surface: make_handle(&shell_surface), - }); + (&mut *imp)( + ShellRequest::NewShellSurface { + surface: make_handle(&shell_surface), + }, + data, + ); }); } @@ -82,10 +85,10 @@ fn implement_shell_surface( state: Arc>, ) -> wl_shell_surface::WlShellSurface where - Impl: FnMut(ShellRequest) + 'static, + Impl: FnMut(ShellRequest, DispatchData<'_>) + 'static, { use self::wl_shell_surface::Request; - shell_surface.quick_assign(move |shell_surface, req, _data| { + shell_surface.quick_assign(move |shell_surface, req, dispatch_data| { let data = shell_surface .as_ref() .user_data() @@ -111,52 +114,70 @@ where }) .unwrap(); if valid { - (&mut *user_impl)(ShellRequest::Pong { - surface: make_handle(&shell_surface), - }); + (&mut *user_impl)( + ShellRequest::Pong { + surface: make_handle(&shell_surface), + }, + dispatch_data, + ); } } Request::Move { seat, serial } => { let serial = Serial::from(serial); - (&mut *user_impl)(ShellRequest::Move { - surface: make_handle(&shell_surface), - serial, - seat, - }) + (&mut *user_impl)( + ShellRequest::Move { + surface: make_handle(&shell_surface), + serial, + seat, + }, + dispatch_data, + ) } Request::Resize { seat, serial, edges } => { let serial = Serial::from(serial); - (&mut *user_impl)(ShellRequest::Resize { - surface: make_handle(&shell_surface), - serial, - seat, - edges, - }) + (&mut *user_impl)( + ShellRequest::Resize { + surface: make_handle(&shell_surface), + serial, + seat, + edges, + }, + dispatch_data, + ) } - Request::SetToplevel => (&mut *user_impl)(ShellRequest::SetKind { - surface: make_handle(&shell_surface), - kind: ShellSurfaceKind::Toplevel, - }), - Request::SetTransient { parent, x, y, flags } => (&mut *user_impl)(ShellRequest::SetKind { - surface: make_handle(&shell_surface), - kind: ShellSurfaceKind::Transient { - parent, - location: (x, y), - inactive: flags.contains(wl_shell_surface::Transient::Inactive), + Request::SetToplevel => (&mut *user_impl)( + ShellRequest::SetKind { + surface: make_handle(&shell_surface), + kind: ShellSurfaceKind::Toplevel, }, - }), + dispatch_data, + ), + Request::SetTransient { parent, x, y, flags } => (&mut *user_impl)( + ShellRequest::SetKind { + surface: make_handle(&shell_surface), + kind: ShellSurfaceKind::Transient { + parent, + location: (x, y), + inactive: flags.contains(wl_shell_surface::Transient::Inactive), + }, + }, + dispatch_data, + ), Request::SetFullscreen { method, framerate, output, - } => (&mut *user_impl)(ShellRequest::SetKind { - surface: make_handle(&shell_surface), - kind: ShellSurfaceKind::Fullscreen { - method, - framerate, - output, + } => (&mut *user_impl)( + ShellRequest::SetKind { + surface: make_handle(&shell_surface), + kind: ShellSurfaceKind::Fullscreen { + method, + framerate, + output, + }, }, - }), + dispatch_data, + ), Request::SetPopup { seat, serial, @@ -166,21 +187,27 @@ where flags, } => { let serial = Serial::from(serial); - (&mut *user_impl)(ShellRequest::SetKind { - surface: make_handle(&shell_surface), - kind: ShellSurfaceKind::Popup { - parent, - serial, - seat, - location: (x, y), - inactive: flags.contains(wl_shell_surface::Transient::Inactive), + (&mut *user_impl)( + ShellRequest::SetKind { + surface: make_handle(&shell_surface), + kind: ShellSurfaceKind::Popup { + parent, + serial, + seat, + location: (x, y), + inactive: flags.contains(wl_shell_surface::Transient::Inactive), + }, }, - }) + dispatch_data, + ) } - Request::SetMaximized { output } => (&mut *user_impl)(ShellRequest::SetKind { - surface: make_handle(&shell_surface), - kind: ShellSurfaceKind::Maximized { output }, - }), + Request::SetMaximized { output } => (&mut *user_impl)( + ShellRequest::SetKind { + surface: make_handle(&shell_surface), + kind: ShellSurfaceKind::Maximized { output }, + }, + dispatch_data, + ), Request::SetTitle { title } => { compositor::with_states(&data.surface, |states| { let mut guard = states