diff --git a/wayland-backend/CHANGELOG.md b/wayland-backend/CHANGELOG.md index 204d866ecef..a0cd40d803d 100644 --- a/wayland-backend/CHANGELOG.md +++ b/wayland-backend/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- client: Add `Backend::poll_fd` to return fd for polling + ## 0.3.0 -- 2023-09-02 #### Breaking change diff --git a/wayland-backend/src/client_api.rs b/wayland-backend/src/client_api.rs index 972a2b65acd..a5911101827 100644 --- a/wayland-backend/src/client_api.rs +++ b/wayland-backend/src/client_api.rs @@ -181,6 +181,12 @@ impl Backend { self.backend.flush() } + /// Access the Wayland socket FD for polling + #[inline] + pub fn poll_fd(&self) -> BorrowedFd { + self.backend.poll_fd() + } + /// Get the object ID for the `wl_display` #[inline] pub fn display_id(&self) -> ObjectId { diff --git a/wayland-backend/src/rs/client_impl/mod.rs b/wayland-backend/src/rs/client_impl/mod.rs index bad86aa3ba8..4920114cbc7 100644 --- a/wayland-backend/src/rs/client_impl/mod.rs +++ b/wayland-backend/src/rs/client_impl/mod.rs @@ -191,6 +191,13 @@ impl InnerBackend { } Ok(()) } + + pub fn poll_fd(&self) -> BorrowedFd { + let raw_fd = self.state.lock_protocol().socket.as_raw_fd(); + // This allows the lifetime of the BorrowedFd to be tied to &self rather than the lock guard, + // which is the real safety concern + unsafe { BorrowedFd::borrow_raw(raw_fd) } + } } #[derive(Debug)] diff --git a/wayland-backend/src/sys/client_impl/mod.rs b/wayland-backend/src/sys/client_impl/mod.rs index 25c59346ac7..b3cc1f60df6 100644 --- a/wayland-backend/src/sys/client_impl/mod.rs +++ b/wayland-backend/src/sys/client_impl/mod.rs @@ -293,6 +293,17 @@ impl InnerBackend { } } + pub fn poll_fd(&self) -> BorrowedFd { + let guard = self.lock_state(); + unsafe { + BorrowedFd::borrow_raw(ffi_dispatch!( + wayland_client_handle(), + wl_display_get_fd, + guard.display + )) + } + } + pub fn dispatch_inner_queue(&self) -> Result { self.inner.dispatch_lock.lock().unwrap().dispatch_pending(self.inner.clone()) } diff --git a/wayland-client/CHANGELOG.md b/wayland-client/CHANGELOG.md index 0976dcb4216..23ec03170cf 100644 --- a/wayland-client/CHANGELOG.md +++ b/wayland-client/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Implement `AsFd` for `Connection` and `EventQueue` so they can easily be used in a + `calloop` source. + ## 0.31.0 -- 2023-09-02 #### Breaking changes diff --git a/wayland-client/src/conn.rs b/wayland-client/src/conn.rs index 6812bfc393f..3dc89af8796 100644 --- a/wayland-client/src/conn.rs +++ b/wayland-client/src/conn.rs @@ -3,7 +3,7 @@ use std::{ io::ErrorKind, os::unix::io::OwnedFd, os::unix::net::UnixStream, - os::unix::prelude::{AsRawFd, FromRawFd}, + os::unix::prelude::{AsFd, AsRawFd, BorrowedFd, FromRawFd}, path::PathBuf, sync::{ atomic::{AtomicBool, Ordering}, @@ -273,6 +273,13 @@ impl fmt::Display for ConnectError { } } +impl AsFd for Connection { + /// Provides fd from [`Backend::poll_fd`] for polling. + fn as_fd(&self) -> BorrowedFd<'_> { + self.backend.poll_fd() + } +} + /* wl_callback object data for wl_display.sync */ diff --git a/wayland-client/src/event_queue.rs b/wayland-client/src/event_queue.rs index b1280baedea..ebd72c87bdb 100644 --- a/wayland-client/src/event_queue.rs +++ b/wayland-client/src/event_queue.rs @@ -2,7 +2,7 @@ use std::any::Any; use std::collections::VecDeque; use std::convert::Infallible; use std::marker::PhantomData; -use std::os::unix::io::OwnedFd; +use std::os::unix::io::{AsFd, BorrowedFd, OwnedFd}; use std::sync::{atomic::Ordering, Arc, Condvar, Mutex}; use std::task; @@ -349,6 +349,13 @@ impl std::fmt::Debug for EventQueue { } } +impl AsFd for EventQueue { + /// Provides fd from [`Backend::poll_fd`] for polling. + fn as_fd(&self) -> BorrowedFd<'_> { + self.conn.as_fd() + } +} + impl EventQueue { pub(crate) fn new(conn: Connection) -> Self { let inner = Arc::new(Mutex::new(EventQueueInner {