diff --git a/CHANGELOG.md b/CHANGELOG.md index 5728a2670..c4e6b8a11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - `wayland-csd-frame` is now used for CSD types like `WindowState`, `DecorationsFrame`, etc. - Added `CompositorHandle::transform_changed` to listen for transform changes. - `xkeysym::Keysym` is used as a keyboard key representation instead of `u32` +- `wayland-rs` dependencies are updated to 0.31 +- `calloop` dependency updated to 0.12.1 #### Fixed diff --git a/Cargo.toml b/Cargo.toml index 7d5bd9da1..c0ad3f35d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ features = ["calloop", "xkbcommon"] rustdoc-args = ["--cfg", "docsrs"] [dependencies] -bitflags = "1.0" +bitflags = "2.4" bytemuck = { version = "1.13.0", optional = true } cursor-icon = "1.0.0" dlib = "0.5" @@ -24,21 +24,23 @@ log = "0.4" memmap2 = "0.7.0" nix = { version = "0.26.1", default-features = false, features = ["fs", "mman"] } thiserror = "1.0.30" -wayland-backend = "0.1.0" -wayland-client = "0.30.2" -wayland-cursor = "0.30.0" -wayland-protocols = { version = "0.30.1", features = ["client", "staging", "unstable"] } -wayland-protocols-wlr = { version = "0.1.0", features = ["client"] } -wayland-scanner = "0.30.0" -wayland-csd-frame = { version = "0.2.2", default-features = false, features = ["wayland-backend_0_1"] } +wayland-backend = "0.3.0" +wayland-client = "0.31.1" +wayland-cursor = "0.31.0" +wayland-protocols = { version = "0.31.0", features = ["client", "staging", "unstable"] } +wayland-protocols-wlr = { version = "0.2.0", features = ["client"] } +wayland-scanner = "0.31.0" +wayland-csd-frame = "0.3.0" xkbcommon = { version = "0.5.0", optional = true, features = ["wayland"] } -calloop = { version = "0.10.5", optional = true } xkeysym = "0.2.0" +calloop = { version = "0.12.1", optional = true } +calloop-wayland-source = { version = "0.2.0", optional = true } + [features] default = ["calloop", "xkbcommon"] -calloop = ["dep:calloop", "wayland-client/calloop"] +calloop = ["dep:calloop", "calloop-wayland-source"] xkbcommon = ["dep:xkbcommon", "bytemuck", "pkg-config", "xkeysym/bytemuck"] [build-dependencies] diff --git a/examples/data_device.rs b/examples/data_device.rs index 0e65f6536..77491aeba 100644 --- a/examples/data_device.rs +++ b/examples/data_device.rs @@ -1,11 +1,13 @@ use std::{ convert::TryInto, - fs::File, + fs::{self, File}, io::{BufRead, BufReader, Write}, + os::unix::io::OwnedFd, time::Duration, }; -use calloop::{EventLoop, LoopHandle, RegistrationToken}; +use smithay_client_toolkit::reexports::calloop::{EventLoop, LoopHandle, RegistrationToken}; +use smithay_client_toolkit::reexports::calloop_wayland_source::WaylandSource; use smithay_client_toolkit::{ compositor::{CompositorHandler, CompositorState}, data_device_manager::{ @@ -43,7 +45,6 @@ use smithay_client_toolkit::{ Shm, ShmHandler, }, }; -use wayland_backend::io_lifetimes::OwnedFd; use wayland_client::{ globals::registry_queue_init, protocol::{ @@ -55,7 +56,7 @@ use wayland_client::{ wl_seat::{self, WlSeat}, wl_shm, wl_surface, }, - Connection, QueueHandle, WaylandSource, + Connection, QueueHandle, }; use wayland_protocols::wp::primary_selection::zv1::client::{ zwp_primary_selection_device_v1::ZwpPrimarySelectionDeviceV1, @@ -78,7 +79,7 @@ fn main() { let mut event_loop: EventLoop = EventLoop::try_new().expect("Failed to initialize the event loop!"); let loop_handle = event_loop.handle(); - WaylandSource::new(event_queue).unwrap().insert(loop_handle).unwrap(); + WaylandSource::new(conn.clone(), event_queue).insert(loop_handle).unwrap(); // The compositor (not to be confused with the server which is commonly called the compositor) allows // configuring surfaces to be presented. @@ -652,6 +653,8 @@ impl DataDeviceHandler for DataDeviceWindow { (o, d, Some(t)) => (o, d, t), _ => return, }; + // SAFETY: it's safe as long as we don't close the underlying file. + let f: &mut fs::File = unsafe { f.get_mut() }; let mut reader = BufReader::new(f); let consumed = match reader.fill_buf() { Ok(buf) => { @@ -727,6 +730,8 @@ impl DataDeviceHandler for DataDeviceWindow { (o, d, Some(t)) => (o, d, t), _ => return, }; + // SAFETY: it's safe as long as we don't close the underlying file. + let f: &mut fs::File = unsafe { f.get_mut() }; let mut reader = BufReader::new(f); let consumed = match reader.fill_buf() { Ok(buf) => { @@ -921,6 +926,8 @@ impl PrimarySelectionDeviceHandler for DataDeviceWindow { (o, d, Some(t)) => (o, d, t), _ => return, }; + // SAFETY: it's safe as long as we don't close the underlying file. + let f: &mut fs::File = unsafe { f.get_mut() }; let mut reader = BufReader::new(f); let consumed = match reader.fill_buf() { Ok(buf) => { diff --git a/examples/simple_window.rs b/examples/simple_window.rs index 58058efe2..369459f54 100644 --- a/examples/simple_window.rs +++ b/examples/simple_window.rs @@ -1,6 +1,7 @@ use std::{convert::TryInto, time::Duration}; -use calloop::{EventLoop, LoopHandle}; +use smithay_client_toolkit::reexports::calloop::{EventLoop, LoopHandle}; +use smithay_client_toolkit::reexports::calloop_wayland_source::WaylandSource; use smithay_client_toolkit::{ compositor::{CompositorHandler, CompositorState}, delegate_compositor, delegate_keyboard, delegate_output, delegate_pointer, delegate_registry, @@ -28,7 +29,7 @@ use smithay_client_toolkit::{ use wayland_client::{ globals::registry_queue_init, protocol::{wl_keyboard, wl_output, wl_pointer, wl_seat, wl_shm, wl_surface}, - Connection, QueueHandle, WaylandSource, + Connection, QueueHandle, }; fn main() { @@ -43,7 +44,7 @@ fn main() { let mut event_loop: EventLoop = EventLoop::try_new().expect("Failed to initialize the event loop!"); let loop_handle = event_loop.handle(); - WaylandSource::new(event_queue).unwrap().insert(loop_handle).unwrap(); + WaylandSource::new(conn.clone(), event_queue).insert(loop_handle).unwrap(); // The compositor (not to be confused with the server which is commonly called the compositor) allows // configuring surfaces to be presented. diff --git a/src/compositor.rs b/src/compositor.rs index a1428f3eb..7941dbeb1 100644 --- a/src/compositor.rs +++ b/src/compositor.rs @@ -1,4 +1,5 @@ use std::mem; +use std::os::unix::io::OwnedFd; use std::sync::MutexGuard; use std::sync::{ atomic::{AtomicI32, Ordering}, @@ -421,10 +422,7 @@ impl wayland_client::backend::ObjectData for RegionData { fn event( self: Arc, _: &wayland_client::backend::Backend, - _: wayland_client::backend::protocol::Message< - wayland_client::backend::ObjectId, - wayland_backend::io_lifetimes::OwnedFd, - >, + _: wayland_client::backend::protocol::Message, ) -> Option> { unreachable!("wl_region has no events"); } diff --git a/src/data_device_manager/data_offer.rs b/src/data_device_manager/data_offer.rs index 988746b70..7a3ef4f26 100644 --- a/src/data_device_manager/data_offer.rs +++ b/src/data_device_manager/data_offer.rs @@ -1,6 +1,6 @@ use std::{ ops::{Deref, DerefMut}, - os::unix::prelude::{FromRawFd, RawFd}, + os::unix::prelude::{BorrowedFd, FromRawFd, RawFd}, sync::{Arc, Mutex}, }; @@ -407,7 +407,7 @@ pub fn receive(offer: &WlDataOffer, mime_type: String) -> std::io::Result std::io::Result io::Result { - self.file.file.read(buf) + unsafe { self.file.get_mut().read(buf) } } } @@ -72,14 +71,14 @@ impl From for ReadPipe { #[cfg(feature = "calloop")] impl AsRawFd for ReadPipe { fn as_raw_fd(&self) -> RawFd { - self.file.file.as_raw_fd() + self.file.get_ref().as_raw_fd() } } #[cfg(feature = "calloop")] impl AsFd for ReadPipe { - fn as_fd(&self) -> wayland_backend::io_lifetimes::BorrowedFd<'_> { - self.file.file.as_fd() + fn as_fd(&self) -> BorrowedFd<'_> { + self.file.get_ref().as_fd() } } @@ -92,7 +91,7 @@ impl AsRawFd for ReadPipe { #[cfg(not(feature = "calloop"))] impl AsFd for ReadPipe { - fn as_fd(&self) -> wayland_backend::io_lifetimes::BorrowedFd<'_> { + fn as_fd(&self) -> BorrowedFd<'_> { self.file.as_fd() } } @@ -100,14 +99,14 @@ impl AsFd for ReadPipe { #[cfg(feature = "calloop")] impl IntoRawFd for ReadPipe { fn into_raw_fd(self) -> RawFd { - self.file.file.into_raw_fd() + self.file.unwrap().as_raw_fd() } } #[cfg(feature = "calloop")] impl From for OwnedFd { fn from(read_pipe: ReadPipe) -> Self { - read_pipe.file.file.into() + read_pipe.file.unwrap().into() } } @@ -129,7 +128,7 @@ impl From for OwnedFd { impl calloop::EventSource for ReadPipe { type Event = (); type Error = std::io::Error; - type Metadata = fs::File; + type Metadata = calloop::generic::NoIoDrop; type Ret = (); fn process_events( @@ -139,7 +138,7 @@ impl calloop::EventSource for ReadPipe { mut callback: F, ) -> std::io::Result where - F: FnMut((), &mut fs::File), + F: FnMut((), &mut calloop::generic::NoIoDrop), { self.file.process_events(readiness, token, |_, file| { callback((), file); diff --git a/src/data_device_manager/write_pipe.rs b/src/data_device_manager/write_pipe.rs index f332213df..c150f33c3 100644 --- a/src/data_device_manager/write_pipe.rs +++ b/src/data_device_manager/write_pipe.rs @@ -1,8 +1,7 @@ use std::{ fs, io, - os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}, + os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}, }; -use wayland_backend::io_lifetimes::{AsFd, OwnedFd}; /// If the `calloop` cargo feature is enabled, this can be used /// as an `EventSource` in a calloop event loop. @@ -18,11 +17,11 @@ pub struct WritePipe { #[cfg(feature = "calloop")] impl io::Write for WritePipe { fn write(&mut self, buf: &[u8]) -> io::Result { - self.file.file.write(buf) + unsafe { self.file.get_mut().write(buf) } } fn flush(&mut self) -> io::Result<()> { - self.file.file.flush() + unsafe { self.file.get_mut().flush() } } } @@ -80,14 +79,14 @@ impl From for WritePipe { #[cfg(feature = "calloop")] impl AsRawFd for WritePipe { fn as_raw_fd(&self) -> RawFd { - self.file.file.as_raw_fd() + self.file.get_ref().as_raw_fd() } } #[cfg(feature = "calloop")] impl AsFd for WritePipe { - fn as_fd(&self) -> wayland_backend::io_lifetimes::BorrowedFd<'_> { - self.file.file.as_fd() + fn as_fd(&self) -> BorrowedFd { + self.file.get_ref().as_fd() } } @@ -100,7 +99,7 @@ impl AsRawFd for WritePipe { #[cfg(not(feature = "calloop"))] impl AsFd for WritePipe { - fn as_fd(&self) -> wayland_backend::io_lifetimes::BorrowedFd<'_> { + fn as_fd(&self) -> BorrowedFd<'_> { self.file.as_fd() } } @@ -108,14 +107,14 @@ impl AsFd for WritePipe { #[cfg(feature = "calloop")] impl IntoRawFd for WritePipe { fn into_raw_fd(self) -> RawFd { - self.file.file.into_raw_fd() + self.file.unwrap().into_raw_fd() } } #[cfg(feature = "calloop")] impl From for OwnedFd { fn from(write_pipe: WritePipe) -> Self { - write_pipe.file.file.into() + write_pipe.file.unwrap().into() } } @@ -137,7 +136,7 @@ impl From for OwnedFd { impl calloop::EventSource for WritePipe { type Event = (); type Error = std::io::Error; - type Metadata = fs::File; + type Metadata = calloop::generic::NoIoDrop; type Ret = (); fn process_events( @@ -147,7 +146,7 @@ impl calloop::EventSource for WritePipe { mut callback: F, ) -> std::io::Result where - F: FnMut((), &mut fs::File), + F: FnMut((), &mut calloop::generic::NoIoDrop), { self.file.process_events(readiness, token, |_, file| { callback((), file); diff --git a/src/lib.rs b/src/lib.rs index 3818c02d9..6e2c944a4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,8 @@ pub mod reexports { #[cfg(feature = "calloop")] pub use calloop; + #[cfg(feature = "calloop")] + pub use calloop_wayland_source; pub use wayland_client as client; pub use wayland_csd_frame as csd_frame; pub use wayland_protocols as protocols; diff --git a/src/primary_selection/offer.rs b/src/primary_selection/offer.rs index c56dcf3b3..861625dbd 100644 --- a/src/primary_selection/offer.rs +++ b/src/primary_selection/offer.rs @@ -1,5 +1,5 @@ use std::{ - os::unix::io::{FromRawFd, RawFd}, + os::unix::io::{BorrowedFd, FromRawFd, RawFd}, sync::Mutex, }; @@ -41,7 +41,7 @@ impl PrimarySelectionOffer { // create a pipe let (readfd, writefd) = pipe2(OFlag::O_CLOEXEC)?; - self.offer.receive(mime_type, writefd); + self.offer.receive(mime_type, unsafe { BorrowedFd::borrow_raw(writefd) }); if let Err(err) = close(writefd) { log::warn!("Failed to close write pipe: {}", err); @@ -57,7 +57,7 @@ impl PrimarySelectionOffer { pub unsafe fn receive_to_fd(&self, mime_type: String, writefd: RawFd) { use nix::unistd::close; - self.offer.receive(mime_type, writefd); + self.offer.receive(mime_type, unsafe { BorrowedFd::borrow_raw(writefd) }); if let Err(err) = close(writefd) { log::warn!("Failed to close write pipe: {}", err); diff --git a/src/shell/wlr_layer/mod.rs b/src/shell/wlr_layer/mod.rs index 34f6c7f94..ea8c4b235 100644 --- a/src/shell/wlr_layer/mod.rs +++ b/src/shell/wlr_layer/mod.rs @@ -236,6 +236,7 @@ bitflags! { /// A combination of two orthogonal edges will cause the layer's anchor point to be the intersection of /// the edges. For example [`Anchor::TOP`] and [`Anchor::LEFT`] will result in an anchor point in the top /// left of the anchor rectangle. + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Anchor: u32 { /// Top edge of the anchor rectangle. const TOP = 1; diff --git a/src/shell/xdg/mod.rs b/src/shell/xdg/mod.rs index 77a2dd015..115b14a57 100644 --- a/src/shell/xdg/mod.rs +++ b/src/shell/xdg/mod.rs @@ -1,6 +1,7 @@ //! ## Cross desktop group (XDG) shell // TODO: Examples +use std::os::unix::io::OwnedFd; use std::sync::{Arc, Mutex}; use crate::reexports::client::globals::{BindError, GlobalList}; @@ -203,10 +204,7 @@ impl wayland_client::backend::ObjectData for PositionerData { fn event( self: Arc, _: &wayland_client::backend::Backend, - _: wayland_client::backend::protocol::Message< - wayland_client::backend::ObjectId, - wayland_backend::io_lifetimes::OwnedFd, - >, + _: wayland_client::backend::protocol::Message, ) -> Option> { unreachable!("xdg_positioner has no events"); } diff --git a/src/shm/multi.rs b/src/shm/multi.rs index c1f49b054..2e82c1aaa 100644 --- a/src/shm/multi.rs +++ b/src/shm/multi.rs @@ -65,6 +65,7 @@ use std::borrow::Borrow; use std::io; +use std::os::unix::io::OwnedFd; use std::sync::{ atomic::{AtomicBool, Ordering}, @@ -404,10 +405,7 @@ impl wayland_client::backend::ObjectData for BufferObjectData { fn event( self: Arc, _backend: &wayland_backend::client::Backend, - msg: wayland_backend::protocol::Message< - wayland_backend::client::ObjectId, - wayland_backend::io_lifetimes::OwnedFd, - >, + msg: wayland_backend::protocol::Message, ) -> Option> { debug_assert!(wayland_client::backend::protocol::same_interface( msg.sender_id.interface(), diff --git a/src/shm/raw.rs b/src/shm/raw.rs index df6c936be..a2e9b576e 100644 --- a/src/shm/raw.rs +++ b/src/shm/raw.rs @@ -6,7 +6,7 @@ use std::{ fs::File, io, - os::unix::prelude::{FromRawFd, RawFd}, + os::unix::prelude::{AsFd, FromRawFd, OwnedFd, RawFd}, sync::Arc, time::{SystemTime, UNIX_EPOCH}, }; @@ -53,7 +53,7 @@ impl RawPool { let pool = shm .send_constructor( - wl_shm::Request::CreatePool { fd: shm_fd, size: len as i32 }, + wl_shm::Request::CreatePool { fd: mem_file.as_fd(), size: len as i32 }, Arc::new(ShmPoolData), ) .unwrap_or_else(|_| Proxy::inert(shm.backend().clone())); @@ -272,10 +272,7 @@ impl ObjectData for ShmPoolData { fn event( self: Arc, _: &wayland_client::backend::Backend, - _: wayland_client::backend::protocol::Message< - wayland_client::backend::ObjectId, - wayland_backend::io_lifetimes::OwnedFd, - >, + _: wayland_client::backend::protocol::Message, ) -> Option> { unreachable!("wl_shm_pool has no events") } diff --git a/src/shm/slot.rs b/src/shm/slot.rs index 1bd638e40..d9cf5e422 100644 --- a/src/shm/slot.rs +++ b/src/shm/slot.rs @@ -2,7 +2,7 @@ use std::io; use std::{ - os::unix::io::AsRawFd, + os::unix::io::{AsRawFd, OwnedFd}, sync::{ atomic::{AtomicU8, AtomicUsize, Ordering}, Arc, Mutex, Weak, @@ -505,10 +505,7 @@ impl wayland_client::backend::ObjectData for BufferData { fn event( self: Arc, handle: &wayland_client::backend::Backend, - msg: wayland_backend::protocol::Message< - wayland_backend::client::ObjectId, - wayland_backend::io_lifetimes::OwnedFd, - >, + msg: wayland_backend::protocol::Message, ) -> Option> { debug_assert!(wayland_client::backend::protocol::same_interface( msg.sender_id.interface(),