From 0ebfc1153e8cc3af678be9e017899344ea59b6a2 Mon Sep 17 00:00:00 2001 From: Schmarni Date: Tue, 30 Sep 2025 22:32:09 +0200 Subject: [PATCH] chore(wayland): update waynest Signed-off-by: Schmarni --- Cargo.lock | 10 +-- Cargo.toml | 7 +- src/wayland/core/buffer.rs | 12 ++-- src/wayland/core/callback.rs | 2 +- src/wayland/core/compositor.rs | 10 +-- src/wayland/core/data_device.rs | 23 ++---- src/wayland/core/keyboard.rs | 6 +- src/wayland/core/output.rs | 2 +- src/wayland/core/pointer.rs | 3 +- src/wayland/core/seat.rs | 9 +-- src/wayland/core/shm.rs | 5 +- src/wayland/core/shm_pool.rs | 5 +- src/wayland/core/surface.rs | 5 +- src/wayland/core/touch.rs | 2 +- src/wayland/display.rs | 5 +- src/wayland/dmabuf/buffer_params.rs | 7 +- src/wayland/dmabuf/feedback.rs | 15 ++-- src/wayland/dmabuf/mod.rs | 7 +- src/wayland/mesa_drm.rs | 2 +- src/wayland/mod.rs | 104 ++++++++++++++++++++++++++-- src/wayland/presentation.rs | 7 +- src/wayland/registry.rs | 23 +++--- src/wayland/util.rs | 2 +- src/wayland/viewporter.rs | 7 +- src/wayland/xdg/popup.rs | 3 +- src/wayland/xdg/positioner.rs | 3 +- src/wayland/xdg/surface.rs | 7 +- src/wayland/xdg/toplevel.rs | 3 +- src/wayland/xdg/wm_base.rs | 7 +- 29 files changed, 204 insertions(+), 99 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec474d1..6092f6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5515,6 +5515,7 @@ dependencies = [ "dashmap", "directories", "drm-fourcc", + "futures-sink", "glam", "global_counter", "input-event-codes", @@ -5525,6 +5526,7 @@ dependencies = [ "nanoid", "openxr", "parking_lot 0.12.4", + "pin-project-lite", "rand 0.9.2", "rustc-hash 2.1.1", "rustix 1.1.2", @@ -6587,7 +6589,7 @@ dependencies = [ [[package]] name = "waynest" version = "0.1.0" -source = "git+https://github.com/verdiwm/waynest.git#cbbc19ed20ba5610fcc5577375d6b743d615da31" +source = "git+https://github.com/verdiwm/waynest.git#5169fdb3d96a09d0c65c2f73397f0576948b14a5" dependencies = [ "bytes", "futures-core", @@ -6601,7 +6603,7 @@ dependencies = [ [[package]] name = "waynest-macros" version = "0.1.0" -source = "git+https://github.com/verdiwm/waynest.git#cbbc19ed20ba5610fcc5577375d6b743d615da31" +source = "git+https://github.com/verdiwm/waynest.git#5169fdb3d96a09d0c65c2f73397f0576948b14a5" dependencies = [ "darling", "quote", @@ -6611,7 +6613,7 @@ dependencies = [ [[package]] name = "waynest-protocols" version = "0.1.0" -source = "git+https://github.com/verdiwm/waynest.git#cbbc19ed20ba5610fcc5577375d6b743d615da31" +source = "git+https://github.com/verdiwm/waynest.git#5169fdb3d96a09d0c65c2f73397f0576948b14a5" dependencies = [ "bitflags 2.9.4", "futures-core", @@ -6624,7 +6626,7 @@ dependencies = [ [[package]] name = "waynest-server" version = "0.1.0" -source = "git+https://github.com/verdiwm/waynest.git#cbbc19ed20ba5610fcc5577375d6b743d615da31" +source = "git+https://github.com/verdiwm/waynest.git#5169fdb3d96a09d0c65c2f73397f0576948b14a5" dependencies = [ "async-trait", "futures-core", diff --git a/Cargo.toml b/Cargo.toml index f0933fd..d739ec4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -141,7 +141,10 @@ openxr = "0.19" # linux stuffs input-event-codes = "6.2.0" -zbus = { version = "5.11.0", features = ["blocking-api", "tokio"], default-features = false } +zbus = { version = "5.11.0", features = [ + "blocking-api", + "tokio", +], default-features = false } directories = "6.0.0" xkbcommon-rs = "0.1.0" cosmic-text = "0.14.2" @@ -163,6 +166,8 @@ vulkano = { git = "https://github.com/Schmarni-Dev/vulkano", branch = "0_35_dmab wgpu-hal = { version = "24", optional = true, features = ["vulkan"] } ash = { version = "0.38.0", optional = true, default-features = false } rustix = { version = "1.0.8", features = ["time"] } +pin-project-lite = "0.2.16" +futures-sink = "0.3.31" [dependencies.stardust-xr] workspace = true diff --git a/src/wayland/core/buffer.rs b/src/wayland/core/buffer.rs index 3b4557a..07db45f 100644 --- a/src/wayland/core/buffer.rs +++ b/src/wayland/core/buffer.rs @@ -10,7 +10,7 @@ use mint::Vector2; use std::sync::Arc; use waynest::ObjectId; pub use waynest_protocols::server::core::wayland::wl_buffer::*; -use waynest_server::RequestDispatcher; +use waynest_server::{Client as _, RequestDispatcher}; #[derive(Debug)] pub struct BufferUsage { @@ -40,7 +40,7 @@ pub enum BufferBacking { } #[derive(Debug, RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Buffer { pub id: ObjectId, backing: BufferBacking, @@ -48,8 +48,12 @@ pub struct Buffer { impl Buffer { #[tracing::instrument(level = "debug", skip_all)] - pub fn new(client: &mut Client, id: ObjectId, backing: BufferBacking) -> Arc { - client.insert(id, Self { id, backing }) + pub fn new( + client: &mut Client, + id: ObjectId, + backing: BufferBacking, + ) -> WaylandResult> { + Ok(client.insert(id, Self { id, backing })?) } /// Returns the tex if it was updated diff --git a/src/wayland/core/callback.rs b/src/wayland/core/callback.rs index d347fb0..6adb951 100644 --- a/src/wayland/core/callback.rs +++ b/src/wayland/core/callback.rs @@ -3,7 +3,7 @@ pub use waynest_protocols::server::core::wayland::wl_callback::*; use waynest_server::RequestDispatcher; #[derive(Debug, RequestDispatcher, Clone)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Callback(pub ObjectId); /// https://wayland.app/protocols/wayland#wl_callback impl WlCallback for Callback { diff --git a/src/wayland/core/compositor.rs b/src/wayland/core/compositor.rs index cfec301..91ac8f4 100644 --- a/src/wayland/core/compositor.rs +++ b/src/wayland/core/compositor.rs @@ -4,10 +4,10 @@ use crate::wayland::{core::surface::Surface, util::ClientExt}; use waynest::ObjectId; use waynest_protocols::server::core::wayland::wl_surface::WlSurface; pub use waynest_protocols::server::core::wayland::{wl_compositor::*, wl_region::*}; -use waynest_server::RequestDispatcher; +use waynest_server::{Client as _, RequestDispatcher}; #[derive(Debug, waynest_server::RequestDispatcher, Default)] -#[waynest(error = WaylandError)] +#[waynest(error = WaylandError, connection = crate::wayland::Client)] pub struct Compositor; impl WlCompositor for Compositor { type Connection = crate::wayland::Client; @@ -19,7 +19,7 @@ impl WlCompositor for Compositor { _sender_id: ObjectId, id: ObjectId, ) -> WaylandResult<()> { - let surface = client.insert(id, Surface::new(client, id)); + let surface = client.insert(id, Surface::new(client, id))?; if let Some(output) = client.display().output.get() { surface.enter(client, id, output.id).await?; } @@ -35,13 +35,13 @@ impl WlCompositor for Compositor { _sender_id: ObjectId, id: ObjectId, ) -> WaylandResult<()> { - client.insert(id, Region { id }); + client.insert(id, Region { id })?; Ok(()) } } #[derive(Debug, RequestDispatcher)] -#[waynest(error = WaylandError)] +#[waynest(error = WaylandError, connection = crate::wayland::Client)] pub struct Region { id: ObjectId, } diff --git a/src/wayland/core/data_device.rs b/src/wayland/core/data_device.rs index 2bbdcf8..cd13c83 100644 --- a/src/wayland/core/data_device.rs +++ b/src/wayland/core/data_device.rs @@ -4,11 +4,12 @@ use waynest::ObjectId; use waynest_protocols::server::core::wayland::{ wl_data_device::*, wl_data_device_manager::*, wl_data_offer::WlDataOffer, wl_data_source::*, }; +use waynest_server::Client as _; // TODO: actually implement this #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct DataDeviceManager; impl WlDataDeviceManager for DataDeviceManager { type Connection = Client; @@ -19,7 +20,7 @@ impl WlDataDeviceManager for DataDeviceManager { _sender_id: ObjectId, id: ObjectId, ) -> WaylandResult<()> { - client.insert(id, DataSource { id }); + client.insert(id, DataSource { id })?; Ok(()) } @@ -30,29 +31,19 @@ impl WlDataDeviceManager for DataDeviceManager { id: ObjectId, _seat: ObjectId, ) -> WaylandResult<()> { - client.insert(id, DataDevice); + client.insert(id, DataDevice)?; Ok(()) } } #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct DataSource { id: ObjectId, } impl WlDataSource for DataSource { type Connection = Client; - async fn send( - &self, - _client: &mut Self::Connection, - _sender_id: ObjectId, - _mime_type: String, - _fd: OwnedFd, - ) -> WaylandResult<()> { - Ok(()) - } - async fn offer( &self, _client: &mut Self::Connection, @@ -82,7 +73,7 @@ impl WlDataSource for DataSource { } #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct DataDevice; impl WlDataDevice for DataDevice { type Connection = Client; @@ -119,7 +110,7 @@ impl WlDataDevice for DataDevice { } #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct DataOffer { id: ObjectId, } diff --git a/src/wayland/core/keyboard.rs b/src/wayland/core/keyboard.rs index e578610..0d46ddd 100644 --- a/src/wayland/core/keyboard.rs +++ b/src/wayland/core/keyboard.rs @@ -9,7 +9,7 @@ use std::{ collections::HashSet, io::Write, os::{ - fd::IntoRawFd, + fd::{AsFd, IntoRawFd}, unix::io::{FromRawFd, OwnedFd}, }, sync::{Arc, Weak}, @@ -68,7 +68,7 @@ impl ModifierState { } #[derive(waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Keyboard { pub id: ObjectId, focused_surface: Mutex>, @@ -103,7 +103,7 @@ impl Keyboard { client, self.id, KeymapFormat::XkbV1, - fd, + fd.as_fd(), keymap.len() as u32, ) .await?; diff --git a/src/wayland/core/output.rs b/src/wayland/core/output.rs index ff0f04d..9c12fd4 100644 --- a/src/wayland/core/output.rs +++ b/src/wayland/core/output.rs @@ -3,7 +3,7 @@ use waynest::ObjectId; pub use waynest_protocols::server::core::wayland::wl_output::*; #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Output { pub id: ObjectId, pub version: u32, diff --git a/src/wayland/core/pointer.rs b/src/wayland/core/pointer.rs index 8136625..debddf7 100644 --- a/src/wayland/core/pointer.rs +++ b/src/wayland/core/pointer.rs @@ -3,6 +3,7 @@ use crate::nodes::items::panel::Geometry; use crate::wayland::core::surface::Surface; use crate::wayland::{Client, WaylandResult}; use mint::Vector2; +use waynest_server::Client as _; use std::sync::Arc; use std::sync::Weak; use tokio::sync::Mutex; @@ -12,7 +13,7 @@ use waynest::ObjectId; pub use waynest_protocols::server::core::wayland::wl_pointer::*; #[derive(waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Pointer { pub id: ObjectId, version: u32, diff --git a/src/wayland/core/seat.rs b/src/wayland/core/seat.rs index 4c24c03..05bf30a 100644 --- a/src/wayland/core/seat.rs +++ b/src/wayland/core/seat.rs @@ -2,6 +2,7 @@ use crate::wayland::Client; use crate::wayland::WaylandResult; use crate::wayland::core::{keyboard::Keyboard, pointer::Pointer, surface::Surface, touch::Touch}; use mint::Vector2; +use waynest_server::Client as _; use std::sync::Arc; use std::sync::OnceLock; use waynest::ObjectId; @@ -45,7 +46,7 @@ pub enum SeatMessage { } #[derive(Default, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Seat { version: u32, pointer: OnceLock>, @@ -171,7 +172,7 @@ impl WlSeat for Seat { _sender_id: ObjectId, id: ObjectId, ) -> WaylandResult<()> { - let pointer = client.insert(id, Pointer::new(id, self.version)); + let pointer = client.insert(id, Pointer::new(id, self.version))?; let _ = self.pointer.set(pointer); Ok(()) } @@ -184,7 +185,7 @@ impl WlSeat for Seat { id: ObjectId, ) -> WaylandResult<()> { tracing::info!("Getting keyboard"); - let keyboard = client.insert(id, Keyboard::new(id)); + let keyboard = client.insert(id, Keyboard::new(id))?; let _ = self.keyboard.set(keyboard); Ok(()) } @@ -196,7 +197,7 @@ impl WlSeat for Seat { _sender_id: ObjectId, id: ObjectId, ) -> WaylandResult<()> { - let touch = client.insert(id, Touch(id)); + let touch = client.insert(id, Touch(id))?; let _ = self.touch.set(touch); Ok(()) } diff --git a/src/wayland/core/shm.rs b/src/wayland/core/shm.rs index e029efa..6a7ba1c 100644 --- a/src/wayland/core/shm.rs +++ b/src/wayland/core/shm.rs @@ -2,9 +2,10 @@ use crate::wayland::{Client, WaylandResult, core::shm_pool::ShmPool}; use std::os::fd::OwnedFd; use waynest::ObjectId; pub use waynest_protocols::server::core::wayland::wl_shm::*; +use waynest_server::Client as _; #[derive(Debug, waynest_server::RequestDispatcher, Default)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Shm; impl Shm { pub async fn advertise_formats( @@ -30,7 +31,7 @@ impl WlShm for Shm { fd: OwnedFd, size: i32, ) -> WaylandResult<()> { - client.insert(pool_id, ShmPool::new(fd, size, pool_id)?); + client.insert(pool_id, ShmPool::new(fd, size, pool_id)?)?; Ok(()) } diff --git a/src/wayland/core/shm_pool.rs b/src/wayland/core/shm_pool.rs index 03d4a81..dcdf6ff 100644 --- a/src/wayland/core/shm_pool.rs +++ b/src/wayland/core/shm_pool.rs @@ -5,13 +5,14 @@ use crate::wayland::{ }; use memmap2::{MmapOptions, RemapOptions}; use parking_lot::{Mutex, MutexGuard, RawMutex, lock_api::MappedMutexGuard}; +use waynest_server::Client as _; use std::os::fd::{IntoRawFd, OwnedFd}; use waynest::ObjectId; use waynest_protocols::server::core::wayland::wl_shm::Format; pub use waynest_protocols::server::core::wayland::wl_shm_pool::*; #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct ShmPool { inner: Mutex, id: ObjectId, @@ -62,7 +63,7 @@ impl WlShmPool for ShmPool { format, ); - Buffer::new(client, id, BufferBacking::Shm(params)); + Buffer::new(client, id, BufferBacking::Shm(params))?; Ok(()) } diff --git a/src/wayland/core/surface.rs b/src/wayland/core/surface.rs index ba4e227..d5cc3f9 100644 --- a/src/wayland/core/surface.rs +++ b/src/wayland/core/surface.rs @@ -22,6 +22,7 @@ use bevy::{ use bevy_dmabuf::import::ImportedDmatexs; use mint::Vector2; use parking_lot::Mutex; +use waynest_server::Client as _; use std::{ fmt::Display, sync::{Arc, OnceLock, Weak}, @@ -90,7 +91,7 @@ impl SurfaceState { // if returning false, don't run this callback again... just remove it pub type OnCommitCallback = Box bool + Send + Sync>; #[derive(waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Surface { pub id: ObjectId, pub surface_id: OnceLock, @@ -376,7 +377,7 @@ impl WlSurface for Surface { _sender_id: ObjectId, callback_id: ObjectId, ) -> WaylandResult<()> { - let callback = client.insert(callback_id, Callback(callback_id)); + let callback = client.insert(callback_id, Callback(callback_id))?; self.state.lock().pending.frame_callbacks.push(callback); Ok(()) } diff --git a/src/wayland/core/touch.rs b/src/wayland/core/touch.rs index a8bd9e5..377fe1e 100644 --- a/src/wayland/core/touch.rs +++ b/src/wayland/core/touch.rs @@ -5,7 +5,7 @@ use waynest::ObjectId; pub use waynest_protocols::server::core::wayland::wl_touch::*; #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Touch(pub ObjectId); impl Touch { pub async fn handle_touch_down( diff --git a/src/wayland/display.rs b/src/wayland/display.rs index b8c8340..f924e1c 100644 --- a/src/wayland/display.rs +++ b/src/wayland/display.rs @@ -10,6 +10,7 @@ use crate::wayland::{ registry::Registry, }; use global_counter::primitive::exact::CounterU32; +use waynest_server::Client as _; use std::{ sync::{Arc, OnceLock}, time::Instant, @@ -18,7 +19,7 @@ use waynest::ObjectId; pub use waynest_protocols::server::core::wayland::wl_display::*; #[derive(waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Display { pub message_sink: MessageSink, pub pid: Option, @@ -69,7 +70,7 @@ impl WlDisplay for Display { _sender_id: ObjectId, registry_id: ObjectId, ) -> WaylandResult<()> { - let registry = client.insert(registry_id, Registry); + let registry = client.insert(registry_id, Registry)?; registry.advertise_globals(client, registry_id).await?; diff --git a/src/wayland/dmabuf/buffer_params.rs b/src/wayland/dmabuf/buffer_params.rs index 824782e..249d035 100644 --- a/src/wayland/dmabuf/buffer_params.rs +++ b/src/wayland/dmabuf/buffer_params.rs @@ -8,6 +8,7 @@ use bevy_dmabuf::dmatex::DmatexPlane; use drm_fourcc::DrmFourcc; use parking_lot::Mutex; use rustc_hash::FxHashMap; +use waynest_server::Client as _; use std::os::fd::{AsRawFd, OwnedFd}; use waynest::ObjectId; use waynest_protocols::server::stable::linux_dmabuf_v1::zwp_linux_buffer_params_v1::{ @@ -20,7 +21,7 @@ use waynest_protocols::server::stable::linux_dmabuf_v1::zwp_linux_buffer_params_ /// that together form a single logical buffer. The object may eventually /// create one wl_buffer unless cancelled by destroying it. #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct BufferParams { pub id: ObjectId, pub(super) planes: Mutex>, @@ -120,7 +121,7 @@ impl ZwpLinuxBufferParamsV1 for BufferParams { }); match buffer { - Ok(buffer) => self.created(client, self.id, buffer.id).await, + Ok(buffer) => self.created(client, self.id, buffer?.id).await, Err(_) => { client.remove(self.id); self.failed(client, self.id).await @@ -148,7 +149,7 @@ impl ZwpLinuxBufferParamsV1 for BufferParams { flags, ) { Ok(backing) => { - Buffer::new(client, buffer_id, BufferBacking::Dmabuf(backing)); + Buffer::new(client, buffer_id, BufferBacking::Dmabuf(backing))?; } Err(e) => { tracing::error!("Failed to import dmabuf because {e}"); diff --git a/src/wayland/dmabuf/feedback.rs b/src/wayland/dmabuf/feedback.rs index 63d58e5..9d64ac3 100644 --- a/src/wayland/dmabuf/feedback.rs +++ b/src/wayland/dmabuf/feedback.rs @@ -3,7 +3,7 @@ use crate::wayland::{Client, WaylandResult, vulkano_data::VULKANO_CONTEXT}; use memfd::MemfdOptions; use std::{ io::Write, - os::fd::{FromRawFd, IntoRawFd, OwnedFd}, + os::fd::{AsFd as _, FromRawFd, IntoRawFd, OwnedFd}, sync::Arc, }; use waynest::ObjectId; @@ -12,7 +12,7 @@ use waynest_protocols::server::stable::linux_dmabuf_v1::zwp_linux_dmabuf_feedbac }; #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct DmabufFeedback(pub Arc); impl DmabufFeedback { #[tracing::instrument(level = "debug", skip_all)] @@ -81,14 +81,9 @@ impl DmabufFeedback { mfd.as_file().write_all(&0_u32.to_ne_bytes())?; mfd.as_file().write_all(&modifier.to_ne_bytes())?; } - - self.format_table( - client, - sender_id, - unsafe { OwnedFd::from_raw_fd(mfd.into_raw_fd()) }, - size, - ) - .await?; + let fd = unsafe { OwnedFd::from_raw_fd(mfd.into_raw_fd()) }; + self.format_table(client, sender_id, fd.as_fd(), size) + .await?; Ok(()) } } diff --git a/src/wayland/dmabuf/mod.rs b/src/wayland/dmabuf/mod.rs index 83f0ede..cfa9553 100644 --- a/src/wayland/dmabuf/mod.rs +++ b/src/wayland/dmabuf/mod.rs @@ -15,6 +15,7 @@ use buffer_params::BufferParams; use drm_fourcc::DrmFourcc; use feedback::DmabufFeedback; use rustc_hash::FxHashSet; +use waynest_server::Client as _; use std::sync::LazyLock; use vulkano::format::FormatFeatures; use waynest::ObjectId; @@ -74,7 +75,7 @@ pub static DMABUF_FORMATS: LazyLock> = LazyLock::new(|| { /// - Proper lifetime management of dmabuf file descriptors /// - Safe handling of buffer attachments #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Dmabuf { // Track supported formats and modifiers // formats: Mutex>, @@ -138,7 +139,7 @@ impl ZwpLinuxDmabufV1 for Dmabuf { params_id: ObjectId, ) -> WaylandResult<()> { // Create new buffer parameters object - let params = client.insert(params_id, BufferParams::new(params_id)); + let params = client.insert(params_id, BufferParams::new(params_id))?; self.active_params.add_raw(¶ms); Ok(()) } @@ -157,7 +158,7 @@ impl ZwpLinuxDmabufV1 for Dmabuf { }); } // Create feedback object for default (non-surface-specific) settings - let feedback = client.insert(id, DmabufFeedback(client.get::(sender_id).unwrap())); + let feedback = client.insert(id, DmabufFeedback(client.get::(sender_id).unwrap()))?; feedback.send_params(client, id).await?; Ok(()) } diff --git a/src/wayland/mesa_drm.rs b/src/wayland/mesa_drm.rs index 506a52d..463e16a 100644 --- a/src/wayland/mesa_drm.rs +++ b/src/wayland/mesa_drm.rs @@ -11,7 +11,7 @@ use waynest::ObjectId; use waynest_protocols::server::mesa::drm::wl_drm::*; #[derive(Debug, waynest_server::RequestDispatcher, Default)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct MesaDrm { version: u32, } diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index 2992afa..9313f22 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -32,6 +32,7 @@ use core::buffer::BufferUsage; use core::{buffer::Buffer, callback::Callback, surface::WL_SURFACE_REGISTRY}; use display::Display; use mint::Vector2; +use pin_project_lite::pin_project; use std::fs::File; use std::io::ErrorKind; use std::mem::MaybeUninit; @@ -42,12 +43,13 @@ use std::{ sync::{Arc, OnceLock}, }; use tokio::{net::UnixStream, sync::mpsc, task::AbortHandle}; -use tokio_stream::StreamExt; +use tokio_stream::{Stream, StreamExt}; use tracing::{debug_span, instrument}; use vulkano_data::setup_vulkano_context; -use waynest::ObjectId; +use waynest::{Connection, Socket}; +use waynest::{ObjectId, ProtocolError}; use waynest_protocols::server::core::wayland::wl_display::WlDisplay; -use waynest_server::{Connection, Listener}; +use waynest_server::{Client as _, Listener, Store, StoreError}; use xdg::toplevel::Toplevel; pub static WAYLAND_DISPLAY: OnceLock = OnceLock::new(); @@ -76,6 +78,97 @@ pub enum WaylandError { DmabufImport(#[from] bevy_dmabuf::import::ImportError), #[error("Server error: {0}")] Server(#[from] ServerError), + #[error("Failed to Insert Object")] + FailedToInsertObject, +} +impl From> for WaylandError { + fn from(_value: StoreError) -> Self { + Self::FailedToInsertObject + } +} + +pin_project! { + pub struct Client { + store: Store, + #[pin] + connection: Socket, + next_event_serial: u32, + } +} +impl Connection for Client { + type Error = WaylandError; + + fn fd(&mut self) -> Result::Error> { + Ok(self.connection.fd()?) + } +} +impl Stream for Client { + type Item = ::Item; + + fn poll_next( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + // ::poll_next(self.project().connection, cx) + self.project().connection.poll_next(cx) + } +} +impl futures_sink::Sink for Client { + type Error = ProtocolError; + + fn poll_ready( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.project().connection.poll_ready(cx) + } + + fn start_send( + self: std::pin::Pin<&mut Self>, + item: waynest::Message, + ) -> Result<(), Self::Error> { + self.project().connection.start_send(item) + } + + fn poll_flush( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.project().connection.poll_flush(cx) + } + + fn poll_close( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.project().connection.poll_close(cx) + } +} +impl Client { + fn new(unix_stream: UnixStream) -> tokio::io::Result { + Ok(Self { + store: Store::new(), + connection: Socket::new(unix_stream.into_std()?)?, + next_event_serial: 0, + }) + } + pub fn next_event_serial(&mut self) -> u32 { + let prev = self.next_event_serial; + self.next_event_serial = self.next_event_serial.wrapping_add(1); + prev + } +} + +impl waynest_server::Client for Client { + type Store = Store; + + fn store(&self) -> &Self::Store { + &self.store + } + + fn store_mut(&mut self) -> &mut Self::Store { + &mut self.store + } } pub fn get_free_wayland_socket_path() -> Option<(PathBuf, File)> { @@ -116,7 +209,6 @@ pub fn get_free_wayland_socket_path() -> Option<(PathBuf, File)> { } pub type WaylandResult = std::result::Result; -pub type Client = waynest_server::Connection; pub enum Message { Frame(Vec>), @@ -148,10 +240,10 @@ struct WaylandClient { impl WaylandClient { pub fn from_stream(socket: UnixStream) -> WaylandResult { let pid = socket.peer_cred().ok().and_then(|c| c.pid()); - let mut client = Connection::new(socket)?; + let mut client = Client::new(socket)?; let (message_sink, message_source) = mpsc::unbounded_channel(); - client.insert(ObjectId::DISPLAY, Display::new(message_sink, pid)); + client.insert(ObjectId::DISPLAY, Display::new(message_sink, pid))?; let abort_handle = tokio::task::spawn(Self::dispatch_loop(client, message_source)).abort_handle(); diff --git a/src/wayland/presentation.rs b/src/wayland/presentation.rs index 17b2e2b..63247fc 100644 --- a/src/wayland/presentation.rs +++ b/src/wayland/presentation.rs @@ -5,6 +5,7 @@ use waynest::ObjectId; use waynest_protocols::server::stable::presentation_time::{ wp_presentation::*, wp_presentation_feedback::*, }; +use waynest_server::Client as _; #[derive(Clone, Copy, Debug)] pub struct MonotonicTimestamp { @@ -33,7 +34,7 @@ impl From for MonotonicTimestamp { } #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Presentation { id: ObjectId, } @@ -65,7 +66,7 @@ impl WpPresentation for Presentation { tracing::error!("unable to get surface#{surface}"); return Ok(()); }; - let feedback = client.insert(id, PresentationFeedback(id)); + let feedback = client.insert(id, PresentationFeedback(id))?; surface.add_presentation_feedback(feedback); Ok(()) @@ -73,7 +74,7 @@ impl WpPresentation for Presentation { } #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct PresentationFeedback(pub ObjectId); impl WpPresentationFeedback for PresentationFeedback { type Connection = crate::wayland::Client; diff --git a/src/wayland/registry.rs b/src/wayland/registry.rs index c609ca2..b81f103 100644 --- a/src/wayland/registry.rs +++ b/src/wayland/registry.rs @@ -25,6 +25,7 @@ use waynest_protocols::server::{ viewporter::wp_viewporter::WpViewporter, }, }; +use waynest_server::Client as _; struct RegistryGlobals; impl RegistryGlobals { @@ -41,7 +42,7 @@ impl RegistryGlobals { } #[derive(Debug, waynest_server::RequestDispatcher, Default)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Registry; impl Registry { @@ -157,11 +158,11 @@ impl WlRegistry for Registry { match name { RegistryGlobals::COMPOSITOR => { tracing::info!("Binding compositor"); - client.insert(new_id.object_id, Compositor); + client.insert(new_id.object_id, Compositor)?; } RegistryGlobals::SHM => { tracing::info!("Binding SHM"); - let shm = client.insert(new_id.object_id, Shm); + let shm = client.insert(new_id.object_id, Shm)?; shm.advertise_formats(client, new_id.object_id).await?; } RegistryGlobals::WM_BASE => { @@ -169,19 +170,19 @@ impl WlRegistry for Registry { client.insert( new_id.object_id, WmBase::new(new_id.object_id, new_id.version), - ); + )?; } RegistryGlobals::SEAT => { tracing::info!("Binding seat with id {}", new_id.object_id); let seat = Seat::new(client, new_id.object_id, new_id.version).await?; - let seat = client.insert(new_id.object_id, seat); + let seat = client.insert(new_id.object_id, seat)?; let _ = client.display().seat.set(seat.clone()); tracing::info!("Seat capabilities advertised"); } RegistryGlobals::DATA_DEVICE_MANAGER => { tracing::info!("Binding data device manager"); - client.insert(new_id.object_id, DataDeviceManager); + client.insert(new_id.object_id, DataDeviceManager)?; } RegistryGlobals::OUTPUT => { tracing::info!("Binding output"); @@ -191,7 +192,7 @@ impl WlRegistry for Registry { id: new_id.object_id, version: new_id.version, }, - ); + )?; let _ = client.display().output.set(output.clone()); output.advertise_outputs(client).await?; } @@ -199,23 +200,23 @@ impl WlRegistry for Registry { tracing::info!("Binding dmabuf"); let dmabuf = Dmabuf::new(client, new_id.object_id, new_id.version).await?; - client.insert(new_id.object_id, dmabuf); + client.insert(new_id.object_id, dmabuf)?; } RegistryGlobals::WL_DRM => { tracing::info!("Binding wl_drm"); let drm = MesaDrm::new(client, new_id.object_id, new_id.version).await?; - client.insert(new_id.object_id, drm); + client.insert(new_id.object_id, drm)?; } RegistryGlobals::PRESENTATION => { tracing::info!("Binding wp_presentation"); - client.insert(new_id.object_id, Presentation::new(new_id.object_id)); + client.insert(new_id.object_id, Presentation::new(new_id.object_id))?; } RegistryGlobals::VIEWPORTER => { tracing::info!("Binding wp_viewporter"); - client.insert(new_id.object_id, Viewporter::new(new_id.object_id)); + client.insert(new_id.object_id, Viewporter::new(new_id.object_id))?; } id => { tracing::error!(id, "Wayland: failed to bind to registry global"); diff --git a/src/wayland/util.rs b/src/wayland/util.rs index 3b1815d..a2711b0 100644 --- a/src/wayland/util.rs +++ b/src/wayland/util.rs @@ -5,7 +5,7 @@ use crate::wayland::{Client, WaylandError, WaylandResult}; use std::{fmt::Debug, sync::Arc}; use waynest::ObjectId; use waynest_protocols::server::core::wayland::wl_display::WlDisplay; -use waynest_server::RequestDispatcher; +use waynest_server::{Client as _, RequestDispatcher}; pub trait ClientExt { fn message_sink(&self) -> MessageSink; diff --git a/src/wayland/viewporter.rs b/src/wayland/viewporter.rs index 2b44d9f..bbfc7bd 100644 --- a/src/wayland/viewporter.rs +++ b/src/wayland/viewporter.rs @@ -3,11 +3,12 @@ use waynest::Fixed; use waynest::ObjectId; pub use waynest_protocols::server::stable::viewporter::wp_viewport::*; pub use waynest_protocols::server::stable::viewporter::wp_viewporter::*; +use waynest_server::Client as _; // This is a barebones/stub no-op implementation of wp_viewporter to make xwayland apps work #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Viewporter { id: ObjectId, } @@ -38,13 +39,13 @@ impl WpViewporter for Viewporter { surface_id: ObjectId, ) -> WaylandResult<()> { let viewport = Viewport::new(id, surface_id); - client.insert(id, viewport); + client.insert(id, viewport)?; Ok(()) } } #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Viewport { id: ObjectId, _surface_id: ObjectId, diff --git a/src/wayland/xdg/popup.rs b/src/wayland/xdg/popup.rs index 9b5a3e8..054cbf7 100644 --- a/src/wayland/xdg/popup.rs +++ b/src/wayland/xdg/popup.rs @@ -6,12 +6,13 @@ use crate::nodes::items::panel::SurfaceId; use crate::wayland::WaylandResult; use parking_lot::Mutex; use rand::Rng; +use waynest_server::Client as _; use std::sync::Arc; use waynest::ObjectId; use waynest_protocols::server::stable::xdg_shell::xdg_popup::XdgPopup; #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Popup { version: u32, pub surface: Arc, diff --git a/src/wayland/xdg/positioner.rs b/src/wayland/xdg/positioner.rs index 6cccd47..f36ec08 100644 --- a/src/wayland/xdg/positioner.rs +++ b/src/wayland/xdg/positioner.rs @@ -3,6 +3,7 @@ use mint::Vector2; use parking_lot::Mutex; use waynest::ObjectId; use waynest_protocols::server::stable::xdg_shell::xdg_positioner::*; +use waynest_server::Client as _; #[derive(Debug, Clone, Copy)] pub struct PositionerData { @@ -127,7 +128,7 @@ impl Default for PositionerData { } #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Positioner { data: Mutex, id: ObjectId, diff --git a/src/wayland/xdg/surface.rs b/src/wayland/xdg/surface.rs index 4fb5b39..6527e64 100644 --- a/src/wayland/xdg/surface.rs +++ b/src/wayland/xdg/surface.rs @@ -9,9 +9,10 @@ use std::sync::Arc; use waynest::ObjectId; use waynest_protocols::server::stable::xdg_shell::xdg_popup::XdgPopup; pub use waynest_protocols::server::stable::xdg_shell::xdg_surface::*; +use waynest_server::Client as _; #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Surface { id: ObjectId, version: u32, @@ -65,7 +66,7 @@ impl XdgSurface for Surface { self.wl_surface.clone(), client.get::(sender_id).unwrap(), ), - ); + )?; self.wl_surface .try_set_role(SurfaceRole::XdgToplevel, Error::AlreadyConstructed) @@ -139,7 +140,7 @@ impl XdgSurface for Surface { let popup = client.insert( popup_id, Popup::new(self.version, surface, &positioner, popup_id), - ); + )?; let positioner_geometry = positioner.data().infinite_geometry(); diff --git a/src/wayland/xdg/toplevel.rs b/src/wayland/xdg/toplevel.rs index 3d5a858..ce30284 100644 --- a/src/wayland/xdg/toplevel.rs +++ b/src/wayland/xdg/toplevel.rs @@ -11,6 +11,7 @@ use crate::{ }; use mint::Vector2; use parking_lot::Mutex; +use waynest_server::Client as _; use std::sync::Arc; use waynest::ObjectId; pub use waynest_protocols::server::stable::xdg_shell::xdg_toplevel::*; @@ -55,7 +56,7 @@ impl Default for ToplevelData { } #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct Toplevel { pub id: ObjectId, xdg_surface: Arc, diff --git a/src/wayland/xdg/wm_base.rs b/src/wayland/xdg/wm_base.rs index 62178f7..a0fdbc1 100644 --- a/src/wayland/xdg/wm_base.rs +++ b/src/wayland/xdg/wm_base.rs @@ -3,9 +3,10 @@ use crate::wayland::{WaylandError, WaylandResult, util::ClientExt, xdg::surface: use waynest::ObjectId; pub use waynest_protocols::server::stable::xdg_shell::xdg_wm_base::*; +use waynest_server::Client as _; #[derive(Debug, waynest_server::RequestDispatcher)] -#[waynest(error = crate::wayland::WaylandError)] +#[waynest(error = crate::wayland::WaylandError, connection = crate::wayland::Client)] pub struct WmBase { version: u32, id: ObjectId, @@ -33,7 +34,7 @@ impl XdgWmBase for WmBase { _sender_id: ObjectId, id: ObjectId, ) -> WaylandResult<()> { - client.insert(id, Positioner::new(id)); + client.insert(id, Positioner::new(id))?; Ok(()) } @@ -56,7 +57,7 @@ impl XdgWmBase for WmBase { } }; let xdg_surface = Surface::new(xdg_surface_id, self.version, wl_surface); - client.insert(xdg_surface_id, xdg_surface); + client.insert(xdg_surface_id, xdg_surface)?; Ok(()) }