Skip to main content

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