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