diff --git a/wayland-client/CHANGELOG.md b/wayland-client/CHANGELOG.md index bb408e76f8..0a1fcaafde 100644 --- a/wayland-client/CHANGELOG.md +++ b/wayland-client/CHANGELOG.md @@ -8,6 +8,10 @@ therefore allowing users to dispatch events to types different than main `State` - `delegate_dispatch` Removed in favour of `DelegateTo` generic on `QueueHandle::make_data` +#### Additions + +- `globals::registry_queue_init_delegated` and `GlobalList::bind_delegated` + ## 0.31.7 -- 2024-10-23 - Updated Wayland core protocol to 1.23 diff --git a/wayland-client/src/event_queue.rs b/wayland-client/src/event_queue.rs index b499b39c2e..fa09d31d6d 100644 --- a/wayland-client/src/event_queue.rs +++ b/wayland-client/src/event_queue.rs @@ -727,4 +727,4 @@ impl std::fmt::Debug fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("QueueProxyData").field("udata", &self.udata).finish() } -} \ No newline at end of file +} diff --git a/wayland-client/src/globals.rs b/wayland-client/src/globals.rs index 3f84f64fe0..308d07942d 100644 --- a/wayland-client/src/globals.rs +++ b/wayland-client/src/globals.rs @@ -54,6 +54,7 @@ use std::{ fmt, + marker::PhantomData, ops::RangeInclusive, os::unix::io::OwnedFd, sync::{ @@ -80,13 +81,30 @@ pub fn registry_queue_init( ) -> Result<(GlobalList, EventQueue), GlobalError> where State: Dispatch + 'static, +{ + registry_queue_init_delegated::(conn) +} + +/// Initialize a new event queue with its associated registry and retrieve the initial list of globals +/// +/// This is a delegating variant of [`registry_queue_init`], it dispatches events to `DelegateTo` +/// generic rather than to `State`. +/// +/// See [the module level documentation][self] for more. +pub fn registry_queue_init_delegated( + conn: &Connection, +) -> Result<(GlobalList, EventQueue), GlobalError> +where + State: 'static, + DelegateTo: Dispatch + 'static, { let event_queue = conn.new_event_queue(); let display = conn.display(); - let data = Arc::new(RegistryState { + let data = Arc::new(RegistryState:: { globals: GlobalListContents { contents: Default::default() }, handle: event_queue.handle(), initial_roundtrip_done: AtomicBool::new(false), + _ph: PhantomData, }); let registry = display.send_constructor(wl_display::Request::GetRegistry {}, data.clone())?; // We don't need to dispatch the event queue as for now nothing will be sent to it @@ -139,6 +157,25 @@ impl GlobalList { I: Proxy + 'static, State: Dispatch + 'static, U: Send + Sync + 'static, + { + self.bind_delegated::(qh, version, udata) + } + + /// Binds a global, returning a new protocol object associated with the global. + /// + /// This is a delegating variant of [`Self::bind`], it dispatches events to `DelegateTo` + /// generic rather than to `State`. Read full docs at [`Self::bind`]. + pub fn bind_delegated( + &self, + qh: &QueueHandle, + version: RangeInclusive, + udata: U, + ) -> Result + where + I: Proxy + 'static, + State: 'static, + U: Send + Sync + 'static, + DelegateTo: Dispatch + 'static, { let version_start = *version.start(); let version_end = *version.end(); @@ -175,7 +212,13 @@ impl GlobalList { // requested version. let version = version.min(version_end); - Ok(self.registry.bind(name, version, qh, udata)) + Ok(self + .registry + .send_constructor( + wl_registry::Request::Bind { name, id: (I::interface(), version) }, + qh.make_data::(udata), + ) + .unwrap()) } /// Returns the [`WlRegistry`][wl_registry] protocol object. @@ -293,15 +336,16 @@ impl GlobalListContents { } } -struct RegistryState { +struct RegistryState { globals: GlobalListContents, handle: QueueHandle, initial_roundtrip_done: AtomicBool, + _ph: PhantomData DelegateTo>, } -impl ObjectData for RegistryState +impl ObjectData for RegistryState where - State: Dispatch, + DelegateTo: Dispatch, { fn event( self: Arc, @@ -344,7 +388,7 @@ where .inner .lock() .unwrap() - .enqueue_event::( + .enqueue_event::( msg, self.clone(), )