diff --git a/examples/data_device.rs b/examples/data_device.rs index 154f636b9..39d7330c2 100644 --- a/examples/data_device.rs +++ b/examples/data_device.rs @@ -18,9 +18,8 @@ use smithay_client_toolkit::{ data_source::{CopyPasteSource, DataSourceHandler, DragSource}, DataDeviceManagerState, WritePipe, }, - delegate_compositor, delegate_data_device, delegate_keyboard, delegate_output, - delegate_pointer, delegate_primary_selection, delegate_registry, delegate_seat, delegate_shm, - delegate_xdg_shell, delegate_xdg_window, + delegate_compositor, delegate_data_device, delegate_keyboard, delegate_pointer, + delegate_primary_selection, delegate_registry, output::{OutputHandler, OutputState}, primary_selection::{ device::{PrimarySelectionDevice, PrimarySelectionDeviceHandler}, @@ -1082,16 +1081,10 @@ struct SeatObject { } delegate_compositor!(DataDeviceWindow); -delegate_output!(DataDeviceWindow); -delegate_shm!(DataDeviceWindow); -delegate_seat!(DataDeviceWindow); delegate_keyboard!(DataDeviceWindow); delegate_pointer!(DataDeviceWindow); -delegate_xdg_shell!(DataDeviceWindow); -delegate_xdg_window!(DataDeviceWindow); - delegate_data_device!(DataDeviceWindow); delegate_primary_selection!(DataDeviceWindow); @@ -1115,3 +1108,5 @@ fn pick_mime(mime_types: &[String]) -> Option { None } + +smithay_client_toolkit::delegate_dispatch2!(DataDeviceWindow); diff --git a/examples/generic_simple_window.rs b/examples/generic_simple_window.rs index d06a1d674..e0e47c432 100644 --- a/examples/generic_simple_window.rs +++ b/examples/generic_simple_window.rs @@ -2,8 +2,7 @@ use std::convert::TryInto; use smithay_client_toolkit::{ compositor::{CompositorHandler, CompositorState}, - delegate_compositor, delegate_keyboard, delegate_output, delegate_pointer, delegate_registry, - delegate_seat, delegate_shm, delegate_xdg_shell, delegate_xdg_window, + delegate_compositor, delegate_keyboard, delegate_pointer, delegate_registry, output::{OutputHandler, OutputState}, registry::{ProvidesRegistryState, RegistryState}, registry_handlers, @@ -477,16 +476,10 @@ impl SimpleWindow { } delegate_compositor!(@ SimpleWindow); -delegate_output!(@ SimpleWindow); -delegate_shm!(@ SimpleWindow); -delegate_seat!(@ SimpleWindow); delegate_keyboard!(@ SimpleWindow); delegate_pointer!(@ SimpleWindow); -delegate_xdg_shell!(@ SimpleWindow); -delegate_xdg_window!(@ SimpleWindow); - delegate_registry!(@ SimpleWindow); impl ProvidesRegistryState for SimpleWindow { @@ -495,3 +488,5 @@ impl ProvidesRegistryState for SimpleWindow { } registry_handlers![OutputState, SeatState,]; } + +smithay_client_toolkit::delegate_dispatch2!(@ SimpleWindow); diff --git a/examples/simple_window.rs b/examples/simple_window.rs index 97aaba556..0b0388c02 100644 --- a/examples/simple_window.rs +++ b/examples/simple_window.rs @@ -6,8 +6,8 @@ use smithay_client_toolkit::reexports::calloop_wayland_source::WaylandSource; use smithay_client_toolkit::{ activation::{ActivationHandler, ActivationState}, compositor::{CompositorHandler, CompositorState}, - delegate_activation, delegate_compositor, delegate_keyboard, delegate_output, delegate_pointer, - delegate_registry, delegate_seat, delegate_shm, delegate_xdg_shell, delegate_xdg_window, + delegate_activation, delegate_compositor, delegate_keyboard, delegate_pointer, + delegate_registry, output::{OutputHandler, OutputState}, registry::{ProvidesRegistryState, RegistryState}, registry_handlers, @@ -517,15 +517,10 @@ impl SimpleWindow { } delegate_compositor!(SimpleWindow); -delegate_output!(SimpleWindow); -delegate_shm!(SimpleWindow); -delegate_seat!(SimpleWindow); delegate_keyboard!(SimpleWindow); delegate_pointer!(SimpleWindow); -delegate_xdg_shell!(SimpleWindow); -delegate_xdg_window!(SimpleWindow); delegate_activation!(SimpleWindow); delegate_registry!(SimpleWindow); @@ -536,3 +531,5 @@ impl ProvidesRegistryState for SimpleWindow { } registry_handlers![OutputState, SeatState,]; } + +smithay_client_toolkit::delegate_dispatch2!(SimpleWindow); diff --git a/src/activation.rs b/src/activation.rs index 69914f031..9ed7f22bd 100644 --- a/src/activation.rs +++ b/src/activation.rs @@ -6,6 +6,7 @@ use wayland_client::{ use wayland_protocols::xdg::activation::v1::client::{xdg_activation_token_v1, xdg_activation_v1}; use crate::{ + dispatch2::Dispatch2, error::GlobalError, globals::{GlobalData, ProvidesBoundGlobal}, }; @@ -129,15 +130,15 @@ impl ActivationState { } } -impl Dispatch for ActivationState +impl Dispatch2 for GlobalData where - D: Dispatch + ActivationHandler, + D: ActivationHandler, { fn event( + &self, _: &mut D, _: &xdg_activation_v1::XdgActivationV1, _: ::Event, - _: &GlobalData, _: &wayland_client::Connection, _: &QueueHandle, ) { @@ -174,11 +175,6 @@ where #[macro_export] macro_rules! delegate_activation { ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: - [ - $crate::reexports::protocols::xdg::activation::v1::client::xdg_activation_v1::XdgActivationV1: $crate::globals::GlobalData - ] => $crate::activation::ActivationState - ); $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ $crate::reexports::protocols::xdg::activation::v1::client::xdg_activation_token_v1::XdgActivationTokenV1: $crate::activation::RequestData diff --git a/src/compositor.rs b/src/compositor.rs index ba0f4ad34..f3da1e73b 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -16,6 +16,7 @@ use wayland_client::{ }; use crate::{ + dispatch2::Dispatch2, error::GlobalError, globals::{GlobalData, ProvidesBoundGlobal}, output::{OutputData, OutputHandler, OutputState, ScaleWatcherHandle}, @@ -269,11 +270,6 @@ macro_rules! delegate_compositor { $crate::delegate_compositor!(@{ $(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty }; surface: [ $($surface),* ]); }; (@{$($ty:tt)*}; surface: []) => { - $crate::reexports::client::delegate_dispatch!($($ty)*: - [ - $crate::reexports::client::protocol::wl_compositor::WlCompositor: $crate::globals::GlobalData - ] => $crate::compositor::CompositorState - ); $crate::reexports::client::delegate_dispatch!($($ty)*: [ $crate::reexports::client::protocol::wl_callback::WlCallback: $crate::reexports::client::protocol::wl_surface::WlSurface @@ -481,15 +477,15 @@ impl wayland_client::backend::ObjectData for RegionData { fn destroyed(&self, _: wayland_client::backend::ObjectId) {} } -impl Dispatch for CompositorState +impl Dispatch2 for GlobalData where - D: Dispatch + CompositorHandler, + D: CompositorHandler, { fn event( + &self, _: &mut D, _: &wl_compositor::WlCompositor, _: wl_compositor::Event, - _: &GlobalData, _: &Connection, _: &QueueHandle, ) { diff --git a/src/dispatch2.rs b/src/dispatch2.rs new file mode 100644 index 000000000..0c5842fdd --- /dev/null +++ b/src/dispatch2.rs @@ -0,0 +1,47 @@ +use std::sync::Arc; +use wayland_client::backend::ObjectData; +use wayland_client::{Connection, Proxy, QueueHandle}; + +pub trait Dispatch2 { + fn event( + &self, + _: &mut State, + _: &I, + _: ::Event, + _: &Connection, + _: &QueueHandle, + ); + + fn event_created_child(opcode: u16, _qh: &QueueHandle) -> Arc { + panic!( + "Missing event_created_child specialization for event opcode {} of {}", + opcode, + I::interface().name + ); + } +} + +#[macro_export] +macro_rules! delegate_dispatch2 { + ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { + impl<$( $( $lt $( : $clt $(+ $dlt )* )? ),+, )? I, UserData> $crate::reexports::client::Dispatch for $ty + where + I: $crate::reexports::client::Proxy, + UserData: $crate::dispatch2::Dispatch2 { + fn event( + state: &mut $ty, + proxy: &I, + event: ::Event, + data: &UserData, + conn: &$crate::reexports::client::Connection, + qh: &QueueHandle<$ty>, + ) { + data.event(state, proxy, event, conn, qh); + } + + fn event_created_child(opcode: u16, qh: &$crate::reexports::client::QueueHandle<$ty>) -> ::std::sync::Arc { + UserData::event_created_child(opcode, qh) + } + } + }; +} diff --git a/src/lib.rs b/src/lib.rs index 6e345fda5..ae9bd3419 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,6 +25,7 @@ pub mod reexports { pub mod activation; pub mod compositor; pub mod data_device_manager; +pub mod dispatch2; pub mod dmabuf; pub mod error; pub mod foreign_toplevel_list; diff --git a/src/output.rs b/src/output.rs index c2dc47446..529ba55b1 100644 --- a/src/output.rs +++ b/src/output.rs @@ -16,6 +16,7 @@ use wayland_protocols::xdg::xdg_output::zv1::client::{ }; use crate::{ + dispatch2::Dispatch2, globals::GlobalData, registry::{GlobalProxy, ProvidesRegistryState, RegistryHandler}, }; @@ -391,30 +392,15 @@ pub struct OutputInfo { pub description: Option, } -#[macro_export] -macro_rules! delegate_output { - ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - $crate::reexports::client::protocol::wl_output::WlOutput: $crate::output::OutputData - ] => $crate::output::OutputState); - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - $crate::reexports::protocols::xdg::xdg_output::zv1::client::zxdg_output_manager_v1::ZxdgOutputManagerV1: $crate::globals::GlobalData - ] => $crate::output::OutputState); - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - $crate::reexports::protocols::xdg::xdg_output::zv1::client::zxdg_output_v1::ZxdgOutputV1: $crate::output::OutputData - ] => $crate::output::OutputState); - }; -} - -impl Dispatch for OutputState +impl Dispatch2 for OutputData where - D: Dispatch + OutputHandler + 'static, + D: OutputHandler + 'static, { fn event( + &self, state: &mut D, output: &wl_output::WlOutput, event: wl_output::Event, - data: &OutputData, conn: &Connection, qh: &QueueHandle, ) { @@ -519,7 +505,7 @@ where inner.pending_wl = false; // Set the user data, see if we need to run scale callbacks - let run_callbacks = data.set(info); + let run_callbacks = self.set(info); // Don't call `new_output` until we have xdg output info if !inner.pending_xdg { @@ -545,15 +531,15 @@ where } } -impl Dispatch for OutputState +impl Dispatch2 for GlobalData where - D: Dispatch + OutputHandler, + D: OutputHandler, { fn event( + &self, _: &mut D, _: &zxdg_output_manager_v1::ZxdgOutputManagerV1, _: zxdg_output_manager_v1::Event, - _: &GlobalData, _: &Connection, _: &QueueHandle, ) { @@ -561,15 +547,15 @@ where } } -impl Dispatch for OutputState +impl Dispatch2 for OutputData where - D: Dispatch + OutputHandler, + D: OutputHandler, { fn event( + &self, state: &mut D, output: &zxdg_output_v1::ZxdgOutputV1, event: zxdg_output_v1::Event, - data: &OutputData, conn: &Connection, qh: &QueueHandle, ) { @@ -631,7 +617,7 @@ where inner.pending_xdg = false; // Set the user data - data.set(info); + self.set(info); let pending_wl = inner.pending_wl; let just_created = inner.just_created; diff --git a/src/seat/mod.rs b/src/seat/mod.rs index 82764025c..f3c87ba7b 100644 --- a/src/seat/mod.rs +++ b/src/seat/mod.rs @@ -16,6 +16,7 @@ use crate::reexports::protocols::wp::cursor_shape::v1::client::wp_cursor_shape_d use crate::reexports::protocols::wp::cursor_shape::v1::client::wp_cursor_shape_manager_v1::WpCursorShapeManagerV1; use crate::{ compositor::SurfaceDataExt, + dispatch2::Dispatch2, globals::GlobalData, registry::{ProvidesRegistryState, RegistryHandler}, }; @@ -425,32 +426,21 @@ pub struct SeatData { id: u32, } -#[macro_export] -macro_rules! delegate_seat { - ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: - [ - $crate::reexports::client::protocol::wl_seat::WlSeat: $crate::seat::SeatData - ] => $crate::seat::SeatState - ); - }; -} - #[derive(Debug)] struct SeatInner { seat: wl_seat::WlSeat, data: SeatData, } -impl Dispatch for SeatState +impl Dispatch2 for SeatData where - D: Dispatch + SeatHandler, + D: SeatHandler, { fn event( + &self, state: &mut D, seat: &wl_seat::WlSeat, event: wl_seat::Event, - data: &SeatData, conn: &Connection, qh: &QueueHandle, ) { @@ -459,15 +449,15 @@ where let capabilities = wl_seat::Capability::from_bits_truncate(capabilities.into()); let keyboard = capabilities.contains(wl_seat::Capability::Keyboard); - let has_keyboard = data.has_keyboard.load(Ordering::SeqCst); + let has_keyboard = self.has_keyboard.load(Ordering::SeqCst); let pointer = capabilities.contains(wl_seat::Capability::Pointer); - let has_pointer = data.has_pointer.load(Ordering::SeqCst); + let has_pointer = self.has_pointer.load(Ordering::SeqCst); let touch = capabilities.contains(wl_seat::Capability::Touch); - let has_touch = data.has_touch.load(Ordering::SeqCst); + let has_touch = self.has_touch.load(Ordering::SeqCst); // Update capabilities as necessary if keyboard != has_keyboard { - data.has_keyboard.store(keyboard, Ordering::SeqCst); + self.has_keyboard.store(keyboard, Ordering::SeqCst); match keyboard { true => state.new_capability(conn, qh, seat.clone(), Capability::Keyboard), @@ -478,7 +468,7 @@ where } if pointer != has_pointer { - data.has_pointer.store(pointer, Ordering::SeqCst); + self.has_pointer.store(pointer, Ordering::SeqCst); match pointer { true => state.new_capability(conn, qh, seat.clone(), Capability::Pointer), @@ -489,7 +479,7 @@ where } if touch != has_touch { - data.has_touch.store(touch, Ordering::SeqCst); + self.has_touch.store(touch, Ordering::SeqCst); match touch { true => state.new_capability(conn, qh, seat.clone(), Capability::Touch), @@ -499,7 +489,7 @@ where } wl_seat::Event::Name { name } => { - *data.name.lock().unwrap() = Some(name); + *self.name.lock().unwrap() = Some(name); } _ => unreachable!(), diff --git a/src/shell/xdg/mod.rs b/src/shell/xdg/mod.rs index 0d7791d4d..65a454cb3 100644 --- a/src/shell/xdg/mod.rs +++ b/src/shell/xdg/mod.rs @@ -17,6 +17,7 @@ use crate::reexports::protocols::xdg::shell::client::{ }; use crate::compositor::Surface; +use crate::dispatch2::Dispatch2; use crate::error::GlobalError; use crate::globals::{GlobalData, ProvidesBoundGlobal}; use crate::registry::GlobalProxy; @@ -291,21 +292,6 @@ impl XdgSurface for XdgShellSurface { } } -#[macro_export] -macro_rules! delegate_xdg_shell { - ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - $crate::reexports::protocols::xdg::shell::client::xdg_wm_base::XdgWmBase: $crate::globals::GlobalData - ] => $crate::shell::xdg::XdgShell); - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - $crate::reexports::protocols::xdg::decoration::zv1::client::zxdg_decoration_manager_v1::ZxdgDecorationManagerV1: $crate::globals::GlobalData - ] => $crate::shell::xdg::XdgShell); - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - $crate::reexports::protocols::xdg::decoration::zv1::client::zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1: $crate::shell::xdg::window::WindowData - ] => $crate::shell::xdg::XdgShell); - }; -} - impl Drop for XdgShellSurface { fn drop(&mut self) { // Surface role must be destroyed before the wl_surface @@ -326,15 +312,12 @@ impl ProvidesBoundGlobal } } -impl Dispatch for XdgShell -where - D: Dispatch, -{ +impl Dispatch2 for GlobalData { fn event( + &self, _state: &mut D, xdg_wm_base: &xdg_wm_base::XdgWmBase, event: xdg_wm_base::Event, - _data: &GlobalData, _conn: &Connection, _qh: &QueueHandle, ) { diff --git a/src/shell/xdg/window/inner.rs b/src/shell/xdg/window/inner.rs index ed2f4d13f..96a276a73 100644 --- a/src/shell/xdg/window/inner.rs +++ b/src/shell/xdg/window/inner.rs @@ -4,7 +4,7 @@ use std::{ sync::Mutex, }; -use wayland_client::{Connection, Dispatch, QueueHandle}; +use wayland_client::{Connection, QueueHandle}; use wayland_protocols::{ xdg::decoration::zv1::client::{ zxdg_decoration_manager_v1, @@ -17,6 +17,7 @@ use wayland_protocols::{ }; use crate::{ + dispatch2::Dispatch2, error::GlobalError, globals::{GlobalData, ProvidesBoundGlobal}, shell::xdg::{XdgShell, XdgShellSurface}, @@ -57,15 +58,15 @@ impl ProvidesBoundGlobal } } -impl Dispatch for XdgShell +impl Dispatch2 for WindowData where - D: Dispatch + WindowHandler, + D: WindowHandler, { fn event( + &self, data: &mut D, xdg_surface: &xdg_surface::XdgSurface, event: xdg_surface::Event, - _: &WindowData, conn: &Connection, qh: &QueueHandle, ) { @@ -85,15 +86,15 @@ where } } -impl Dispatch for XdgShell +impl Dispatch2 for WindowData where - D: Dispatch + WindowHandler, + D: WindowHandler, { fn event( + &self, data: &mut D, toplevel: &xdg_toplevel::XdgToplevel, event: xdg_toplevel::Event, - _: &WindowData, conn: &Connection, qh: &QueueHandle, ) { @@ -179,15 +180,15 @@ where // XDG decoration -impl Dispatch for XdgShell +impl Dispatch2 for GlobalData where - D: Dispatch + WindowHandler, + D: WindowHandler, { fn event( + &self, _: &mut D, _: &zxdg_decoration_manager_v1::ZxdgDecorationManagerV1, _: zxdg_decoration_manager_v1::Event, - _: &GlobalData, _: &Connection, _: &QueueHandle, ) { @@ -195,15 +196,15 @@ where } } -impl Dispatch for XdgShell +impl Dispatch2 for WindowData where - D: Dispatch + WindowHandler, + D: WindowHandler, { fn event( + &self, _: &mut D, decoration: &zxdg_toplevel_decoration_v1::ZxdgToplevelDecorationV1, event: zxdg_toplevel_decoration_v1::Event, - _: &WindowData, _: &Connection, _: &QueueHandle, ) { diff --git a/src/shell/xdg/window/mod.rs b/src/shell/xdg/window/mod.rs index 31eda58b5..69527f8a9 100644 --- a/src/shell/xdg/window/mod.rs +++ b/src/shell/xdg/window/mod.rs @@ -307,15 +307,3 @@ impl PartialEq for Window { #[derive(Debug, Clone)] pub struct WindowData(pub(crate) Weak); - -#[macro_export] -macro_rules! delegate_xdg_window { - ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - $crate::reexports::protocols::xdg::shell::client::xdg_surface::XdgSurface: $crate::shell::xdg::window::WindowData - ] => $crate::shell::xdg::XdgShell); - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: [ - $crate::reexports::protocols::xdg::shell::client::xdg_toplevel::XdgToplevel: $crate::shell::xdg::window::WindowData - ] => $crate::shell::xdg::XdgShell); - }; -} diff --git a/src/shm/mod.rs b/src/shm/mod.rs index d660c306a..0a3997568 100644 --- a/src/shm/mod.rs +++ b/src/shm/mod.rs @@ -11,6 +11,7 @@ use wayland_client::{ }; use crate::{ + dispatch2::Dispatch2, error::GlobalError, globals::{GlobalData, ProvidesBoundGlobal}, }; @@ -69,49 +70,15 @@ pub enum CreatePoolError { Create(#[from] io::Error), } -/// Delegates the handling of [`wl_shm`] to some [`Shm`]. -/// -/// This macro requires two things, the type that will delegate to [`Shm`] and a closure specifying how -/// to obtain the state object. -/// -/// ``` -/// use smithay_client_toolkit::shm::{ShmHandler, Shm}; -/// use smithay_client_toolkit::delegate_shm; -/// -/// struct ExampleApp { -/// /// The state object that will be our delegate. -/// shm: Shm, -/// } -/// -/// // Use the macro to delegate wl_shm to Shm. -/// delegate_shm!(ExampleApp); -/// -/// // You must implement the ShmHandler trait to provide a way to access the Shm from your data type. -/// impl ShmHandler for ExampleApp { -/// fn shm_state(&mut self) -> &mut Shm { -/// &mut self.shm -/// } -/// } -#[macro_export] -macro_rules! delegate_shm { - ($(@<$( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+>)? $ty: ty) => { - $crate::reexports::client::delegate_dispatch!($(@< $( $lt $( : $clt $(+ $dlt )* )? ),+ >)? $ty: - [ - $crate::reexports::client::protocol::wl_shm::WlShm: $crate::globals::GlobalData - ] => $crate::shm::Shm - ); - }; -} - -impl Dispatch for Shm +impl Dispatch2 for GlobalData where - D: Dispatch + ShmHandler, + D: ShmHandler, { fn event( + &self, state: &mut D, _proxy: &wl_shm::WlShm, event: wl_shm::Event, - _: &GlobalData, _: &Connection, _: &QueueHandle, ) {