Skip to content

Commit

Permalink
Add globals::registry_queue_init_delegated and `GlobalList::bind_de…
Browse files Browse the repository at this point in the history
…legated`
  • Loading branch information
PolyMeilex committed Dec 14, 2024
1 parent d3b6104 commit f7c0076
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 7 deletions.
4 changes: 4 additions & 0 deletions wayland-client/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion wayland-client/src/event_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,4 +727,4 @@ impl<I: Proxy, U: std::fmt::Debug, State, DispatchTo> std::fmt::Debug
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("QueueProxyData").field("udata", &self.udata).finish()
}
}
}
56 changes: 50 additions & 6 deletions wayland-client/src/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
use std::{
fmt,
marker::PhantomData,
ops::RangeInclusive,
os::unix::io::OwnedFd,
sync::{
Expand All @@ -80,13 +81,30 @@ pub fn registry_queue_init<State>(
) -> Result<(GlobalList, EventQueue<State>), GlobalError>
where
State: Dispatch<wl_registry::WlRegistry, GlobalListContents> + 'static,
{
registry_queue_init_delegated::<State, State>(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<State, DelegateTo>(
conn: &Connection,
) -> Result<(GlobalList, EventQueue<State>), GlobalError>
where
State: 'static,
DelegateTo: Dispatch<wl_registry::WlRegistry, GlobalListContents, State> + 'static,
{
let event_queue = conn.new_event_queue();
let display = conn.display();
let data = Arc::new(RegistryState {
let data = Arc::new(RegistryState::<State, DelegateTo> {
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
Expand Down Expand Up @@ -139,6 +157,25 @@ impl GlobalList {
I: Proxy + 'static,
State: Dispatch<I, U> + 'static,
U: Send + Sync + 'static,
{
self.bind_delegated::<I, State, U, State>(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<I, State, U, DelegateTo>(
&self,
qh: &QueueHandle<State>,
version: RangeInclusive<u32>,
udata: U,
) -> Result<I, BindError>
where
I: Proxy + 'static,
State: 'static,
U: Send + Sync + 'static,
DelegateTo: Dispatch<I, U, State> + 'static,
{
let version_start = *version.start();
let version_end = *version.end();
Expand Down Expand Up @@ -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::<I, U, DelegateTo>(udata),
)
.unwrap())
}

/// Returns the [`WlRegistry`][wl_registry] protocol object.
Expand Down Expand Up @@ -293,15 +336,16 @@ impl GlobalListContents {
}
}

struct RegistryState<State> {
struct RegistryState<State, DelegateTo> {
globals: GlobalListContents,
handle: QueueHandle<State>,
initial_roundtrip_done: AtomicBool,
_ph: PhantomData<fn() -> DelegateTo>,
}

impl<State: 'static> ObjectData for RegistryState<State>
impl<State: 'static, DelegateTo: 'static> ObjectData for RegistryState<State, DelegateTo>
where
State: Dispatch<wl_registry::WlRegistry, GlobalListContents>,
DelegateTo: Dispatch<wl_registry::WlRegistry, GlobalListContents, State>,
{
fn event(
self: Arc<Self>,
Expand Down Expand Up @@ -344,7 +388,7 @@ where
.inner
.lock()
.unwrap()
.enqueue_event::<wl_registry::WlRegistry, GlobalListContents, State>(
.enqueue_event::<wl_registry::WlRegistry, GlobalListContents, DelegateTo>(
msg,
self.clone(),
)
Expand Down

0 comments on commit f7c0076

Please sign in to comment.