1 | use std::any::Any; |
2 | use std::collections::VecDeque; |
3 | use std::convert::Infallible; |
4 | use std::marker::PhantomData; |
5 | use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; |
6 | use std::sync::{atomic::Ordering, Arc, Condvar, Mutex}; |
7 | use std::task; |
8 | |
9 | use wayland_backend::{ |
10 | client::{Backend, ObjectData, ObjectId, ReadEventsGuard, WaylandError}, |
11 | protocol::{Argument, Message}, |
12 | }; |
13 | |
14 | use 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). |
95 | pub trait Dispatch<I, UserData, State = Self> |
96 | where |
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 ] |
169 | macro_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 | |
190 | type QueueCallback<State> = fn( |
191 | &Connection, |
192 | Message<ObjectId, OwnedFd>, |
193 | &mut State, |
194 | Arc<dyn ObjectData>, |
195 | &QueueHandle<State>, |
196 | ) -> Result<(), DispatchError>; |
197 | |
198 | struct QueueEvent<State>(QueueCallback<State>, Message<ObjectId, OwnedFd>, Arc<dyn ObjectData>); |
199 | |
200 | impl<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(name:"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 | /// ``` |
318 | pub struct EventQueue<State> { |
319 | handle: QueueHandle<State>, |
320 | conn: Connection, |
321 | } |
322 | |
323 | #[derive (Debug)] |
324 | pub(crate) struct EventQueueInner<State> { |
325 | queue: VecDeque<QueueEvent<State>>, |
326 | freeze_count: usize, |
327 | waker: Option<task::Waker>, |
328 | } |
329 | |
330 | impl<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: fn queue_callback(…) -> … = 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: Waker) = self.waker.take() { |
344 | waker.wake(); |
345 | } |
346 | } |
347 | } |
348 | } |
349 | |
350 | impl<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(name:"handle" , &self.handle).finish_non_exhaustive() |
354 | } |
355 | } |
356 | |
357 | impl<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 | |
364 | impl<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 | |
571 | struct DispatchWaker { |
572 | cond: Condvar, |
573 | } |
574 | |
575 | impl 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. |
582 | pub 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)] |
588 | pub struct QueueFreezeGuard<'a, State> { |
589 | qh: &'a QueueHandle<State>, |
590 | } |
591 | |
592 | impl<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(name:"inner" , &Arc::as_ptr(&self.inner)).finish() |
596 | } |
597 | } |
598 | |
599 | impl<State> Clone for QueueHandle<State> { |
600 | fn clone(&self) -> Self { |
601 | Self { inner: self.inner.clone() } |
602 | } |
603 | } |
604 | |
605 | impl<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 | |
635 | impl<State> Drop for QueueFreezeGuard<'_, State> { |
636 | fn drop(&mut self) { |
637 | let mut lock: MutexGuard<'_, EventQueueInner<…>> = 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: Waker) = lock.waker.take() { |
641 | waker.wake(); |
642 | } |
643 | } |
644 | } |
645 | } |
646 | |
647 | fn 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: I, event: ::Event) = I::parse_event(conn:handle, msg)?; |
659 | let udata: &U = odata.data_as_any().downcast_ref().expect(msg:"Wrong user_data value for object" ); |
660 | <State as Dispatch<I, U, State>>::event(state:data, &proxy, event, data:udata, conn:handle, qhandle); |
661 | Ok(()) |
662 | } |
663 | |
664 | /// The [`ObjectData`] implementation used by Wayland proxies, integrating with [`Dispatch`] |
665 | pub 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 | |
672 | impl<I: Proxy + 'static, U: Send + Sync + 'static, State> ObjectData for QueueProxyData<I, U, State> |
673 | where |
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: Option> = msgbool |
682 | .args |
683 | .iter() |
684 | .any(|arg: &Argument| 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 | |
699 | impl<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(name:"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 ] |
777 | macro_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 ] |
827 | macro_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 | } |
857 | |