pub struct Scope<'scope, 'env: 'scope> { /* private fields */ }Expand description
A scope for event handlers with shorter than 'static lifetime.
Scopes are created by calling Queue::dispatch_scope_blocking and
Queue::dispatch_scope_async.
Event handlers attached via a scope have the following, additional restriction: they
will be dropped and therefore not be invoked after the lifetime of the scope has
ended. The proxies can still be used to send requests or as arguments, but no event
callbacks will be invoked. Instead, the OwnedProxy::NO_OP_EVENT_HANDLER will be
invoked to prevent any memory leaks.
Async scopes created via Queue::dispatch_scope_async have one more restriction:
event handlers will only be invoked while the returned future is being polled. Until
the future completes, the queue should therefore only be dispatched from inside the
future.
§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());Implementations§
Source§impl<'scope> Scope<'scope, '_>
impl<'scope> Scope<'scope, '_>
Sourcepub fn set_event_handler<P, H>(&'scope self, proxy: &P, handler: H)where
P: OwnedProxy,
P::Api: CreateEventHandler<H>,
<P::Api as CreateEventHandler<H>>::EventHandler: Send + 'scope,
pub fn set_event_handler<P, H>(&'scope self, proxy: &P, handler: H)where
P: OwnedProxy,
P::Api: CreateEventHandler<H>,
<P::Api as CreateEventHandler<H>>::EventHandler: Send + 'scope,
Sets the event handler of the proxy.
This function is the same as proxy::set_event_handler except that the event
handler does not have to implement 'static and that the event handler will not
be invoked after 'scope.
The proxy must belong to the queue that was used to create this scope.
§Panic
This function panics whenever proxy::set_event_handler panics and also if the
proxy does not belong to the queue that was used to create this scope.
§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 sync = display.sync();
let done = AtomicBool::new(false);
queue.dispatch_scope_blocking(|scope| {
// Attach the event handler.
scope.set_event_handler(&sync, WlCallback::on_done(|_, _| done.store(true, Relaxed)));
// Wait for the compositor to send the `done` message.
queue.dispatch_roundtrip_blocking().unwrap();
});
// The event handler sets the value to `true`.
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}
77
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
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 fn set_event_handler_local<P, H>(&'scope self, proxy: &P, handler: H)where
P: OwnedProxy,
P::Api: CreateEventHandler<H>,
<P::Api as CreateEventHandler<H>>::EventHandler: 'scope,
pub fn set_event_handler_local<P, H>(&'scope self, proxy: &P, handler: H)where
P: OwnedProxy,
P::Api: CreateEventHandler<H>,
<P::Api as CreateEventHandler<H>>::EventHandler: 'scope,
Sets the !Send event handler of the proxy.
This function is the same as proxy::set_event_handler_local except that the
event handler does not have to implement 'static and that the event handler will
not be invoked after 'scope.
The proxy must belong to the queue that was used to create this scope.
§Panic
This function panics whenever proxy::set_event_handler_local panics and also
if the proxy does not belong to the queue that was used to create this scope.
§Example
let lib = Libwayland::open().unwrap();
let con = lib.connect_to_default_display().unwrap();
let queue = con.create_local_queue(c"queue name");
let display: WlDisplay = queue.display();
let sync = display.sync();
let done = Cell::new(false);
queue.dispatch_scope_blocking(|scope| {
// Attach the event handler.
scope.set_event_handler_local(&sync, WlCallback::on_done(|_, _| done.set(true)));
// Wait for the compositor to send the `done` message.
queue.dispatch_roundtrip_blocking().unwrap();
});
// The event handler sets the value to `true`.
assert!(done.get());Examples found in repository?
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}