pub struct Queue { /* private fields */ }Expand description
An event queue.
An event queue stores events that have been sent by the compositor but whose callbacks have not yet been invoked. Invoking these callbacks is called dispatching the queue.
A connection can have many queues that can be dispatched in parallel, but the events in a single queue are always dispatched in series. That is, the callback for the next event will not start executing until after the callback for the previous event.
New queues are created by calling Connection::create_local_queue or
Connection::create_queue.
§Proxies attached to a queue
Each proxy is attached to a queue. This queue is determined as follows:
- When
Queue::displayis called, the returned proxy is attached to that queue. - When
Queue::wrap_proxyis called, the returned proxy is attached to that queue. - When a constructor request is called on an owned proxy
P, e.g.WlDisplay::sync, the returned proxy is attached to the same queue asP. - When a constructor request is called on a borrowed proxy, e.g.
WlDisplayRef::sync, the request takes a queue argument and the returned proxy is attached to that queue.
See the documentation of the proxy module for more information about proxies.
§Queue ownership
Each queue is owned by a QueueOwner which is returned when you call
Connection::create_local_queue or Connection::create_queue.
When a QueueOwner is dropped, it will automatically destroy some of the proxies
attached to the queue. This ensures that, when the QueueOwner is dropped, all
reference cycles between proxies and their event handlers are broken and no memory is
leaked. (Normally these cycles are broken when a destructor request is sent or the
proxy is destroyed with proxy::destroy, but for long-lived proxies, such as
wl_registry, it is more convenient for this to happen automatically.)
A queue and the attached proxies should no longer be used after its QueueOwner has
been dropped. Doing so might lead to panics or memory leaks.
To ensure that the QueueOwner is eventually dropped, the queue owner should never
be reachable from an event handler.
fn main() {
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue: QueueOwner = con.create_queue(c"queue name");
// the queue owner is stored on the stack and will be dropped when this function
// returns
application_logic(&queue);
}§Local and non-local queues
Each queue is either local or non-local. Local queues are created with
Connection::create_local_queue. Non-local queues are created with
Connection::create_queue.
Local queues have the following advantage:
- Event handlers attached to local queues do not have to implement
Send.
This allows such events handlers to contain Rc<T> where the same event handler on
a non-local queue would have to use Arc<T>.
To ensure that these event handlers are not accessed or dropped on different threads, this advantage comes with the following restrictions:
- If a local queue was created on a thread
X:- Event handlers must be attached on
X. - The queue must only be dispatched on
X. - The
QueueOwnerowning the queue must be dropped onX. - Proxies attached to the queue must only be destroyed on
X.- Note: Proxies are destroyed when
proxy::destroyis called or when a destructor request is sent or implicitly when the last reference to the proxy is dropped.
- Note: Proxies are destroyed when
- Event handlers must be attached on
These restrictions are checked at runtime and will lead to panics if violated.
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
// Create a local queue.
let queue = con.create_local_queue(c"queue name");
let display: WlDisplay = queue.display();
// Create an `Rc` and use it as an event handler.
let done = Rc::new(Cell::new(false));
let done2 = done.clone();
let sync = display.sync();
proxy::set_event_handler_local(&sync, WlCallback::on_done(move |_, _| done2.set(true)));
// Calling this function from another thread would panic.
queue.dispatch_roundtrip_blocking().unwrap();
assert!(done.get());§Locking
Each queue contains a re-entrant mutex. Re-entrant means that a thread that already holds the lock can acquire it again.
This lock can be acquired explicitly by calling Queue::lock_dispatch. You might
want to use this function if you’re dispatching the queue from multiple threads to
avoid lock inversion. For example, consider the following situation:
- Thread 1: Acquires the lock of some shared state.
- Thread 2: Starts dispatching and acquires the queue’s re-entrant lock.
- Thread 2: Calls an event handler which tries to lock the shared state and blocks.
- Thread 1: Destroys a proxy which will implicitly acquire the queue’s re-entrant lock. This deadlocks.
Instead, thread 1 could call Queue::lock_dispatch before locking the shared state
to prevent the lock inversion.
This deadlock concern does not apply if the queue is only ever used from a single
thread or if the queue is a local queue. If you need to poll the wayland socket on a
separate thread, you can use BorrowedQueue::wait_for_events and send a message to
the main thread when the future completes.
The lock is acquired implicitly in the following situations:
- The lock is held for the entirety of the following function calls:
- The lock is sometimes held during the following function calls but not while they are waiting for new events:
- The lock is sometimes held while the futures produced by the following functions are being polled but not while they are waiting for new events:
- The lock is held at the start and the end of the following function calls but not while invoking the callback:
- The lock is sometimes held while the futures produced by the following functions are being polled but not while polling the future passed as an argument:
- The lock is held while attaching an event handler to a proxy.
- The lock is held when a proxy with an event handler is being destroyed:
- When sending a destructor request.
- When calling
proxy::destroy. - Implicitly when dropping the last reference to a proxy.
- The lock is held while dropping the
QueueOwnerof the queue.
Implementations§
Source§impl Queue
impl Queue
Sourcepub fn dispatch_scope_blocking<'env, T, F>(&self, f: F) -> T
pub fn dispatch_scope_blocking<'env, T, F>(&self, f: F) -> T
Creates a blocking scope for event handlers with shorter than 'static lifetime.
The scope can be used to attach event handlers to proxies. The following
restriction applies: Such event handlers will only be invoked while inside this
function. Once this function returns, the OwnedProxy::NO_OP_EVENT_HANDLER of
the proxy is invoked instead.
§Panic
Panics if this is a local queue and the current thread is not the thread that this queue was created in.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_local_queue(c"queue name");
let sync = queue.display::<WlDisplay>().sync();
let done = Cell::new(false);
queue.dispatch_scope_blocking(|scope| {
scope.set_event_handler_local(&sync, WlCallback::on_done(|_, _| done.set(true)));
queue.dispatch_roundtrip_blocking().unwrap();
});
assert!(done.get());Examples found in repository?
56pub fn get_singletons(display: &WlDisplay) -> Singletons {
57 let map = Mutex::new(HashMap::new());
58
59 let queue = proxy::queue(display);
60 let wl_registry = display.get_registry();
61
62 queue.dispatch_scope_blocking(|scope| {
63 scope.set_event_handler(
64 &wl_registry,
65 WlRegistry::on_global(|_, name, interface, version| {
66 map.lock().insert(interface.to_owned(), (name, version));
67 }),
68 );
69 queue.dispatch_roundtrip_blocking().unwrap();
70 });
71
72 Singletons {
73 wl_registry,
74 map: map.into_inner(),
75 }
76}More examples
27fn get_registry_snapshot(queue: &Queue) -> (WlRegistry, Vec<Global>) {
28 // Create a new registry that will receive the globals and can later be used to
29 // bind them.
30 let registry = queue.display::<WlDisplay>().get_registry();
31 let globals = Mutex::new(vec![]);
32 // Since we don't care about registry events after this function returns, we can
33 // use a dispatch scope. The event handlers in this scope will not be called after
34 // the function returns.
35 queue.dispatch_scope_blocking(|scope| {
36 scope.set_event_handler(
37 ®istry,
38 // Since we only want to create a snapshot, we don't care about
39 // global_remove events. This allows us to use the functional event handler
40 // form.
41 WlRegistry::on_global(|_, name, interface, version| {
42 globals.lock().push(Global {
43 name,
44 interface: interface.to_string(),
45 version,
46 });
47 }),
48 );
49 queue.dispatch_roundtrip_blocking().unwrap();
50 });
51 // The event handler will no longer be called after this function returns but
52 // the registry can still be used to bind globals.
53 (registry, globals.into_inner())
54}Sourcepub async fn dispatch_scope_async<'env, T, F>(&self, f: F) -> Twhere
F: for<'scope> AsyncFnOnce(&'scope Scope<'scope, 'env>) -> T,
pub async fn dispatch_scope_async<'env, T, F>(&self, f: F) -> Twhere
F: for<'scope> AsyncFnOnce(&'scope Scope<'scope, 'env>) -> T,
Creates an async scope for event handlers with shorter than 'static lifetime.
The scope can be used to attach event handlers to proxies. The following
restriction applies: Such event handlers will only be invoked while the future is
being polled. If an event needs to be dispatched in any other situation, the
OwnedProxy::NO_OP_EVENT_HANDLER of the proxy is invoked instead.
In particular, dispatching the queue from a outside this future while this future exists is unlikely to have the desired effect.
§Panic
Panics if this is a local queue and the thread polling the future is not the thread that this queue was created in.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_local_queue(c"queue name");
let sync = queue.display::<WlDisplay>().sync();
let done = Cell::new(false);
queue.dispatch_scope_async(async |scope| {
scope.set_event_handler_local(&sync, WlCallback::on_done(|_, _| done.set(true)));
queue.dispatch_roundtrip_async().await.unwrap();
}).await;
assert!(done.get());Examples found in repository?
78pub async fn get_singletons_async(display: &WlDisplay) -> Singletons {
79 let map = Mutex::new(HashMap::new());
80
81 let queue = proxy::queue(display);
82 let wl_registry = display.get_registry();
83
84 queue
85 .dispatch_scope_async(async |scope| {
86 scope.set_event_handler(
87 &wl_registry,
88 WlRegistry::on_global(|_, name, interface, version| {
89 map.lock().insert(interface.to_owned(), (name, version));
90 }),
91 );
92 queue.dispatch_roundtrip_async().await.unwrap();
93 })
94 .await;
95
96 Singletons {
97 wl_registry,
98 map: map.into_inner(),
99 }
100}More examples
11async fn main() {
12 let lib = Libwayland::open().unwrap();
13 let con = lib.connect_to_default_display().unwrap();
14 let queue = con.create_local_queue(c"async-roundtrip");
15 let registry = queue.display::<WlDisplay>().get_registry();
16 let num_globals = Cell::new(0);
17 queue
18 .dispatch_scope_async(async |scope| {
19 scope.set_event_handler_local(
20 ®istry,
21 WlRegistry::on_global(|_, _, _, _| {
22 num_globals.set(num_globals.get() + 1);
23 }),
24 );
25 // This function can be used to perform an async roundtrip. It is
26 // compatible with any async runtime. This example also demonstrates
27 // that this works in combination with scoped event handlers.
28 queue.dispatch_roundtrip_async().await.unwrap();
29 })
30 .await;
31 println!("number of globals: {}", num_globals.get());
32}Source§impl Queue
impl Queue
Sourcepub fn libwayland(&self) -> &'static Libwayland
pub fn libwayland(&self) -> &'static Libwayland
Returns a reference to the Libwayland singleton.
Examples found in repository?
347 unsafe fn handle_event(
348 &self,
349 queue: &Queue,
350 slf: &UntypedBorrowedProxy,
351 opcode: u32,
352 args: *mut wl_argument,
353 ) {
354 // SAFETY: This function required that slf has the interface INTERFACE
355 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlDisplayRef>(slf) };
356 match opcode {
357 0 => {
358 // SAFETY: INTERFACE requires that there are 3 arguments
359 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
360 // SAFETY: - INTERFACE requires that args[0] contains an object
361 let arg0 = unsafe {
362 if let Some(p) = NonNull::new(args[0].o.cast()) {
363 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
364 } else {
365 None
366 }
367 };
368 let arg0 = arg0.as_ref();
369 // SAFETY: - INTERFACE requires that args[1] contains a uint
370 let arg1 = unsafe { args[1].u };
371 // SAFETY: - INTERFACE requires that args[2] contains a string
372 // - if the pointer is not null, then it is a c string
373 let arg2 = unsafe { convert_string_arg("wl_display", "message", args[2].s) };
374 self.0.error(slf, arg0, arg1, arg2);
375 }
376 1 => {
377 // SAFETY: INTERFACE requires that there are 1 arguments
378 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
379 // SAFETY: - INTERFACE requires that args[0] contains a uint
380 let arg0 = unsafe { args[0].u };
381 self.0.delete_id(slf, arg0);
382 }
383 _ => {
384 invalid_opcode("wl_display", opcode);
385 }
386 }
387 }More examples
968 unsafe fn handle_event(
969 &self,
970 queue: &Queue,
971 slf: &UntypedBorrowedProxy,
972 opcode: u32,
973 args: *mut wl_argument,
974 ) {
975 // SAFETY: This function required that slf has the interface INTERFACE
976 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(slf) };
977 match opcode {
978 0 => {
979 // SAFETY: INTERFACE requires that there are 1 arguments
980 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
981 // SAFETY: - INTERFACE requires that args[0] contains an object
982 let arg0 = unsafe {
983 if let Some(p) = NonNull::new(args[0].o.cast()) {
984 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
985 } else {
986 None
987 }
988 };
989 // SAFETY: - INTERFACE requires that the object has the interface WlOutput::WL_INTERFACE
990 let arg0 = arg0.as_ref().map(|arg0| unsafe {
991 proxy::low_level::from_untyped_borrowed::<WlOutputRef>(arg0)
992 });
993 self.0.enter(slf, arg0);
994 }
995 1 => {
996 // SAFETY: INTERFACE requires that there are 1 arguments
997 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
998 // SAFETY: - INTERFACE requires that args[0] contains an object
999 let arg0 = unsafe {
1000 if let Some(p) = NonNull::new(args[0].o.cast()) {
1001 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
1002 } else {
1003 None
1004 }
1005 };
1006 // SAFETY: - INTERFACE requires that the object has the interface WlOutput::WL_INTERFACE
1007 let arg0 = arg0.as_ref().map(|arg0| unsafe {
1008 proxy::low_level::from_untyped_borrowed::<WlOutputRef>(arg0)
1009 });
1010 self.0.leave(slf, arg0);
1011 }
1012 2 => {
1013 // SAFETY: INTERFACE requires that there are 1 arguments
1014 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1015 // SAFETY: - INTERFACE requires that args[0] contains an int
1016 let arg0 = unsafe { args[0].i };
1017 self.0.preferred_buffer_scale(slf, arg0);
1018 }
1019 3 => {
1020 // SAFETY: INTERFACE requires that there are 1 arguments
1021 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
1022 // SAFETY: - INTERFACE requires that args[0] contains a uint
1023 let arg0 = unsafe { WlOutputTransform(args[0].u) };
1024 self.0.preferred_buffer_transform(slf, arg0);
1025 }
1026 _ => {
1027 invalid_opcode("wl_surface", opcode);
1028 }
1029 }
1030 }419 unsafe fn handle_event(
420 &self,
421 queue: &Queue,
422 slf: &UntypedBorrowedProxy,
423 opcode: u32,
424 args: *mut wl_argument,
425 ) {
426 // SAFETY: This function required that slf has the interface INTERFACE
427 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlTouchRef>(slf) };
428 match opcode {
429 0 => {
430 // SAFETY: INTERFACE requires that there are 6 arguments
431 let args = unsafe { &*args.cast::<[wl_argument; 6]>() };
432 // SAFETY: - INTERFACE requires that args[0] contains a uint
433 let arg0 = unsafe { args[0].u };
434 // SAFETY: - INTERFACE requires that args[1] contains a uint
435 let arg1 = unsafe { args[1].u };
436 // SAFETY: - INTERFACE requires that args[2] contains an object
437 let arg2 = unsafe {
438 if let Some(p) = NonNull::new(args[2].o.cast()) {
439 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
440 } else {
441 None
442 }
443 };
444 // SAFETY: - INTERFACE requires that the object has the interface WlSurface::WL_INTERFACE
445 let arg2 = arg2.as_ref().map(|arg2| unsafe {
446 proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(arg2)
447 });
448 // SAFETY: - INTERFACE requires that args[3] contains an int
449 let arg3 = unsafe { args[3].i };
450 // SAFETY: - INTERFACE requires that args[4] contains a fixed
451 let arg4 = unsafe { Fixed::from_wire(args[4].f) };
452 // SAFETY: - INTERFACE requires that args[5] contains a fixed
453 let arg5 = unsafe { Fixed::from_wire(args[5].f) };
454 self.0.down(slf, arg0, arg1, arg2, arg3, arg4, arg5);
455 }
456 1 => {
457 // SAFETY: INTERFACE requires that there are 3 arguments
458 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
459 // SAFETY: - INTERFACE requires that args[0] contains a uint
460 let arg0 = unsafe { args[0].u };
461 // SAFETY: - INTERFACE requires that args[1] contains a uint
462 let arg1 = unsafe { args[1].u };
463 // SAFETY: - INTERFACE requires that args[2] contains an int
464 let arg2 = unsafe { args[2].i };
465 self.0.up(slf, arg0, arg1, arg2);
466 }
467 2 => {
468 // SAFETY: INTERFACE requires that there are 4 arguments
469 let args = unsafe { &*args.cast::<[wl_argument; 4]>() };
470 // SAFETY: - INTERFACE requires that args[0] contains a uint
471 let arg0 = unsafe { args[0].u };
472 // SAFETY: - INTERFACE requires that args[1] contains an int
473 let arg1 = unsafe { args[1].i };
474 // SAFETY: - INTERFACE requires that args[2] contains a fixed
475 let arg2 = unsafe { Fixed::from_wire(args[2].f) };
476 // SAFETY: - INTERFACE requires that args[3] contains a fixed
477 let arg3 = unsafe { Fixed::from_wire(args[3].f) };
478 self.0.motion(slf, arg0, arg1, arg2, arg3);
479 }
480 3 => {
481 self.0.frame(slf);
482 }
483 4 => {
484 self.0.cancel(slf);
485 }
486 5 => {
487 // SAFETY: INTERFACE requires that there are 3 arguments
488 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
489 // SAFETY: - INTERFACE requires that args[0] contains an int
490 let arg0 = unsafe { args[0].i };
491 // SAFETY: - INTERFACE requires that args[1] contains a fixed
492 let arg1 = unsafe { Fixed::from_wire(args[1].f) };
493 // SAFETY: - INTERFACE requires that args[2] contains a fixed
494 let arg2 = unsafe { Fixed::from_wire(args[2].f) };
495 self.0.shape(slf, arg0, arg1, arg2);
496 }
497 6 => {
498 // SAFETY: INTERFACE requires that there are 2 arguments
499 let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
500 // SAFETY: - INTERFACE requires that args[0] contains an int
501 let arg0 = unsafe { args[0].i };
502 // SAFETY: - INTERFACE requires that args[1] contains a fixed
503 let arg1 = unsafe { Fixed::from_wire(args[1].f) };
504 self.0.orientation(slf, arg0, arg1);
505 }
506 _ => {
507 invalid_opcode("wl_touch", opcode);
508 }
509 }
510 }490 unsafe fn handle_event(
491 &self,
492 queue: &Queue,
493 slf: &UntypedBorrowedProxy,
494 opcode: u32,
495 args: *mut wl_argument,
496 ) {
497 // SAFETY: This function required that slf has the interface INTERFACE
498 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlDataDeviceRef>(slf) };
499 match opcode {
500 0 => {
501 // SAFETY: INTERFACE requires that there are 1 arguments
502 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
503 // SAFETY: - INTERFACE requires that args[0] contains an object
504 // - ownership is transferred to this function
505 // - INTERFACE requires that the object has the interface WlDataOffer::WL_INTERFACE
506 let arg0 = unsafe {
507 UntypedOwnedProxy::from_plain_wl_proxy(
508 queue,
509 NonNull::new_unchecked(args[0].o.cast()),
510 WlDataOffer::WL_INTERFACE,
511 )
512 };
513 // SAFETY: - INTERFACE requires that the object has the interface WlDataOffer::WL_INTERFACE
514 let arg0 = unsafe { proxy::low_level::from_untyped_owned::<WlDataOffer>(arg0) };
515 self.0.data_offer(slf, arg0);
516 }
517 1 => {
518 // SAFETY: INTERFACE requires that there are 5 arguments
519 let args = unsafe { &*args.cast::<[wl_argument; 5]>() };
520 // SAFETY: - INTERFACE requires that args[0] contains a uint
521 let arg0 = unsafe { args[0].u };
522 // SAFETY: - INTERFACE requires that args[1] contains an object
523 let arg1 = unsafe {
524 if let Some(p) = NonNull::new(args[1].o.cast()) {
525 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
526 } else {
527 None
528 }
529 };
530 // SAFETY: - INTERFACE requires that the object has the interface WlSurface::WL_INTERFACE
531 let arg1 = arg1.as_ref().map(|arg1| unsafe {
532 proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(arg1)
533 });
534 // SAFETY: - INTERFACE requires that args[2] contains a fixed
535 let arg2 = unsafe { Fixed::from_wire(args[2].f) };
536 // SAFETY: - INTERFACE requires that args[3] contains a fixed
537 let arg3 = unsafe { Fixed::from_wire(args[3].f) };
538 // SAFETY: - INTERFACE requires that args[4] contains an object
539 let arg4 = unsafe {
540 if let Some(p) = NonNull::new(args[4].o.cast()) {
541 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
542 } else {
543 None
544 }
545 };
546 // SAFETY: - INTERFACE requires that the object has the interface WlDataOffer::WL_INTERFACE
547 let arg4 = arg4.as_ref().map(|arg4| unsafe {
548 proxy::low_level::from_untyped_borrowed::<WlDataOfferRef>(arg4)
549 });
550 self.0.enter(slf, arg0, arg1, arg2, arg3, arg4);
551 }
552 2 => {
553 self.0.leave(slf);
554 }
555 3 => {
556 // SAFETY: INTERFACE requires that there are 3 arguments
557 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
558 // SAFETY: - INTERFACE requires that args[0] contains a uint
559 let arg0 = unsafe { args[0].u };
560 // SAFETY: - INTERFACE requires that args[1] contains a fixed
561 let arg1 = unsafe { Fixed::from_wire(args[1].f) };
562 // SAFETY: - INTERFACE requires that args[2] contains a fixed
563 let arg2 = unsafe { Fixed::from_wire(args[2].f) };
564 self.0.motion(slf, arg0, arg1, arg2);
565 }
566 4 => {
567 self.0.drop(slf);
568 }
569 5 => {
570 // SAFETY: INTERFACE requires that there are 1 arguments
571 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
572 // SAFETY: - INTERFACE requires that args[0] contains an object
573 let arg0 = unsafe {
574 if let Some(p) = NonNull::new(args[0].o.cast()) {
575 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
576 } else {
577 None
578 }
579 };
580 // SAFETY: - INTERFACE requires that the object has the interface WlDataOffer::WL_INTERFACE
581 let arg0 = arg0.as_ref().map(|arg0| unsafe {
582 proxy::low_level::from_untyped_borrowed::<WlDataOfferRef>(arg0)
583 });
584 self.0.selection(slf, arg0);
585 }
586 _ => {
587 invalid_opcode("wl_data_device", opcode);
588 }
589 }
590 }434 unsafe fn handle_event(
435 &self,
436 queue: &Queue,
437 slf: &UntypedBorrowedProxy,
438 opcode: u32,
439 args: *mut wl_argument,
440 ) {
441 // SAFETY: This function required that slf has the interface INTERFACE
442 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<WlKeyboardRef>(slf) };
443 match opcode {
444 0 => {
445 // SAFETY: INTERFACE requires that there are 3 arguments
446 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
447 // SAFETY: - INTERFACE requires that args[0] contains a uint
448 let arg0 = unsafe { WlKeyboardKeymapFormat(args[0].u) };
449 // SAFETY: - INTERFACE requires that args[1] contains a file descriptor
450 let arg1 = unsafe { OwnedFd::from_raw_fd(args[1].h) };
451 // SAFETY: - INTERFACE requires that args[2] contains a uint
452 let arg2 = unsafe { args[2].u };
453 self.0.keymap(slf, arg0, arg1, arg2);
454 }
455 1 => {
456 // SAFETY: INTERFACE requires that there are 3 arguments
457 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
458 // SAFETY: - INTERFACE requires that args[0] contains a uint
459 let arg0 = unsafe { args[0].u };
460 // SAFETY: - INTERFACE requires that args[1] contains an object
461 let arg1 = unsafe {
462 if let Some(p) = NonNull::new(args[1].o.cast()) {
463 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
464 } else {
465 None
466 }
467 };
468 // SAFETY: - INTERFACE requires that the object has the interface WlSurface::WL_INTERFACE
469 let arg1 = arg1.as_ref().map(|arg1| unsafe {
470 proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(arg1)
471 });
472 // SAFETY: - INTERFACE requires that args[2] contains an array
473 let arg2 = unsafe {
474 let a = &*args[2].a;
475 std::slice::from_raw_parts(a.data.cast(), a.size)
476 };
477 self.0.enter(slf, arg0, arg1, arg2);
478 }
479 2 => {
480 // SAFETY: INTERFACE requires that there are 2 arguments
481 let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
482 // SAFETY: - INTERFACE requires that args[0] contains a uint
483 let arg0 = unsafe { args[0].u };
484 // SAFETY: - INTERFACE requires that args[1] contains an object
485 let arg1 = unsafe {
486 if let Some(p) = NonNull::new(args[1].o.cast()) {
487 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
488 } else {
489 None
490 }
491 };
492 // SAFETY: - INTERFACE requires that the object has the interface WlSurface::WL_INTERFACE
493 let arg1 = arg1.as_ref().map(|arg1| unsafe {
494 proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(arg1)
495 });
496 self.0.leave(slf, arg0, arg1);
497 }
498 3 => {
499 // SAFETY: INTERFACE requires that there are 4 arguments
500 let args = unsafe { &*args.cast::<[wl_argument; 4]>() };
501 // SAFETY: - INTERFACE requires that args[0] contains a uint
502 let arg0 = unsafe { args[0].u };
503 // SAFETY: - INTERFACE requires that args[1] contains a uint
504 let arg1 = unsafe { args[1].u };
505 // SAFETY: - INTERFACE requires that args[2] contains a uint
506 let arg2 = unsafe { args[2].u };
507 // SAFETY: - INTERFACE requires that args[3] contains a uint
508 let arg3 = unsafe { WlKeyboardKeyState(args[3].u) };
509 self.0.key(slf, arg0, arg1, arg2, arg3);
510 }
511 4 => {
512 // SAFETY: INTERFACE requires that there are 5 arguments
513 let args = unsafe { &*args.cast::<[wl_argument; 5]>() };
514 // SAFETY: - INTERFACE requires that args[0] contains a uint
515 let arg0 = unsafe { args[0].u };
516 // SAFETY: - INTERFACE requires that args[1] contains a uint
517 let arg1 = unsafe { args[1].u };
518 // SAFETY: - INTERFACE requires that args[2] contains a uint
519 let arg2 = unsafe { args[2].u };
520 // SAFETY: - INTERFACE requires that args[3] contains a uint
521 let arg3 = unsafe { args[3].u };
522 // SAFETY: - INTERFACE requires that args[4] contains a uint
523 let arg4 = unsafe { args[4].u };
524 self.0.modifiers(slf, arg0, arg1, arg2, arg3, arg4);
525 }
526 5 => {
527 // SAFETY: INTERFACE requires that there are 2 arguments
528 let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
529 // SAFETY: - INTERFACE requires that args[0] contains an int
530 let arg0 = unsafe { args[0].i };
531 // SAFETY: - INTERFACE requires that args[1] contains an int
532 let arg1 = unsafe { args[1].i };
533 self.0.repeat_info(slf, arg0, arg1);
534 }
535 _ => {
536 invalid_opcode("wl_keyboard", opcode);
537 }
538 }
539 }483 unsafe fn handle_event(
484 &self,
485 queue: &Queue,
486 slf: &UntypedBorrowedProxy,
487 opcode: u32,
488 args: *mut wl_argument,
489 ) {
490 // SAFETY: This function required that slf has the interface INTERFACE
491 let slf = unsafe { proxy::low_level::from_untyped_borrowed::<ZwpTabletPadV2Ref>(slf) };
492 match opcode {
493 0 => {
494 // SAFETY: INTERFACE requires that there are 1 arguments
495 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
496 // SAFETY: - INTERFACE requires that args[0] contains an object
497 // - ownership is transferred to this function
498 // - INTERFACE requires that the object has the interface ZwpTabletPadGroupV2::WL_INTERFACE
499 let arg0 = unsafe {
500 UntypedOwnedProxy::from_plain_wl_proxy(
501 queue,
502 NonNull::new_unchecked(args[0].o.cast()),
503 ZwpTabletPadGroupV2::WL_INTERFACE,
504 )
505 };
506 // SAFETY: - INTERFACE requires that the object has the interface ZwpTabletPadGroupV2::WL_INTERFACE
507 let arg0 =
508 unsafe { proxy::low_level::from_untyped_owned::<ZwpTabletPadGroupV2>(arg0) };
509 self.0.group(slf, arg0);
510 }
511 1 => {
512 // SAFETY: INTERFACE requires that there are 1 arguments
513 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
514 // SAFETY: - INTERFACE requires that args[0] contains a string
515 // - if the pointer is not null, then it is a c string
516 let arg0 = unsafe { convert_string_arg("zwp_tablet_pad_v2", "path", args[0].s) };
517 self.0.path(slf, arg0);
518 }
519 2 => {
520 // SAFETY: INTERFACE requires that there are 1 arguments
521 let args = unsafe { &*args.cast::<[wl_argument; 1]>() };
522 // SAFETY: - INTERFACE requires that args[0] contains a uint
523 let arg0 = unsafe { args[0].u };
524 self.0.buttons(slf, arg0);
525 }
526 3 => {
527 self.0.done(slf);
528 }
529 4 => {
530 // SAFETY: INTERFACE requires that there are 3 arguments
531 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
532 // SAFETY: - INTERFACE requires that args[0] contains a uint
533 let arg0 = unsafe { args[0].u };
534 // SAFETY: - INTERFACE requires that args[1] contains a uint
535 let arg1 = unsafe { args[1].u };
536 // SAFETY: - INTERFACE requires that args[2] contains a uint
537 let arg2 = unsafe { ZwpTabletPadV2ButtonState(args[2].u) };
538 self.0.button(slf, arg0, arg1, arg2);
539 }
540 5 => {
541 // SAFETY: INTERFACE requires that there are 3 arguments
542 let args = unsafe { &*args.cast::<[wl_argument; 3]>() };
543 // SAFETY: - INTERFACE requires that args[0] contains a uint
544 let arg0 = unsafe { args[0].u };
545 // SAFETY: - INTERFACE requires that args[1] contains an object
546 let arg1 = unsafe {
547 if let Some(p) = NonNull::new(args[1].o.cast()) {
548 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
549 } else {
550 None
551 }
552 };
553 // SAFETY: - INTERFACE requires that the object has the interface ZwpTabletV2::WL_INTERFACE
554 let arg1 = arg1.as_ref().map(|arg1| unsafe {
555 proxy::low_level::from_untyped_borrowed::<ZwpTabletV2Ref>(arg1)
556 });
557 // SAFETY: - INTERFACE requires that args[2] contains an object
558 let arg2 = unsafe {
559 if let Some(p) = NonNull::new(args[2].o.cast()) {
560 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
561 } else {
562 None
563 }
564 };
565 // SAFETY: - INTERFACE requires that the object has the interface WlSurface::WL_INTERFACE
566 let arg2 = arg2.as_ref().map(|arg2| unsafe {
567 proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(arg2)
568 });
569 self.0.enter(slf, arg0, arg1, arg2);
570 }
571 6 => {
572 // SAFETY: INTERFACE requires that there are 2 arguments
573 let args = unsafe { &*args.cast::<[wl_argument; 2]>() };
574 // SAFETY: - INTERFACE requires that args[0] contains a uint
575 let arg0 = unsafe { args[0].u };
576 // SAFETY: - INTERFACE requires that args[1] contains an object
577 let arg1 = unsafe {
578 if let Some(p) = NonNull::new(args[1].o.cast()) {
579 Some(UntypedBorrowedProxy::new_immutable(queue.libwayland(), p))
580 } else {
581 None
582 }
583 };
584 // SAFETY: - INTERFACE requires that the object has the interface WlSurface::WL_INTERFACE
585 let arg1 = arg1.as_ref().map(|arg1| unsafe {
586 proxy::low_level::from_untyped_borrowed::<WlSurfaceRef>(arg1)
587 });
588 self.0.leave(slf, arg0, arg1);
589 }
590 7 => {
591 self.0.removed(slf);
592 }
593 _ => {
594 invalid_opcode("zwp_tablet_pad_v2", opcode);
595 }
596 }
597 }Sourcepub fn connection(&self) -> &Connection
pub fn connection(&self) -> &Connection
Returns the connection that this queue belongs to.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
assert_eq!(queue.connection(), &con);Sourcepub fn lock_dispatch(&self) -> DispatchLock<'_>
pub fn lock_dispatch(&self) -> DispatchLock<'_>
Acquires the queue’s re-entrant lock.
See the description of Queue for why you might use this.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
let lock = queue.lock_dispatch();
let thread = {
let queue = queue.clone();
thread::spawn(move || {
// this dispatch will not start until the lock is dropped.
queue.dispatch_roundtrip_blocking().unwrap();
})
};
// this dispatch starts immediately since the lock is re-entrant
queue.dispatch_roundtrip_blocking().unwrap();
drop(lock);
thread.join().unwrap();Sourcepub fn display<T>(&self) -> Twhere
T: OwnedProxy,
pub fn display<T>(&self) -> Twhere
T: OwnedProxy,
Creates a wrapper proxy around the singleton wl_display object.
The proxy is a wrapper and no event handler can be attached to it.
The proxy is attached to this queue.
§Panic
Panics if the interface of T is not compatible with the wl_display interface.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
let display: WlDisplay = queue.display();
assert_eq!(proxy::queue(&display), &*queue);
assert_eq!(proxy::id(&*display), 1);Examples found in repository?
More examples
26fn main() {
27 let lib = Libwayland::open().unwrap();
28 let con = lib.connect_to_default_display().unwrap();
29 let queue = con.create_local_queue(c"keyboard-events");
30 let singletons = get_singletons(&queue.display());
31 let simple_window = simple_window::prepare(singletons);
32
33 let wl_registry = queue.display::<WlDisplay>().get_registry();
34 proxy::set_event_handler_local(
35 &wl_registry,
36 RegistryEventHandler {
37 wl_registry: wl_registry.clone(),
38 seats: Default::default(),
39 },
40 );
41
42 while !simple_window.exit.get() {
43 queue.dispatch_blocking().unwrap();
44 }
45}11async fn main() {
12 let lib = Libwayland::open().unwrap();
13 let con = lib.connect_to_default_display().unwrap();
14 let queue = con.create_local_queue(c"async-roundtrip");
15 let registry = queue.display::<WlDisplay>().get_registry();
16 let num_globals = Cell::new(0);
17 queue
18 .dispatch_scope_async(async |scope| {
19 scope.set_event_handler_local(
20 ®istry,
21 WlRegistry::on_global(|_, _, _, _| {
22 num_globals.set(num_globals.get() + 1);
23 }),
24 );
25 // This function can be used to perform an async roundtrip. It is
26 // compatible with any async runtime. This example also demonstrates
27 // that this works in combination with scoped event handlers.
28 queue.dispatch_roundtrip_async().await.unwrap();
29 })
30 .await;
31 println!("number of globals: {}", num_globals.get());
32}Sourcepub fn is_local(&self) -> bool
pub fn is_local(&self) -> bool
Returns whether this is a local queue.
The documentation of the Queue type explains the difference between local and
non-local queues.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue1 = con.create_queue(c"non-local queue");
let queue2 = con.create_local_queue(c"local queue");
assert!(queue1.is_non_local());
assert!(queue2.is_local());Sourcepub fn is_non_local(&self) -> bool
pub fn is_non_local(&self) -> bool
Returns whether this is not a local queue.
This is the same as !self.is_local().
The documentation of the Queue type explains the difference between local and
non-local queues.
Sourcepub fn wl_event_queue(&self) -> NonNull<wl_event_queue>
pub fn wl_event_queue(&self) -> NonNull<wl_event_queue>
Returns the wl_event_queue pointer of this queue.
The returned pointer is valid for as long as this queue exists.
You must not dispatch the queue except through the Queue interface.
Otherwise the behavior is undefined.
Sourcepub fn dispatch_blocking(&self) -> Result<u64>
pub fn dispatch_blocking(&self) -> Result<u64>
Blocks the current thread until at least one event has been dispatched.
If you are in an async context, then you might want to use
Queue::dispatch_async instead.
This function should not be used when integrating with an existing, poll-based
event loop, as it might block indefinitely. Use Connection::create_watcher and
Queue::dispatch_pending instead.
The returned number is the number of events that have been dispatched by this call. The number can be zero if another thread dispatched the events before us.
§Panic
Panics if this is a local queue and the current thread is not the thread that this queue was created in.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
// For this example, ensure that the compositor sends an event in the near future.
let _sync = queue.display::<WlDisplay>().sync();
queue.dispatch_blocking().unwrap();Examples found in repository?
More examples
26fn main() {
27 let lib = Libwayland::open().unwrap();
28 let con = lib.connect_to_default_display().unwrap();
29 let queue = con.create_local_queue(c"keyboard-events");
30 let singletons = get_singletons(&queue.display());
31 let simple_window = simple_window::prepare(singletons);
32
33 let wl_registry = queue.display::<WlDisplay>().get_registry();
34 proxy::set_event_handler_local(
35 &wl_registry,
36 RegistryEventHandler {
37 wl_registry: wl_registry.clone(),
38 seats: Default::default(),
39 },
40 );
41
42 while !simple_window.exit.get() {
43 queue.dispatch_blocking().unwrap();
44 }
45}Sourcepub async fn dispatch_async(&self) -> Result<u64>
pub async fn dispatch_async(&self) -> Result<u64>
Completes when at least one event has been dispatched.
This function is the same as Queue::dispatch_blocking except that it is async and does
not block the current thread.
§Panic
Panics if this is a local queue and the thread polling the future is not the thread that this queue was created in.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
// For this example, ensure that the compositor sends an event in the near future.
let _sync = queue.display::<WlDisplay>().sync();
queue.dispatch_async().await.unwrap();Sourcepub fn dispatch_pending(&self) -> Result<u64>
pub fn dispatch_pending(&self) -> Result<u64>
Dispatches enqueued events.
This function does not read new events from the file descriptor.
This function can be used together with BorrowedQueue::wait_for_events or
Queue::create_watcher to dispatch the queue in an async context or event loop
respectively.
The returned number is the number of events that were dispatched.
§Panic
Panics if this is a local queue and the current thread is not the thread that this queue was created in.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
let display: WlDisplay = queue.display();
let done = Arc::new(AtomicBool::new(false));
let done2 = done.clone();
let sync = display.sync();
proxy::set_event_handler(&sync, WlCallback::on_done(move |_, _| {
done2.store(true, Relaxed);
}));
while !done.load(Relaxed) {
queue.wait_for_events().await.unwrap();
// Dispatch the events.
queue.dispatch_pending().unwrap();
}Examples found in repository?
10async fn main() {
11 let lib = Libwayland::open().unwrap();
12 let con = lib.connect_to_default_display().unwrap();
13 let queue = con.create_local_queue(c"async-wait");
14
15 create_sync(&queue, 1);
16
17 loop {
18 queue.wait_for_events().await.unwrap();
19 queue.dispatch_pending().unwrap();
20 }
21}More examples
11fn main() {
12 let lib = Libwayland::open().unwrap();
13 let con = lib.connect_to_default_display().unwrap();
14 let queue = con.create_local_queue(c"poll-integration");
15
16 // The watcher exposes a file descriptor that will become readable when the queue
17 // has new events.
18 let watcher = queue.create_watcher().unwrap();
19 let token = Token(0);
20
21 create_sync(&queue, 1);
22
23 let mut events = mio::Events::with_capacity(2);
24 let mut poll = mio::Poll::new().unwrap();
25 poll.registry()
26 .register(
27 &mut SourceFd(&watcher.as_raw_fd()),
28 token,
29 Interest::READABLE,
30 )
31 .unwrap();
32
33 loop {
34 // Flush requests before polling.
35 con.flush().unwrap();
36 poll.poll(&mut events, None).unwrap();
37 for event in events.iter() {
38 if event.token() == token {
39 queue.dispatch_pending().unwrap();
40 // Reset the watcher to clear the readability status.
41 watcher.reset().unwrap();
42 }
43 }
44 events.clear();
45 }
46}Sourcepub fn dispatch_roundtrip_blocking(&self) -> Result<()>
pub fn dispatch_roundtrip_blocking(&self) -> Result<()>
Blocks the current thread until the compositor has processed all previous requests and all of its response events have been dispatched.
If you are in an async context, then you might want to use
Queue::dispatch_roundtrip_async instead.
Since this function usually returns quickly, you might use this function even when integrating a wayland connection into an existing event loop and even in an async context. For example, a library that creates buffers might use this function during initialization to receive the full list of supported formats before returning.
If this function returns Ok(()), then the function returns after (in the sense
of the C++ memory model) the event handlers of all previous events have been
invoked.
§Panic
Panics if this is a local queue and the current thread is not the thread that this queue was created in.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"");
let display: WlDisplay = queue.display();
// send some messages to the compositor
let done = Arc::new(AtomicBool::new(false));
let done2 = done.clone();
let sync = display.sync();
proxy::set_event_handler(&sync, WlCallback::on_done(move |_, _| {
done2.store(true, Relaxed);
}));
// perform a roundtrip
queue.dispatch_roundtrip_blocking().unwrap();
// assert that we've received the response
assert!(done.load(Relaxed));Examples found in repository?
56pub fn get_singletons(display: &WlDisplay) -> Singletons {
57 let map = Mutex::new(HashMap::new());
58
59 let queue = proxy::queue(display);
60 let wl_registry = display.get_registry();
61
62 queue.dispatch_scope_blocking(|scope| {
63 scope.set_event_handler(
64 &wl_registry,
65 WlRegistry::on_global(|_, name, interface, version| {
66 map.lock().insert(interface.to_owned(), (name, version));
67 }),
68 );
69 queue.dispatch_roundtrip_blocking().unwrap();
70 });
71
72 Singletons {
73 wl_registry,
74 map: map.into_inner(),
75 }
76}More examples
27fn get_registry_snapshot(queue: &Queue) -> (WlRegistry, Vec<Global>) {
28 // Create a new registry that will receive the globals and can later be used to
29 // bind them.
30 let registry = queue.display::<WlDisplay>().get_registry();
31 let globals = Mutex::new(vec![]);
32 // Since we don't care about registry events after this function returns, we can
33 // use a dispatch scope. The event handlers in this scope will not be called after
34 // the function returns.
35 queue.dispatch_scope_blocking(|scope| {
36 scope.set_event_handler(
37 ®istry,
38 // Since we only want to create a snapshot, we don't care about
39 // global_remove events. This allows us to use the functional event handler
40 // form.
41 WlRegistry::on_global(|_, name, interface, version| {
42 globals.lock().push(Global {
43 name,
44 interface: interface.to_string(),
45 version,
46 });
47 }),
48 );
49 queue.dispatch_roundtrip_blocking().unwrap();
50 });
51 // The event handler will no longer be called after this function returns but
52 // the registry can still be used to bind globals.
53 (registry, globals.into_inner())
54}9fn main() {
10 // Load the `libwayland-client.so` dynamic library.
11 let lib = Libwayland::open().unwrap();
12 // Connect to the default display determined by the `WAYLAND_DISPLAY` env var.
13 let con = lib.connect_to_default_display().unwrap();
14 // Create a new event queue with the name `hello-wayland`. This name will show up
15 // when debugging applications with `WAYLAND_DEBUG=1`.
16 let queue = con.create_queue(c"hello-wayland");
17 // Get a reference to the `wl_display` singleton. This type was generated with the
18 // `wl-client-builder` crate.
19 let display: WlDisplay = queue.display();
20 // Create a `wl_callback` object. The compositor will immediately respond with a
21 // `wl_callback.done` event.
22 let sync = display.sync();
23 // Set the event handler of the proxy.
24 proxy::set_event_handler(
25 &sync,
26 // When only handling a single event, the following functional form can be used.
27 // In general, and when handling more than one event, the event handler trait must
28 // be implemented. In this case, `WlCallbackEventHandler`.
29 WlCallback::on_done(|_, _| println!("Hello wayland!")),
30 );
31 // Perform a roundtrip to ensure that the `done` event has been dispatched.
32 queue.dispatch_roundtrip_blocking().unwrap();
33}Sourcepub async fn dispatch_roundtrip_async(&self) -> Result<()>
pub async fn dispatch_roundtrip_async(&self) -> Result<()>
Completes when the compositor has processed all previous requests and all of its response events have been dispatched.
This function is the same as Queue::dispatch_roundtrip_blocking except that it is async and does
not block the current thread.
If the future completes with Ok(()), then the future completes after (in the
sense of the C++ memory model) the event handlers of all previous events have been
invoked.
§Panic
Panics if this is a local queue and the thread polling the future is not the thread that this queue was created in.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
let display: WlDisplay = queue.display();
// send some messages to the compositor
let done = Arc::new(AtomicBool::new(false));
let done2 = done.clone();
let sync = display.sync();
proxy::set_event_handler(&sync, WlCallback::on_done(move |_, _| {
done2.store(true, Relaxed);
}));
// perform a roundtrip
queue.dispatch_roundtrip_async().await.unwrap();
// assert that we've received the response
assert!(done.load(Relaxed));Examples found in repository?
78pub async fn get_singletons_async(display: &WlDisplay) -> Singletons {
79 let map = Mutex::new(HashMap::new());
80
81 let queue = proxy::queue(display);
82 let wl_registry = display.get_registry();
83
84 queue
85 .dispatch_scope_async(async |scope| {
86 scope.set_event_handler(
87 &wl_registry,
88 WlRegistry::on_global(|_, name, interface, version| {
89 map.lock().insert(interface.to_owned(), (name, version));
90 }),
91 );
92 queue.dispatch_roundtrip_async().await.unwrap();
93 })
94 .await;
95
96 Singletons {
97 wl_registry,
98 map: map.into_inner(),
99 }
100}More examples
11async fn main() {
12 let lib = Libwayland::open().unwrap();
13 let con = lib.connect_to_default_display().unwrap();
14 let queue = con.create_local_queue(c"async-roundtrip");
15 let registry = queue.display::<WlDisplay>().get_registry();
16 let num_globals = Cell::new(0);
17 queue
18 .dispatch_scope_async(async |scope| {
19 scope.set_event_handler_local(
20 ®istry,
21 WlRegistry::on_global(|_, _, _, _| {
22 num_globals.set(num_globals.get() + 1);
23 }),
24 );
25 // This function can be used to perform an async roundtrip. It is
26 // compatible with any async runtime. This example also demonstrates
27 // that this works in combination with scoped event handlers.
28 queue.dispatch_roundtrip_async().await.unwrap();
29 })
30 .await;
31 println!("number of globals: {}", num_globals.get());
32}Sourcepub fn wrap_proxy<P>(&self, proxy: &P) -> P::Ownedwhere
P: BorrowedProxy,
pub fn wrap_proxy<P>(&self, proxy: &P) -> P::Ownedwhere
P: BorrowedProxy,
Creates a wrapper for an existing proxy.
The wrapper will be assigned to this queue. No event handler can be assigned to the wrapper.
§Panic
- Panics if the proxy and this queue don’t belong to the same
wl_display. - Panics if the proxy is already destroyed.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue1 = con.create_queue(c"queue name");
let display1: WlDisplay = queue1.display();
assert_eq!(proxy::queue(&display1), &*queue1);
let queue2 = con.create_queue(c"second queue");
let display2 = queue2.wrap_proxy(&*display1);
assert_eq!(proxy::queue(&display2), &*queue2);Sourcepub unsafe fn wrap_wl_proxy<P>(&self, proxy: NonNull<wl_proxy>) -> Pwhere
P: OwnedProxy,
pub unsafe fn wrap_wl_proxy<P>(&self, proxy: NonNull<wl_proxy>) -> Pwhere
P: OwnedProxy,
Creates a wrapper for an existing wl_proxy.
The wrapper will be assigned to this queue. No event handler can be assigned to the wrapper.
If the wl_proxy already has a safe wrapper, the Queue::wrap_proxy function
can be used instead.
§Panic
- Panics if the proxy and this queue don’t belong to the same
wl_display.
§Safety
proxymust be a valid pointer.proxymust have an interface compatible withP::WL_INTERFACE.
§Example
Some frameworks, e.g. winit, expose libwayland wl_display and wl_surface
pointers. These can be imported into this crate as follows:
unsafe fn wrap_foreign_surface(display: NonNull<c_void>, wl_surface: NonNull<c_void>) {
let lib = Libwayland::open().unwrap();
// SAFETY: ...
let con = unsafe { lib.wrap_borrowed_pointer(display.cast()).unwrap() };
let queue = con.create_queue(c"queue name");
// SAFETY: ...
let surface: WlSurface = unsafe { queue.wrap_wl_proxy(wl_surface.cast()) };
}Sourcepub fn create_watcher(&self) -> Result<QueueWatcher>
pub fn create_watcher(&self) -> Result<QueueWatcher>
Creates a QueueWatcher for event-loop integration.
This is a shorthand for calling Connection::create_watcher with a queue list
containing exactly this queue.
Examples found in repository?
11fn main() {
12 let lib = Libwayland::open().unwrap();
13 let con = lib.connect_to_default_display().unwrap();
14 let queue = con.create_local_queue(c"poll-integration");
15
16 // The watcher exposes a file descriptor that will become readable when the queue
17 // has new events.
18 let watcher = queue.create_watcher().unwrap();
19 let token = Token(0);
20
21 create_sync(&queue, 1);
22
23 let mut events = mio::Events::with_capacity(2);
24 let mut poll = mio::Poll::new().unwrap();
25 poll.registry()
26 .register(
27 &mut SourceFd(&watcher.as_raw_fd()),
28 token,
29 Interest::READABLE,
30 )
31 .unwrap();
32
33 loop {
34 // Flush requests before polling.
35 con.flush().unwrap();
36 poll.poll(&mut events, None).unwrap();
37 for event in events.iter() {
38 if event.token() == token {
39 queue.dispatch_pending().unwrap();
40 // Reset the watcher to clear the readability status.
41 watcher.reset().unwrap();
42 }
43 }
44 events.clear();
45 }
46}Methods from Deref<Target = BorrowedQueue>§
Sourcepub async fn wait_for_events(&self) -> Result<()>
pub async fn wait_for_events(&self) -> Result<()>
Completes when there are new events in this queue.
When this function returns Ok(()), this queue has an event queued.
This is a shorthand for calling Connection::wait_for_events with a
queue list consisting of exactly this queue.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
let display: WlDisplay = queue.display();
let done = Arc::new(AtomicBool::new(false));
let done2 = done.clone();
let sync = display.sync();
proxy::set_event_handler(&sync, WlCallback::on_done(move |_, _| {
done2.store(true, Release);
}));
while !done.load(Acquire) {
queue.wait_for_events().await.unwrap();
queue.dispatch_pending().unwrap();
}Examples found in repository?
10async fn main() {
11 let lib = Libwayland::open().unwrap();
12 let con = lib.connect_to_default_display().unwrap();
13 let queue = con.create_local_queue(c"async-wait");
14
15 create_sync(&queue, 1);
16
17 loop {
18 queue.wait_for_events().await.unwrap();
19 queue.dispatch_pending().unwrap();
20 }
21}Sourcepub fn wl_event_queue(&self) -> Option<NonNull<wl_event_queue>>
pub fn wl_event_queue(&self) -> Option<NonNull<wl_event_queue>>
Returns the wl_event_queue representing this queue.
This function returns None if and only if this queue is the default queue of the
connection.
The returned pointer, if any, remains valid as long as this object exists.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_queue(c"queue name");
let default_queue = con.borrow_default_queue();
assert_eq!((**queue).wl_event_queue(), Some(queue.wl_event_queue()));
assert_eq!(default_queue.wl_event_queue(), None);