From 383e91addfa927d85c96928f77c6a05203dcf9e6 Mon Sep 17 00:00:00 2001 From: Till Wegmueller Date: Sat, 4 Apr 2026 18:30:32 +0200 Subject: [PATCH] Split Wayland protocol handlers into dedicated modules Move handler trait impls and delegate macros from state.rs into handlers/{compositor,xdg_shell,input,output}.rs. Flesh out CompositorHandler::commit with on_commit_buffer_handler and XdgShellHandler::new_toplevel with window mapping. Add DataDeviceHandler, SelectionHandler, ClientDndGrabHandler, and ServerDndGrabHandler impls with DataDeviceState in the WayRay struct. State.rs now contains only the struct definition and constructor. --- crates/wrsrvd/src/handlers/compositor.rs | 65 +++++++++++ crates/wrsrvd/src/handlers/input.rs | 43 +++++++ crates/wrsrvd/src/handlers/mod.rs | 6 + crates/wrsrvd/src/handlers/output.rs | 18 +++ crates/wrsrvd/src/handlers/xdg_shell.rs | 43 +++++++ crates/wrsrvd/src/main.rs | 1 + crates/wrsrvd/src/state.rs | 138 ++--------------------- 7 files changed, 187 insertions(+), 127 deletions(-) create mode 100644 crates/wrsrvd/src/handlers/compositor.rs create mode 100644 crates/wrsrvd/src/handlers/input.rs create mode 100644 crates/wrsrvd/src/handlers/mod.rs create mode 100644 crates/wrsrvd/src/handlers/output.rs create mode 100644 crates/wrsrvd/src/handlers/xdg_shell.rs diff --git a/crates/wrsrvd/src/handlers/compositor.rs b/crates/wrsrvd/src/handlers/compositor.rs new file mode 100644 index 0000000..a3369ab --- /dev/null +++ b/crates/wrsrvd/src/handlers/compositor.rs @@ -0,0 +1,65 @@ +use smithay::{ + delegate_compositor, delegate_shm, + reexports::wayland_server::{ + Client, + protocol::wl_surface::WlSurface, + }, + wayland::{ + buffer::BufferHandler, + compositor::{CompositorClientState, CompositorHandler, CompositorState}, + shm::{ShmHandler, ShmState}, + }, +}; +use tracing::trace; + +use crate::state::WayRay; + +/// Per-client state required by Smithay's compositor subsystem. +/// +/// Must be stored in the client's `ClientData` so that `CompositorHandler` +/// can retrieve it. Implements `wayland_server::backend::ClientData`. +pub struct ClientState { + pub compositor_state: CompositorClientState, +} + +impl smithay::reexports::wayland_server::backend::ClientData for ClientState { + fn initialized(&self, _client_id: smithay::reexports::wayland_server::backend::ClientId) {} + fn disconnected( + &self, + _client_id: smithay::reexports::wayland_server::backend::ClientId, + _reason: smithay::reexports::wayland_server::backend::DisconnectReason, + ) { + } +} + +impl CompositorHandler for WayRay { + fn compositor_state(&mut self) -> &mut CompositorState { + &mut self.compositor_state + } + + fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { + &client.get_data::().unwrap().compositor_state + } + + fn commit(&mut self, surface: &WlSurface) { + trace!(?surface, "surface commit"); + smithay::backend::renderer::utils::on_commit_buffer_handler::(surface); + } +} + +impl BufferHandler for WayRay { + fn buffer_destroyed( + &mut self, + _buffer: &smithay::reexports::wayland_server::protocol::wl_buffer::WlBuffer, + ) { + } +} + +impl ShmHandler for WayRay { + fn shm_state(&self) -> &ShmState { + &self.shm_state + } +} + +delegate_compositor!(WayRay); +delegate_shm!(WayRay); diff --git a/crates/wrsrvd/src/handlers/input.rs b/crates/wrsrvd/src/handlers/input.rs new file mode 100644 index 0000000..b86082a --- /dev/null +++ b/crates/wrsrvd/src/handlers/input.rs @@ -0,0 +1,43 @@ +use smithay::{ + delegate_data_device, delegate_seat, + input::{Seat, SeatHandler, SeatState, pointer::CursorImageStatus}, + reexports::wayland_server::protocol::wl_surface::WlSurface, + wayland::selection::{ + SelectionHandler, + data_device::{ + ClientDndGrabHandler, DataDeviceHandler, DataDeviceState, ServerDndGrabHandler, + }, + }, +}; + +use crate::state::WayRay; + +impl SeatHandler for WayRay { + type KeyboardFocus = WlSurface; + type PointerFocus = WlSurface; + type TouchFocus = WlSurface; + + fn seat_state(&mut self) -> &mut SeatState { + &mut self.seat_state + } + + fn focus_changed(&mut self, _seat: &Seat, _focused: Option<&WlSurface>) {} + + fn cursor_image(&mut self, _seat: &Seat, _image: CursorImageStatus) {} +} + +impl SelectionHandler for WayRay { + type SelectionUserData = (); +} + +impl ClientDndGrabHandler for WayRay {} +impl ServerDndGrabHandler for WayRay {} + +impl DataDeviceHandler for WayRay { + fn data_device_state(&self) -> &DataDeviceState { + &self.data_device_state + } +} + +delegate_seat!(WayRay); +delegate_data_device!(WayRay); diff --git a/crates/wrsrvd/src/handlers/mod.rs b/crates/wrsrvd/src/handlers/mod.rs new file mode 100644 index 0000000..9455711 --- /dev/null +++ b/crates/wrsrvd/src/handlers/mod.rs @@ -0,0 +1,6 @@ +mod compositor; +mod input; +mod output; +mod xdg_shell; + +pub use compositor::ClientState; diff --git a/crates/wrsrvd/src/handlers/output.rs b/crates/wrsrvd/src/handlers/output.rs new file mode 100644 index 0000000..d8ce53d --- /dev/null +++ b/crates/wrsrvd/src/handlers/output.rs @@ -0,0 +1,18 @@ +use smithay::{ + delegate_output, + output::Output, + wayland::output::OutputHandler, +}; + +use crate::state::WayRay; + +impl OutputHandler for WayRay { + fn output_bound( + &mut self, + _output: Output, + _wl_output: smithay::reexports::wayland_server::protocol::wl_output::WlOutput, + ) { + } +} + +delegate_output!(WayRay); diff --git a/crates/wrsrvd/src/handlers/xdg_shell.rs b/crates/wrsrvd/src/handlers/xdg_shell.rs new file mode 100644 index 0000000..dab31d3 --- /dev/null +++ b/crates/wrsrvd/src/handlers/xdg_shell.rs @@ -0,0 +1,43 @@ +use smithay::{ + delegate_xdg_shell, + desktop::Window, + reexports::wayland_server::protocol::wl_seat, + utils::Serial, + wayland::shell::xdg::{ + PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, XdgShellState, + }, +}; +use tracing::info; + +use crate::state::WayRay; + +impl XdgShellHandler for WayRay { + fn xdg_shell_state(&mut self) -> &mut XdgShellState { + &mut self.xdg_shell_state + } + + fn new_toplevel(&mut self, surface: ToplevelSurface) { + let window = Window::new_wayland_window(surface); + self.space.map_element(window, (0, 0), false); + info!("new toplevel mapped"); + } + + fn new_popup(&mut self, _surface: PopupSurface, _positioner: PositionerState) { + // TODO: handle new popups + } + + fn grab(&mut self, _surface: PopupSurface, _seat: wl_seat::WlSeat, _serial: Serial) { + // TODO: handle popup grabs + } + + fn reposition_request( + &mut self, + _surface: PopupSurface, + _positioner: PositionerState, + _token: u32, + ) { + // TODO: handle popup reposition requests + } +} + +delegate_xdg_shell!(WayRay); diff --git a/crates/wrsrvd/src/main.rs b/crates/wrsrvd/src/main.rs index 34006c5..03fbe7f 100644 --- a/crates/wrsrvd/src/main.rs +++ b/crates/wrsrvd/src/main.rs @@ -1,4 +1,5 @@ mod errors; +mod handlers; mod state; use crate::state::WayRay; diff --git a/crates/wrsrvd/src/state.rs b/crates/wrsrvd/src/state.rs index 956d9c3..87c22bd 100644 --- a/crates/wrsrvd/src/state.rs +++ b/crates/wrsrvd/src/state.rs @@ -1,41 +1,18 @@ use smithay::{ - delegate_compositor, delegate_output, delegate_seat, delegate_shm, delegate_xdg_shell, desktop::Space, - input::{Seat, SeatHandler, SeatState, pointer::CursorImageStatus}, - output::Output, - reexports::wayland_server::{ - Display, DisplayHandle, Client, - protocol::{wl_seat, wl_surface::WlSurface}, - }, - utils::{Clock, Monotonic, Serial}, + input::{Seat, SeatState}, + reexports::wayland_server::{Display, DisplayHandle}, + utils::{Clock, Monotonic}, wayland::{ - buffer::BufferHandler, - compositor::{CompositorClientState, CompositorHandler, CompositorState}, - output::{OutputHandler, OutputManagerState}, - shell::xdg::{XdgShellHandler, XdgShellState, ToplevelSurface, PopupSurface, PositionerState}, - shm::{ShmHandler, ShmState}, + compositor::CompositorState, + output::OutputManagerState, + selection::data_device::DataDeviceState, + shell::xdg::XdgShellState, + shm::ShmState, }, }; use tracing::info; -/// Per-client state required by Smithay's compositor subsystem. -/// -/// Must be stored in the client's `ClientData` so that `CompositorHandler` -/// can retrieve it. Implements `wayland_server::backend::ClientData`. -pub struct ClientState { - pub compositor_state: CompositorClientState, -} - -impl smithay::reexports::wayland_server::backend::ClientData for ClientState { - fn initialized(&self, _client_id: smithay::reexports::wayland_server::backend::ClientId) {} - fn disconnected( - &self, - _client_id: smithay::reexports::wayland_server::backend::ClientId, - _reason: smithay::reexports::wayland_server::backend::DisconnectReason, - ) { - } -} - /// Central compositor state holding all Smithay subsystem states. /// /// This is the "god struct" pattern required by Smithay — a single type that @@ -47,6 +24,7 @@ pub struct WayRay { pub shm_state: ShmState, pub seat_state: SeatState, pub output_manager_state: OutputManagerState, + pub data_device_state: DataDeviceState, pub space: Space, pub seat: Seat, pub clock: Clock, @@ -60,6 +38,7 @@ impl WayRay { let compositor_state = CompositorState::new::(&dh); let xdg_shell_state = XdgShellState::new::(&dh); let shm_state = ShmState::new::(&dh, vec![]); + let data_device_state = DataDeviceState::new::(&dh); let mut seat_state = SeatState::new(); let seat = seat_state.new_wl_seat(&dh, "wayray"); @@ -75,105 +54,10 @@ impl WayRay { shm_state, seat_state, output_manager_state, + data_device_state, space: Space::default(), seat, clock: Clock::new(), } } } - -// --- Minimal handler trait impls required by delegate macros --- -// TODO: These will be expanded and moved to handlers/ in Task 4. - -impl CompositorHandler for WayRay { - fn compositor_state(&mut self) -> &mut CompositorState { - &mut self.compositor_state - } - - fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState { - &client.get_data::().unwrap().compositor_state - } - - fn commit(&mut self, _surface: &WlSurface) { - // TODO: handle surface commits (Task 4) - } -} - -impl XdgShellHandler for WayRay { - fn xdg_shell_state(&mut self) -> &mut XdgShellState { - &mut self.xdg_shell_state - } - - fn new_toplevel(&mut self, _surface: ToplevelSurface) { - // TODO: handle new toplevel windows (Task 4) - } - - fn new_popup(&mut self, _surface: PopupSurface, _positioner: PositionerState) { - // TODO: handle new popups (Task 4) - } - - fn grab(&mut self, _surface: PopupSurface, _seat: wl_seat::WlSeat, _serial: Serial) { - // TODO: handle popup grabs (Task 4) - } - - fn reposition_request( - &mut self, - _surface: PopupSurface, - _positioner: PositionerState, - _token: u32, - ) { - // TODO: handle popup reposition requests (Task 4) - } -} - -impl ShmHandler for WayRay { - fn shm_state(&self) -> &ShmState { - &self.shm_state - } -} - -impl BufferHandler for WayRay { - fn buffer_destroyed( - &mut self, - _buffer: &smithay::reexports::wayland_server::protocol::wl_buffer::WlBuffer, - ) { - // TODO: handle buffer destruction (Task 4) - } -} - -impl SeatHandler for WayRay { - type KeyboardFocus = WlSurface; - type PointerFocus = WlSurface; - type TouchFocus = WlSurface; - - fn seat_state(&mut self) -> &mut SeatState { - &mut self.seat_state - } - - fn focus_changed(&mut self, _seat: &Seat, _focused: Option<&WlSurface>) { - // TODO: handle focus changes (Task 4) - } - - fn cursor_image(&mut self, _seat: &Seat, _image: CursorImageStatus) { - // TODO: handle cursor image updates (Task 4) - } -} - -impl OutputHandler for WayRay { - fn output_bound( - &mut self, - _output: Output, - _wl_output: smithay::reexports::wayland_server::protocol::wl_output::WlOutput, - ) { - // TODO: handle output binding (Task 4) - } -} - -// --- Delegate macros wiring Smithay's Dispatch impls --- -// TODO: These will be moved to handlers/ in Task 4. - -delegate_compositor!(WayRay); -delegate_xdg_shell!(WayRay); -delegate_shm!(WayRay); -delegate_seat!(WayRay); -delegate_output!(WayRay);