wayland_client/event_queue.rs
1use std::any::Any;
2use std::collections::VecDeque;
3use std::convert::Infallible;
4use std::marker::PhantomData;
5use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd};
6use std::sync::{Arc, Condvar, Mutex, atomic::Ordering};
7use std::task;
8
9use wayland_backend::{
10 client::{Backend, ObjectData, ObjectId, ReadEventsGuard, WaylandError},
11 protocol::{Argument, Message},
12};
13
14use crate::{Connection, DispatchError, Proxy, conn::SyncData};
15
16/// A trait for handlers of proxies' events delivered to an [`EventQueue`].
17///
18/// ## General usage
19///
20/// You need to implement this trait on your `State` for every type of Wayland object that will be processed
21/// by the [`EventQueue`] working with your `State`.
22///
23/// You can have different implementations of the trait for the same interface but different `UserData` type.
24/// This way the events for a given object will be processed by the adequate implementation depending on
25/// which `UserData` was assigned to it at creation.
26///
27/// The way this trait works is that the [`Dispatch::event()`] method will be invoked by the event queue for
28/// every event received by an object associated to this event queue. Your implementation can then match on
29/// the associated [`Proxy::Event`] enum and do any processing needed with that event.
30///
31/// In the rare case of an interface with *events* creating new objects (in the core protocol, the only
32/// instance of this is the `wl_data_device.data_offer` event), you'll need to implement the
33/// [`Dispatch::event_created_child()`] method. See the [`event_created_child!()`] macro
34/// for a simple way to do this.
35///
36/// [`event_created_child!()`]: crate::event_created_child!()
37///
38/// ## Modularity
39///
40/// To provide generic handlers for downstream usage, it is possible to make an implementation of the trait
41/// that is generic over the last type argument, as illustrated below.
42///
43/// As a result, when your implementation is instantiated, the last type parameter `State` will be the state
44/// struct of the app using your generic implementation. You can put additional trait constraints on it to
45/// specify an interface between your module and downstream code, as illustrated in this example:
46///
47/// ```
48/// use wayland_client::{protocol::wl_registry, Dispatch};
49///
50/// /// The type we want to delegate to
51/// struct DelegateToMe;
52///
53/// /// The user data relevant for your implementation.
54/// /// When providing a delegate implementation, it is recommended to use your own type here, even if it is
55/// /// just a unit struct: using () would cause a risk of clashing with another such implementation.
56/// struct MyUserData;
57///
58/// // Now a generic implementation of Dispatch, we are generic over the last type argument instead of using
59/// // the default State=Self.
60/// impl<State> Dispatch<wl_registry::WlRegistry, State> for MyUserData
61/// where
62/// // State is the type which has delegated to this type, so it needs to have an impl of Dispatch itself
63/// State: Dispatch<wl_registry::WlRegistry, MyUserData>,
64/// // If your delegate type has some internal state, it'll need to access it, and you can
65/// // require it by adding custom trait bounds.
66/// // In this example, we just require an AsMut implementation
67/// State: AsMut<DelegateToMe>,
68/// {
69/// fn event(
70/// &self,
71/// state: &mut State,
72/// _proxy: &wl_registry::WlRegistry,
73/// _event: wl_registry::Event,
74/// _conn: &wayland_client::Connection,
75/// _qhandle: &wayland_client::QueueHandle<State>,
76/// ) {
77/// // Here the delegate may handle incoming events as it pleases.
78///
79/// // For example, it retrives its state and does some processing with it
80/// let me: &mut DelegateToMe = state.as_mut();
81/// // do something with `me` ...
82/// # std::mem::drop(me) // use `me` to avoid a warning
83/// }
84/// }
85/// ```
86///
87/// **Note:** Due to limitations in Rust's trait resolution algorithm, a type providing a generic
88/// implementation of [`Dispatch`] cannot be used directly as the dispatching state, as rustc
89/// currently fails to understand that it also provides `Dispatch<I, U, Self>` (assuming all other
90/// trait bounds are respected as well).
91pub trait Dispatch<I, State>
92where
93 I: Proxy,
94{
95 /// Called when an event from the server is processed
96 ///
97 /// This method contains your logic for processing events, which can vary wildly from an object to the
98 /// other. You are given as argument:
99 ///
100 /// - a proxy representing the object that received this event
101 /// - the event itself as the [`Proxy::Event`] enum (which you'll need to match against)
102 /// - a reference to the `UserData` that was associated with that object on creation
103 /// - a reference to the [`Connection`] in case you need to access it
104 /// - a reference to a [`QueueHandle`] associated with the [`EventQueue`] currently processing events, in
105 /// case you need to create new objects that you want associated to the same [`EventQueue`].
106 fn event(
107 &self,
108 state: &mut State,
109 proxy: &I,
110 event: I::Event,
111 conn: &Connection,
112 qhandle: &QueueHandle<State>,
113 );
114
115 /// Method used to initialize the user-data of objects created by events
116 ///
117 /// If the interface does not have any such event, you can ignore it. If not, the
118 /// [`event_created_child!()`] macro is provided for overriding it.
119 ///
120 /// [`event_created_child!()`]: crate::event_created_child!()
121 #[cfg_attr(unstable_coverage, coverage(off))]
122 fn event_created_child(opcode: u16, _qhandle: &QueueHandle<State>) -> Arc<dyn ObjectData> {
123 panic!(
124 "Missing event_created_child specialization for event opcode {} of {}",
125 opcode,
126 I::interface().name
127 );
128 }
129}
130
131/// Macro used to override [`Dispatch::event_created_child()`]
132///
133/// Use this macro inside the [`Dispatch`] implementation to override this method, to implement the
134/// initialization of the user data for event-created objects. The usage syntax is as follow:
135///
136/// ```ignore
137/// impl Dispatch<WlFoo, FooUserData> for MyState {
138/// fn event(
139/// &mut self,
140/// proxy: &WlFoo,
141/// event: FooEvent,
142/// data: &FooUserData,
143/// connhandle: &mut ConnectionHandle,
144/// qhandle: &QueueHandle<MyState>
145/// ) {
146/// /* ... */
147/// }
148///
149/// event_created_child!(MyState, WlFoo, [
150/// // there can be multiple lines if this interface has multiple object-creating event
151/// EVT_CREATE_BAR => (WlBar, BarUserData::new()),
152/// // ~~~~~~~~~~~~~~ ~~~~~ ~~~~~~~~~~~~~~~~~~
153/// // | | |
154/// // | | +-- an expression whose evaluation produces the
155/// // | | user data value
156/// // | +-- the type of the newly created object
157/// // +-- the opcode of the event that creates a new object, constants for those are
158/// // generated alongside the `WlFoo` type in the `wl_foo` module
159/// ]);
160/// }
161/// ```
162#[macro_export]
163macro_rules! event_created_child {
164 // Must match `pat` to allow paths `wl_data_device::EVT_DONE_OPCODE` and expressions `0` to both work.
165 ($(@< $( $lt:tt $( : $clt:tt $(+ $dlt:tt )* )? ),+ >)? $selftype:ty, $iface:ty, [$($opcode:pat => ($child_iface:ty, $child_udata:expr_2021)),* $(,)?]) => {
166 fn event_created_child(
167 opcode: u16,
168 qhandle: &$crate::QueueHandle<$selftype>
169 ) -> std::sync::Arc<dyn $crate::backend::ObjectData> {
170 match opcode {
171 $(
172 $opcode => {
173 qhandle.make_data::<$child_iface, _>({$child_udata})
174 },
175 )*
176 _ => {
177 panic!("Missing event_created_child specialization for event opcode {} of {}", opcode, <$iface as $crate::Proxy>::interface().name);
178 },
179 }
180 }
181 };
182}
183
184type QueueCallback<State> = fn(
185 &Connection,
186 Message<ObjectId, OwnedFd>,
187 &mut State,
188 Arc<dyn ObjectData>,
189 &QueueHandle<State>,
190) -> Result<(), DispatchError>;
191
192struct QueueEvent<State>(QueueCallback<State>, Message<ObjectId, OwnedFd>, Arc<dyn ObjectData>);
193
194impl<State> std::fmt::Debug for QueueEvent<State> {
195 #[cfg_attr(unstable_coverage, coverage(off))]
196 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197 f.debug_struct("QueueEvent").field("msg", &self.1).finish_non_exhaustive()
198 }
199}
200
201/// An event queue
202///
203/// This is an abstraction for handling event dispatching, that allows you to ensure
204/// access to some common state `&mut State` to your event handlers.
205///
206/// Event queues are created through [`Connection::new_event_queue()`].
207///
208/// Upon creation, a wayland object is assigned to an event queue by passing the associated [`QueueHandle`]
209/// as argument to the method creating it. All events received by that object will be processed by that event
210/// queue, when [`dispatch_pending()`][Self::dispatch_pending()] or
211/// [`blocking_dispatch()`][Self::blocking_dispatch()] is invoked.
212///
213/// ## Usage
214///
215/// ### Single queue app
216///
217/// If your app is simple enough that the only source of event to process is the Wayland socket and you only
218/// need a single event queue, your main loop can be as simple as this:
219///
220/// ```rust,no_run
221/// use wayland_client::Connection;
222///
223/// let connection = Connection::connect_to_env().unwrap();
224/// let mut event_queue = connection.new_event_queue();
225///
226/// /*
227/// * Here your initial setup
228/// */
229/// # struct State {
230/// # exit: bool
231/// # }
232/// # let mut state = State { exit: false };
233///
234/// // And the main loop:
235/// while !state.exit {
236/// event_queue.blocking_dispatch(&mut state).unwrap();
237/// }
238/// ```
239///
240/// The [`blocking_dispatch()`][Self::blocking_dispatch()] call will wait (by putting the thread to sleep)
241/// until there are some events from the server that can be processed, and all your actual app logic can be
242/// done in the callbacks of the [`Dispatch`] implementations, and in the main `loop` after the
243/// [`blocking_dispatch()`][Self::blocking_dispatch()] call.
244///
245/// ### Multi-thread multi-queue app
246///
247/// In a case where you app is multithreaded and you want to process events in multiple thread, a simple
248/// pattern is to have one [`EventQueue`] per thread processing Wayland events.
249///
250/// With this pattern, each thread can use [`EventQueue::blocking_dispatch()`]
251/// on its own event loop, and everything will "Just Work".
252///
253/// ### Single-queue guest library
254///
255/// If your code is some library code that will act on a Wayland connection shared by the main program, it is
256/// likely you should not trigger socket reads yourself and instead let the main app take care of it. In this
257/// case, to ensure your [`EventQueue`] still makes progress, you should regularly invoke
258/// [`EventQueue::dispatch_pending()`] which will process the events that were
259/// enqueued in the inner buffer of your [`EventQueue`] by the main app reading the socket.
260///
261/// ### Integrating the event queue with other sources of events
262///
263/// If your program needs to monitor other sources of events alongside the Wayland socket using a monitoring
264/// system like `epoll`, you can integrate the Wayland socket into this system. This is done with the help
265/// of the [`EventQueue::prepare_read()`] method. You event loop will be a bit more
266/// explicit:
267///
268/// ```rust,no_run
269/// # use wayland_client::Connection;
270/// # let connection = Connection::connect_to_env().unwrap();
271/// # let mut event_queue = connection.new_event_queue();
272/// # let mut state = ();
273///
274/// loop {
275/// // flush the outgoing buffers to ensure that the server does receive the messages
276/// // you've sent
277/// event_queue.flush().unwrap();
278///
279/// // (this step is only relevant if other threads might be reading the socket as well)
280/// // make sure you don't have any pending events if the event queue that might have been
281/// // enqueued by other threads reading the socket
282/// event_queue.dispatch_pending(&mut state).unwrap();
283///
284/// // This puts in place some internal synchronization to prepare for the fact that
285/// // you're going to wait for events on the socket and read them, in case other threads
286/// // are doing the same thing
287/// let read_guard = event_queue.prepare_read().unwrap();
288///
289/// /*
290/// * At this point you can invoke epoll(..) to wait for readiness on the multiple FD you
291/// * are working with, and read_guard.connection_fd() will give you the FD to wait on for
292/// * the Wayland connection
293/// */
294/// # let wayland_socket_ready = true;
295///
296/// if wayland_socket_ready {
297/// // If epoll notified readiness of the Wayland socket, you can now proceed to the read
298/// read_guard.read().unwrap();
299/// // And now, you must invoke dispatch_pending() to actually process the events
300/// event_queue.dispatch_pending(&mut state).unwrap();
301/// } else {
302/// // otherwise, some of your other FD are ready, but you didn't receive Wayland events,
303/// // you can drop the guard to cancel the read preparation
304/// std::mem::drop(read_guard);
305/// }
306///
307/// /*
308/// * There you process all relevant events from your other event sources
309/// */
310/// }
311/// ```
312pub struct EventQueue<State> {
313 handle: QueueHandle<State>,
314 conn: Connection,
315}
316
317#[derive(Debug)]
318pub(crate) struct EventQueueInner<State> {
319 queue: VecDeque<QueueEvent<State>>,
320 freeze_count: usize,
321 waker: Option<task::Waker>,
322}
323
324impl<State> EventQueueInner<State> {
325 pub(crate) fn enqueue_event<I, U>(
326 &mut self,
327 msg: Message<ObjectId, OwnedFd>,
328 odata: Arc<dyn ObjectData>,
329 ) where
330 U: Dispatch<I, State> + Send + Sync + 'static,
331 I: Proxy,
332 {
333 let func = queue_callback::<I, U, State>;
334 self.queue.push_back(QueueEvent(func, msg, odata));
335 if self.freeze_count == 0 {
336 if let Some(waker) = self.waker.take() {
337 waker.wake();
338 }
339 }
340 }
341}
342
343impl<State> std::fmt::Debug for EventQueue<State> {
344 #[cfg_attr(unstable_coverage, coverage(off))]
345 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
346 f.debug_struct("EventQueue").field("handle", &self.handle).finish_non_exhaustive()
347 }
348}
349
350impl<State> AsFd for EventQueue<State> {
351 /// Provides fd from [`Backend::poll_fd`] for polling.
352 fn as_fd(&self) -> BorrowedFd<'_> {
353 self.conn.as_fd()
354 }
355}
356
357impl<State> EventQueue<State> {
358 pub(crate) fn new(conn: Connection) -> Self {
359 let inner = Arc::new(Mutex::new(EventQueueInner {
360 queue: VecDeque::new(),
361 freeze_count: 0,
362 waker: None,
363 }));
364 Self { handle: QueueHandle { inner }, conn }
365 }
366
367 /// Get a [`QueueHandle`] for this event queue
368 pub fn handle(&self) -> QueueHandle<State> {
369 self.handle.clone()
370 }
371
372 /// Dispatch pending events
373 ///
374 /// Events are accumulated in the event queue internal buffer when the Wayland socket is read using
375 /// the read APIs on [`Connection`], or when reading is done from an other thread.
376 /// This method will dispatch all such pending events by sequentially invoking their associated handlers:
377 /// the [`Dispatch`] implementations on the provided `&mut D`.
378 ///
379 /// Note: this may block if another thread has frozen the queue.
380 pub fn dispatch_pending(&mut self, data: &mut State) -> Result<usize, DispatchError> {
381 Self::dispatching_impl(&self.conn, &self.handle, data)
382 }
383
384 /// Block waiting for events and dispatch them
385 ///
386 /// This method is similar to [`dispatch_pending()`][Self::dispatch_pending], but if there are no
387 /// pending events it will also flush the connection and block waiting for the Wayland server to send an
388 /// event.
389 ///
390 /// A simple app event loop can consist of invoking this method in a loop.
391 pub fn blocking_dispatch(&mut self, data: &mut State) -> Result<usize, DispatchError> {
392 let dispatched = self.dispatch_pending(data)?;
393 if dispatched > 0 {
394 return Ok(dispatched);
395 }
396
397 self.conn.flush()?;
398
399 if let Some(guard) = self.conn.prepare_read() {
400 crate::conn::blocking_read(guard)?;
401 }
402
403 self.dispatch_pending(data)
404 }
405
406 /// Synchronous roundtrip
407 ///
408 /// This function will cause a synchronous round trip with the wayland server. This function will block
409 /// until all requests in the queue are sent and processed by the server.
410 ///
411 /// This function may be useful during initial setup of your app. This function may also be useful
412 /// where you need to guarantee all requests prior to calling this function are completed.
413 pub fn roundtrip(&mut self, data: &mut State) -> Result<usize, DispatchError> {
414 let done = Arc::new(SyncData::default());
415
416 let display = self.conn.display();
417 self.conn
418 .send_request(
419 &display,
420 crate::protocol::wl_display::Request::Sync {},
421 Some(done.clone()),
422 )
423 .map_err(|_| WaylandError::Io(rustix::io::Errno::PIPE.into()))?;
424
425 let mut dispatched = 0;
426
427 while !done.done.load(Ordering::Relaxed) {
428 dispatched += self.blocking_dispatch(data)?;
429 }
430
431 Ok(dispatched)
432 }
433
434 /// Start a synchronized read from the socket
435 ///
436 /// This is needed if you plan to wait on readiness of the Wayland socket using an event
437 /// loop. See the [`EventQueue`] and [`ReadEventsGuard`] docs for details. Once the events are received,
438 /// you'll then need to dispatch them from the event queue using
439 /// [`EventQueue::dispatch_pending()`].
440 ///
441 /// If this method returns [`None`], you should invoke ['dispatch_pending()`][Self::dispatch_pending]
442 /// before trying to invoke it again.
443 ///
444 /// If you don't need to manage multiple event sources, see
445 /// [`blocking_dispatch()`][Self::blocking_dispatch()] for a simpler mechanism.
446 ///
447 /// This method is identical to [`Connection::prepare_read()`].
448 #[must_use]
449 pub fn prepare_read(&self) -> Option<ReadEventsGuard> {
450 self.conn.prepare_read()
451 }
452
453 /// Flush pending outgoing events to the server
454 ///
455 /// This needs to be done regularly to ensure the server receives all your requests.
456 /// /// This method is identical to [`Connection::flush()`].
457 pub fn flush(&self) -> Result<(), WaylandError> {
458 self.conn.flush()
459 }
460
461 fn dispatching_impl(
462 backend: &Connection,
463 qhandle: &QueueHandle<State>,
464 data: &mut State,
465 ) -> Result<usize, DispatchError> {
466 // This call will most of the time do nothing, but ensure that if the Connection is in guest mode
467 // from some external connection, only invoking `EventQueue::dispatch_pending()` will be enough to
468 // process the events assuming the host program already takes care of reading the socket.
469 //
470 // We purposefully ignore the possible error, as that would make us early return in a way that might
471 // lose events, and the potential socket error will be caught in other places anyway.
472 let mut dispatched = backend.backend.dispatch_inner_queue().unwrap_or_default();
473
474 while let Some(QueueEvent(cb, msg, odata)) = Self::try_next(&qhandle.inner) {
475 cb(backend, msg, data, odata, qhandle)?;
476 dispatched += 1;
477 }
478 Ok(dispatched)
479 }
480
481 fn try_next(inner: &Mutex<EventQueueInner<State>>) -> Option<QueueEvent<State>> {
482 let mut lock = inner.lock().unwrap();
483 if lock.freeze_count != 0 && !lock.queue.is_empty() {
484 let waker = Arc::new(DispatchWaker { cond: Condvar::new() });
485 while lock.freeze_count != 0 {
486 lock.waker = Some(waker.clone().into());
487 lock = waker.cond.wait(lock).unwrap();
488 }
489 }
490 lock.queue.pop_front()
491 }
492
493 /// Attempt to dispatch events from this queue, registering the current task for wakeup if no
494 /// events are pending.
495 ///
496 /// This method is similar to [`dispatch_pending()`][Self::dispatch_pending]; it will not
497 /// perform reads on the Wayland socket. Reads on the socket by other tasks or threads will
498 /// cause the current task to wake up if events are pending on this queue.
499 ///
500 /// ```
501 /// use futures_channel::mpsc::Receiver;
502 /// use futures_util::future::{poll_fn,select};
503 /// use futures_util::stream::StreamExt;
504 /// use wayland_client::EventQueue;
505 ///
506 /// struct Data;
507 ///
508 /// enum AppEvent {
509 /// SomethingHappened(u32),
510 /// }
511 ///
512 /// impl Data {
513 /// fn handle(&mut self, event: AppEvent) {
514 /// // actual event handling goes here
515 /// }
516 /// }
517 ///
518 /// // An async task that is spawned on an executor in order to handle events that need access
519 /// // to a specific data object.
520 /// async fn run(data: &mut Data, mut wl_queue: EventQueue<Data>, mut app_queue: Receiver<AppEvent>)
521 /// -> Result<(), Box<dyn std::error::Error>>
522 /// {
523 /// use futures_util::future::Either;
524 /// loop {
525 /// match select(
526 /// poll_fn(|cx| wl_queue.poll_dispatch_pending(cx, data)),
527 /// app_queue.next(),
528 /// ).await {
529 /// Either::Left((res, _)) => match res? {},
530 /// Either::Right((Some(event), _)) => {
531 /// data.handle(event);
532 /// }
533 /// Either::Right((None, _)) => return Ok(()),
534 /// }
535 /// }
536 /// }
537 /// ```
538 pub fn poll_dispatch_pending(
539 &mut self,
540 cx: &mut task::Context,
541 data: &mut State,
542 ) -> task::Poll<Result<Infallible, DispatchError>> {
543 loop {
544 if let Err(e) = self.conn.backend.dispatch_inner_queue() {
545 return task::Poll::Ready(Err(e.into()));
546 }
547 let mut lock = self.handle.inner.lock().unwrap();
548 if lock.freeze_count != 0 {
549 lock.waker = Some(cx.waker().clone());
550 return task::Poll::Pending;
551 }
552 let QueueEvent(cb, msg, odata) = if let Some(elt) = lock.queue.pop_front() {
553 elt
554 } else {
555 lock.waker = Some(cx.waker().clone());
556 return task::Poll::Pending;
557 };
558 drop(lock);
559 cb(&self.conn, msg, data, odata, &self.handle)?
560 }
561 }
562}
563
564struct DispatchWaker {
565 cond: Condvar,
566}
567
568impl task::Wake for DispatchWaker {
569 fn wake(self: Arc<Self>) {
570 self.cond.notify_all()
571 }
572}
573
574/// A handle representing an [`EventQueue`], used to assign objects upon creation.
575pub struct QueueHandle<State> {
576 pub(crate) inner: Arc<Mutex<EventQueueInner<State>>>,
577}
578
579/// A handle that temporarily pauses event processing on an [`EventQueue`].
580#[derive(Debug)]
581pub struct QueueFreezeGuard<'a, State> {
582 qh: &'a QueueHandle<State>,
583}
584
585impl<State> std::fmt::Debug for QueueHandle<State> {
586 #[cfg_attr(unstable_coverage, coverage(off))]
587 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
588 f.debug_struct("QueueHandle").field("inner", &Arc::as_ptr(&self.inner)).finish()
589 }
590}
591
592impl<State> Clone for QueueHandle<State> {
593 fn clone(&self) -> Self {
594 Self { inner: self.inner.clone() }
595 }
596}
597
598impl<State: 'static> QueueHandle<State> {
599 /// Create an object data associated with this event queue
600 ///
601 /// This creates an implementation of [`ObjectData`] fitting for direct use with `wayland-backend` APIs
602 /// that forwards all events to the event queue associated with this token, integrating the object into
603 /// the [`Dispatch`]-based logic of `wayland-client`.
604 pub fn make_data<I: Proxy + 'static, U>(&self, user_data: U) -> Arc<dyn ObjectData>
605 where
606 U: Dispatch<I, State> + Send + Sync + 'static,
607 {
608 Arc::new(QueueProxyData::<I, U, State> {
609 handle: self.clone(),
610 udata: user_data,
611 _phantom: PhantomData,
612 })
613 }
614
615 /// Temporarily block processing on this queue.
616 ///
617 /// This will cause the associated queue to block (or return `NotReady` to poll) until all
618 /// [`QueueFreezeGuard`]s associated with the queue are dropped.
619 pub fn freeze(&self) -> QueueFreezeGuard<'_, State> {
620 self.inner.lock().unwrap().freeze_count += 1;
621 QueueFreezeGuard { qh: self }
622 }
623}
624
625impl<State> Drop for QueueFreezeGuard<'_, State> {
626 fn drop(&mut self) {
627 let mut lock = self.qh.inner.lock().unwrap();
628 lock.freeze_count -= 1;
629 if lock.freeze_count == 0 && !lock.queue.is_empty() {
630 if let Some(waker) = lock.waker.take() {
631 waker.wake();
632 }
633 }
634 }
635}
636
637fn queue_callback<I: Proxy, U: Dispatch<I, State> + Send + Sync + 'static, State>(
638 handle: &Connection,
639 msg: Message<ObjectId, OwnedFd>,
640 data: &mut State,
641 odata: Arc<dyn ObjectData>,
642 qhandle: &QueueHandle<State>,
643) -> Result<(), DispatchError> {
644 let (proxy, event) = I::parse_event(handle, msg)?;
645 let udata: &U = odata.data_as_any().downcast_ref().expect("Wrong user_data value for object");
646 udata.event(data, &proxy, event, handle, qhandle);
647 Ok(())
648}
649
650/// The [`ObjectData`] implementation used by Wayland proxies, integrating with [`Dispatch`]
651pub struct QueueProxyData<I: Proxy, U, State> {
652 handle: QueueHandle<State>,
653 /// The user data associated with this object
654 pub udata: U,
655 _phantom: PhantomData<fn(&I)>,
656}
657
658impl<I: Proxy + 'static, State: 'static, U> ObjectData for QueueProxyData<I, U, State>
659where
660 U: Dispatch<I, State> + Send + Sync + 'static,
661{
662 fn event(
663 self: Arc<Self>,
664 _: &Backend,
665 msg: Message<ObjectId, OwnedFd>,
666 ) -> Option<Arc<dyn ObjectData>> {
667 let new_data = msg
668 .args
669 .iter()
670 .any(|arg| matches!(arg, Argument::NewId(id) if !id.is_null()))
671 .then(|| U::event_created_child(msg.opcode, &self.handle));
672
673 self.handle.inner.lock().unwrap().enqueue_event::<I, U>(msg, self.clone());
674
675 new_data
676 }
677
678 fn destroyed(&self, _: ObjectId) {}
679
680 fn data_as_any(&self) -> &dyn Any {
681 &self.udata
682 }
683}
684
685impl<I: Proxy, U: std::fmt::Debug, State> std::fmt::Debug for QueueProxyData<I, U, State> {
686 #[cfg_attr(unstable_coverage, coverage(off))]
687 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
688 f.debug_struct("QueueProxyData").field("udata", &self.udata).finish()
689 }
690}
691
692/// A type that implements [`Dispatch`] for all interfaces, panicking on any event.
693#[derive(Debug)]
694pub struct Noop;
695
696impl<I: Proxy, State> Dispatch<I, State> for Noop {
697 fn event(&self, _: &mut State, _: &I, _: I::Event, _: &Connection, _: &QueueHandle<State>) {
698 unreachable!()
699 }
700}
701
702/// A type that implements [`Dispatch`] for all interfaces, ignoring any event.
703#[derive(Debug)]
704pub struct NoopIgnore;
705
706impl<I: Proxy, State> Dispatch<I, State> for NoopIgnore {
707 fn event(&self, _: &mut State, _: &I, _: I::Event, _: &Connection, _: &QueueHandle<State>) {}
708}