Skip to content

Commit 8d161e5

Browse files
Supreeemeelinorbgr
authored andcommitted
wayland-client: add example for bypassing Dispatch
Also mention ObjectData in the docs for bypassing Dispatch.
1 parent d9f2fde commit 8d161e5

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use std::os::fd::OwnedFd;
2+
use std::sync::Arc;
3+
use wayland_client::{
4+
backend::{self, Backend},
5+
protocol::{wl_display, wl_registry},
6+
Connection, Proxy,
7+
};
8+
9+
// This struct represents the data associated with our registry.
10+
struct RegistryData(Arc<Connection>);
11+
12+
// Instead of implementing Dispatch on some global state, we will implement
13+
// ObjectData for our registry. This is required to receive events
14+
// (specifically, the wl_registry.global events) after our wl_registry.get_registry request.
15+
impl backend::ObjectData for RegistryData {
16+
fn event(
17+
self: Arc<Self>,
18+
_: &Backend,
19+
msg: backend::protocol::Message<backend::ObjectId, OwnedFd>,
20+
) -> Option<Arc<dyn backend::ObjectData>> {
21+
// Here, we parse the wire message into an event using Proxy::parse_event.
22+
let (_registry, event) = wl_registry::WlRegistry::parse_event(&self.0, msg).unwrap();
23+
24+
// Similar to the dispatch example, we only care about the global event and
25+
// will print out the received globals.
26+
if let wl_registry::Event::Global { name, interface, version } = event {
27+
println!("[{}] {} (v{})", name, interface, version);
28+
}
29+
None
30+
}
31+
32+
// This method is called whenever the object is destroyed. In the case of our registry,
33+
// however, there is no way to destroy it, so we will mark it as unreachable.
34+
fn destroyed(&self, _: wayland_backend::client::ObjectId) {
35+
unreachable!();
36+
}
37+
}
38+
39+
fn main() {
40+
// Create our connection like the Dispatch example, except we store it in an Arc
41+
// to share with our registry object data.
42+
let conn = Arc::new(Connection::connect_to_env().unwrap());
43+
let display = conn.display();
44+
45+
let registry_data = Arc::new(RegistryData(conn.clone()));
46+
47+
// Send the `wl_display.get_registry` request, which returns a `wl_registry` to us.
48+
// Since this request creates a new object, we will use the `Proxy::send_constructor` method
49+
// to send it. If it didn't, we would use `Proxy::send_request`.
50+
let _registry: wl_registry::WlRegistry = display
51+
.send_constructor(wl_display::Request::GetRegistry {}, registry_data.clone())
52+
.unwrap();
53+
54+
println!("Advertised globals:");
55+
56+
// Invoke our roundtrip to receive the events. This essentially is the same as the
57+
// `EventQueue::roundtrip` method, except it does not have a state to dispatch methods on.
58+
conn.roundtrip().unwrap();
59+
}

wayland-client/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@
140140
//! APIs from `wayland-backend`, allowing you to register callbacks for those objects that will be invoked
141141
//! whenever they receive an event and *any* event queue from the program is being dispatched. Those
142142
//! callbacks are more constrained: they don't get a `&mut State` reference, and must be threadsafe. See
143-
//! [`Proxy::send_constructor`] for details about how to assign such callbacks to objects.
143+
//! [`Proxy::send_constructor`] and [`ObjectData`](crate::backend::ObjectData) for details about how to
144+
//! assign such callbacks to objects.
144145
//!
145146
//! ### Interaction with FFI
146147
//!

0 commit comments

Comments
 (0)