Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wayland-client: add example for bypassing Dispatch #711

Merged
merged 1 commit into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions wayland-client/examples/list_globals_no_dispatch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use std::os::fd::OwnedFd;
use std::sync::Arc;
use wayland_client::{
backend::{self, Backend},
protocol::{wl_display, wl_registry},
Connection, Proxy,
};

// This struct represents the data associated with our registry.
struct RegistryData(Arc<Connection>);

// Instead of implementing Dispatch on some global state, we will implement
// ObjectData for our registry. This is required to receive events
// (specifically, the wl_registry.global events) after our wl_registry.get_registry request.
impl backend::ObjectData for RegistryData {
fn event(
self: Arc<Self>,
_: &Backend,
msg: backend::protocol::Message<backend::ObjectId, OwnedFd>,
) -> Option<Arc<dyn backend::ObjectData>> {
// Here, we parse the wire message into an event using Proxy::parse_event.
let (_registry, event) = wl_registry::WlRegistry::parse_event(&self.0, msg).unwrap();

// Similar to the dispatch example, we only care about the global event and
// will print out the received globals.
if let wl_registry::Event::Global { name, interface, version } = event {
println!("[{}] {} (v{})", name, interface, version);
}
None
}

// This method is called whenever the object is destroyed. In the case of our registry,
// however, there is no way to destroy it, so we will mark it as unreachable.
fn destroyed(&self, _: wayland_backend::client::ObjectId) {
unreachable!();
}
}

fn main() {
// Create our connection like the Dispatch example, except we store it in an Arc
// to share with our registry object data.
let conn = Arc::new(Connection::connect_to_env().unwrap());
let display = conn.display();

let registry_data = Arc::new(RegistryData(conn.clone()));

// Send the `wl_display.get_registry` request, which returns a `wl_registry` to us.
// Since this request creates a new object, we will use the `Proxy::send_constructor` method
// to send it. If it didn't, we would use `Proxy::send_request`.
let _registry: wl_registry::WlRegistry = display
.send_constructor(wl_display::Request::GetRegistry {}, registry_data.clone())
.unwrap();

println!("Advertised globals:");

// Invoke our roundtrip to receive the events. This essentially is the same as the
// `EventQueue::roundtrip` method, except it does not have a state to dispatch methods on.
conn.roundtrip().unwrap();
}
3 changes: 2 additions & 1 deletion wayland-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,8 @@
//! APIs from `wayland-backend`, allowing you to register callbacks for those objects that will be invoked
//! whenever they receive an event and *any* event queue from the program is being dispatched. Those
//! callbacks are more constrained: they don't get a `&mut State` reference, and must be threadsafe. See
//! [`Proxy::send_constructor`] for details about how to assign such callbacks to objects.
//! [`Proxy::send_constructor`] and [`ObjectData`](crate::backend::ObjectData) for details about how to

Check warning on line 143 in wayland-client/src/lib.rs

View workflow job for this annotation

GitHub Actions / Documentation on Github Pages

redundant explicit link target
//! assign such callbacks to objects.
//!
//! ### Interaction with FFI
//!
Expand All @@ -151,7 +152,7 @@
//! it to your dependencies and enabling its `client_system` feature.
//!
//! - If you need to send pointers to FFI, you can retrive the `*mut wl_proxy` pointers from the proxies by
//! first getting the [`ObjectId`](crate::backend::ObjectId) using the [`Proxy::id()`] method, and then

Check warning on line 155 in wayland-client/src/lib.rs

View workflow job for this annotation

GitHub Actions / Documentation on Github Pages

redundant explicit link target
//! using the `ObjectId::as_ptr()` method.
//! - If you need to receive pointers from FFI, you need to first create a
//! [`Backend`](crate::backend::Backend) from the `*mut wl_display` using the `from_external_display()`
Expand Down
Loading