From cbabd591a30d4436ee4bb044c2100275dbc94fc2 Mon Sep 17 00:00:00 2001 From: En-En <39373446+En-En-Code@users.noreply.github.com> Date: Tue, 5 Aug 2025 15:31:37 +0000 Subject: [PATCH] server: impl Deref(Mut) for ServerState to Inner coercion --- src/lib.rs | 9 +- src/server/event.rs | 100 ++++++++----------- src/server/mod.rs | 237 +++++++++++++------------------------------- src/server/tests.rs | 15 ++- 4 files changed, 121 insertions(+), 240 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 055c26f..82bd0ab 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,7 @@ mod server; pub mod xstate; -use crate::server::{EarlyConnection, PendingSurfaceState, ServerState}; +use crate::server::{NoConnection, PendingSurfaceState, ServerState}; use crate::xstate::{RealConnection, XState}; use log::{error, info}; use rustix::event::{poll, PollFd, PollFlags}; @@ -29,7 +29,7 @@ pub trait X11Selection { fn write_to(&self, mime: &str, pipe: WritePipe); } -type EarlyServerState = ServerState::X11Selection>>; +type EarlyServerState = ServerState::X11Selection>>; type RealServerState = ServerState; pub trait RunData { @@ -63,6 +63,7 @@ pub fn main(mut data: impl RunData) -> Option<()> { // FFI level, see (`XState::new`), `xsock_wl`'s destructor also closes the FD, leading the FD // being closed twice. This mainly caused problems in the integration tests, where `xsock_wl`'s // destructor would be run after the descriptor was freed, leading to an opaque abort message. + // See https://github.com/rust-x-bindings/rust-xcb/issues/282 for further explanation. let xsock_wl = Box::leak(Box::new(xsock_wl)); // Prevent creation of new Xwayland command from closing fd rustix::io::fcntl_setfd(&xsock_xwl, rustix::io::FdFlags::empty()).unwrap(); @@ -176,7 +177,7 @@ pub fn main(mut data: impl RunData) -> Option<()> { Err(other) => panic!("Poll failed: {other:?}"), } - display.dispatch_clients(server_state.inner_mut()).unwrap(); + display.dispatch_clients(&mut *server_state).unwrap(); server_state.run(); display.flush_clients().unwrap(); } @@ -207,7 +208,7 @@ pub fn main(mut data: impl RunData) -> Option<()> { loop { xstate.handle_events(&mut server_state); - display.dispatch_clients(server_state.inner_mut()).unwrap(); + display.dispatch_clients(&mut *server_state).unwrap(); server_state.run(); display.flush_clients().unwrap(); diff --git a/src/server/event.rs b/src/server/event.rs index 946ca9e..090cd6e 100644 --- a/src/server/event.rs +++ b/src/server/event.rs @@ -88,7 +88,8 @@ impl Event for SurfaceEvents { SurfaceEvents::Popup(event) => Self::popup_event(event, target, state), SurfaceEvents::FractionalScale(event) => match event { wp_fractional_scale_v1::Event::PreferredScale { scale } => { - let entity = state.inner.world.entity(target).unwrap(); + let state = state.deref_mut(); + let entity = state.world.entity(target).unwrap(); let factor = scale as f64 / 120.0; debug!( "{} scale factor: {}", @@ -100,14 +101,14 @@ impl Event for SurfaceEvents { if let Some(OnOutput(output)) = entity.get::<&OnOutput>().as_deref().copied() { if update_output_scale( - state.inner.world.query_one(output).unwrap(), + state.world.query_one(output).unwrap(), OutputScaleFactor::Fractional(factor), ) { - state.inner.updated_outputs.push(output); + state.updated_outputs.push(output); } } if entity.has::() { - update_surface_viewport(state.inner.world.query_one(target).unwrap()); + update_surface_viewport(state.world.query_one(target).unwrap()); } } _ => unreachable!(), @@ -416,18 +417,13 @@ pub(super) fn update_surface_viewport( impl Event for client::wl_buffer::Event { fn handle(self, target: Entity, state: &mut ServerState) { // The only event from a buffer would be the release. - state - .inner - .world - .get::<&WlBuffer>(target) - .unwrap() - .release(); + state.world.get::<&WlBuffer>(target).unwrap().release(); } } impl Event for client::wl_seat::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let server = state.inner.world.get::<&WlSeat>(target).unwrap(); + let server = state.world.get::<&WlSeat>(target).unwrap(); simple_event_shunt! { server, self => [ Capabilities { |capabilities| convert_wenum(capabilities) }, @@ -457,12 +453,13 @@ impl Event for client::wl_pointer::Event { surface_x, surface_y, } => { + let connection = &mut state.connection; + let state = &mut state.inner; let mut cmd = CommandBuffer::new(); - let pending_enter = state.inner.world.remove_one::(target).ok(); - let server = state.inner.world.get::<&WlPointer>(target).unwrap(); + let pending_enter = state.world.remove_one::(target).ok(); + let server = state.world.get::<&WlPointer>(target).unwrap(); let mut query = surface.data().copied().and_then(|e| { state - .inner .world .query_one::<(&WlSurface, &SurfaceRole, &SurfaceScaleFactor, &x::Window)>(e) .ok() @@ -479,9 +476,9 @@ impl Event for client::wl_pointer::Event { let mut do_enter = || { debug!("pointer entering {} ({serial} {})", surface.id(), scale.0); server.enter(serial, surface, surface_x * scale.0, surface_y * scale.0); - state.connection.raise_to_top(*window); + connection.raise_to_top(*window); if !surface_is_popup { - state.inner.last_hovered = Some(*window); + state.last_hovered = Some(*window); } }; @@ -510,22 +507,21 @@ impl Event for client::wl_pointer::Event { } drop(query); drop(server); - cmd.run_on(&mut state.inner.world); + cmd.run_on(&mut state.world); } client::wl_pointer::Event::Leave { serial, surface } => { - let _ = state.inner.world.remove_one::(target); + let _ = state.world.remove_one::(target); if !surface.is_alive() { return; } debug!("leaving surface ({serial})"); - let _ = state.inner.world.remove_one::(target); + let _ = state.world.remove_one::(target); if let Some(surface) = surface .data() .copied() - .and_then(|key| state.inner.world.get::<&WlSurface>(key).ok()) + .and_then(|key| state.world.get::<&WlSurface>(key).ok()) { state - .inner .world .get::<&WlPointer>(target) .unwrap() @@ -539,7 +535,7 @@ impl Event for client::wl_pointer::Event { surface_x, surface_y, } => { - let pending_enter = state.inner.world.get::<&PendingEnter>(target).ok(); + let pending_enter = state.world.get::<&PendingEnter>(target).ok(); match pending_enter.as_deref() { Some(p) => { let PendingEnter(client::wl_pointer::Event::Enter { @@ -554,7 +550,7 @@ impl Event for client::wl_pointer::Event { if surface .data() .copied() - .is_some_and(|key| state.inner.world.contains(key)) + .is_some_and(|key| state.world.contains(key)) { trace!("resending enter ({serial}) before motion"); let enter_event = client::wl_pointer::Event::Enter { @@ -574,7 +570,6 @@ impl Event for client::wl_pointer::Event { None => { drop(pending_enter); let (server, scale) = state - .inner .world .query_one_mut::<(&WlPointer, &SurfaceScaleFactor)>(target) .unwrap(); @@ -589,7 +584,7 @@ impl Event for client::wl_pointer::Event { } } _ => { - let server = state.inner.world.get::<&WlPointer>(target).unwrap(); + let server = state.world.get::<&WlPointer>(target).unwrap(); simple_event_shunt! { server, self => [ Frame, @@ -632,7 +627,7 @@ impl Event for client::wl_pointer::Event { impl Event for client::wl_keyboard::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let state = state.inner_mut(); + let state = state.deref_mut(); let data = state.world.entity(target).unwrap(); let keyboard = data.get::<&WlKeyboard>().unwrap(); match self { @@ -723,7 +718,7 @@ impl Event for client::wl_keyboard::Event { impl Event for client::wl_touch::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let state = state.inner_mut(); + let state = state.deref_mut(); match self { Self::Down { serial, @@ -1039,7 +1034,7 @@ impl OutputEvent { y, state, ); - let state = state.inner_mut(); + let state = state.deref_mut(); let (output, dimensions, xdg) = state .world @@ -1081,7 +1076,7 @@ impl OutputEvent { height, refresh, } => { - let state = state.inner_mut(); + let state = state.deref_mut(); let (output, dimensions) = state .world .query_one_mut::<(&WlOutput, &mut OutputDimensions)>(target) @@ -1098,7 +1093,7 @@ impl OutputEvent { output.mode(convert_wenum(flags), width, height, refresh); } Event::Scale { factor } => { - let state = state.inner_mut(); + let state = state.deref_mut(); debug!( "{} scale: {factor}", state.world.get::<&WlOutput>(target).unwrap().id() @@ -1114,7 +1109,7 @@ impl OutputEvent { } } Event::Name { name } => { - let state = state.inner_mut(); + let state = state.deref_mut(); state .world .get::<&WlOutput>(target) @@ -1123,7 +1118,7 @@ impl OutputEvent { state.world.insert(target, (OutputName(name),)).unwrap(); } _ => simple_event_shunt! { - state.inner.world.get::<&WlOutput>(target).unwrap(), + state.world.get::<&WlOutput>(target).unwrap(), event: client::wl_output::Event => [ Description { description }, Done @@ -1142,7 +1137,7 @@ impl OutputEvent { match event { Event::LogicalPosition { x, y } => { update_output_offset(target, OutputDimensionsSource::Xdg, x, y, state); - let state = state.inner_mut(); + let state = state.deref_mut(); state .world .get::<&XdgOutputServer>(target) @@ -1153,7 +1148,7 @@ impl OutputEvent { ); } Event::LogicalSize { .. } => { - let state = state.inner_mut(); + let state = state.deref_mut(); let (xdg, dimensions) = state .world .query_one_mut::<(&XdgOutputServer, &OutputDimensions)>(target) @@ -1165,7 +1160,7 @@ impl OutputEvent { } } _ => simple_event_shunt! { - state.inner.world.get::<&XdgOutputServer>(target).unwrap(), + state.world.get::<&XdgOutputServer>(target).unwrap(), event: zxdg_output_v1::Event => [ Done, Name { name }, @@ -1178,7 +1173,7 @@ impl OutputEvent { impl Event for wl_drm::client::wl_drm::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let server = state.inner.world.get::<&WlDrmServer>(target).unwrap(); + let server = state.world.get::<&WlDrmServer>(target).unwrap(); simple_event_shunt! { server, self => [ Device { name }, @@ -1193,7 +1188,6 @@ impl Event for wl_drm::client::wl_drm::Event { impl Event for c_dmabuf::zwp_linux_dmabuf_feedback_v1::Event { fn handle(self, target: Entity, state: &mut ServerState) { let server = state - .inner .world .get::<&s_dmabuf::zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1>(target) .unwrap(); @@ -1213,11 +1207,7 @@ impl Event for c_dmabuf::zwp_linux_dmabuf_feedback_v1::Event { impl Event for zwp_relative_pointer_v1::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let server = state - .inner - .world - .get::<&RelativePointerServer>(target) - .unwrap(); + let server = state.world.get::<&RelativePointerServer>(target).unwrap(); simple_event_shunt! { server, self => [ RelativeMotion { @@ -1235,11 +1225,7 @@ impl Event for zwp_relative_pointer_v1::Event { impl Event for zwp_locked_pointer_v1::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let server = state - .inner - .world - .get::<&LockedPointerServer>(target) - .unwrap(); + let server = state.world.get::<&LockedPointerServer>(target).unwrap(); simple_event_shunt! { server, self => [ Locked, @@ -1251,11 +1237,7 @@ impl Event for zwp_locked_pointer_v1::Event { impl Event for zwp_confined_pointer_v1::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let server = state - .inner - .world - .get::<&ConfinedPointerServer>(target) - .unwrap(); + let server = state.world.get::<&ConfinedPointerServer>(target).unwrap(); simple_event_shunt! { server, self => [ Confined, @@ -1267,7 +1249,7 @@ impl Event for zwp_confined_pointer_v1::Event { impl Event for zwp_tablet_seat_v2::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let state = state.inner_mut(); + let state = state.deref_mut(); let seat = state.world.get::<&TabletSeatServer>(target).unwrap(); match self { Self::TabletAdded { id } => { @@ -1295,7 +1277,7 @@ impl Event for zwp_tablet_seat_v2::Event { impl Event for zwp_tablet_v2::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let tab = state.inner.world.get::<&TabletServer>(target).unwrap(); + let tab = state.world.get::<&TabletServer>(target).unwrap(); simple_event_shunt! { tab, self => [ Name { name }, @@ -1310,7 +1292,7 @@ impl Event for zwp_tablet_v2::Event { impl Event for zwp_tablet_pad_v2::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let state = state.inner_mut(); + let state = state.deref_mut(); let pad = state.world.get::<&TabletPadServer>(target).unwrap(); let s_surf; match self { @@ -1364,7 +1346,7 @@ impl Event for zwp_tablet_pad_v2::Event { impl Event for zwp_tablet_tool_v2::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let state = state.inner_mut(); + let state = state.deref_mut(); match self { Self::ProximityIn { serial, @@ -1465,7 +1447,7 @@ where impl Event for zwp_tablet_pad_group_v2::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let state = state.inner_mut(); + let state = state.deref_mut(); let group = state.world.get::<&TabletPadGroupServer>(target).unwrap(); match self { Self::Buttons { buttons } => group.buttons(buttons), @@ -1494,7 +1476,7 @@ impl Event for zwp_tablet_pad_group_v2::Event { impl Event for zwp_tablet_pad_ring_v2::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let state = state.inner_mut(); + let state = state.deref_mut(); let ring = state.world.get::<&TabletPadRingServer>(target).unwrap(); simple_event_shunt! { ring, self => [ @@ -1509,7 +1491,7 @@ impl Event for zwp_tablet_pad_ring_v2::Event { impl Event for zwp_tablet_pad_strip_v2::Event { fn handle(self, target: Entity, state: &mut ServerState) { - let state = state.inner_mut(); + let state = state.deref_mut(); let strip = state.world.get::<&TabletPadStripServer>(target).unwrap(); simple_event_shunt! { strip, self => [ diff --git a/src/server/mod.rs b/src/server/mod.rs index 18613a9..56f5e67 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -18,6 +18,7 @@ use smithay_client_toolkit::data_device_manager::{ }; use std::collections::{HashMap, HashSet}; use std::io::Read; +use std::ops::{Deref, DerefMut}; use std::os::fd::{AsFd, BorrowedFd}; use std::os::unix::net::UnixStream; use std::rc::{Rc, Weak}; @@ -393,10 +394,10 @@ struct GlobalOutputOffset { /// The state of the X11 connection before XState has been fully initialized. /// It implements XConnection minimally, gracefully doing nothing but logging the called functions. -pub struct EarlyConnection { +pub struct NoConnection { _p: std::marker::PhantomData, } -impl XConnection for EarlyConnection { +impl XConnection for NoConnection { type X11Selection = S; fn focus_window(&mut self, _: x::Window, _: Option) { debug!("could not focus window without XWayland initialized"); @@ -423,6 +424,17 @@ pub struct ServerState { inner: InnerServerState, pub connection: C, } +impl Deref for ServerState { + type Target = InnerServerState; + fn deref(&self) -> &Self::Target { + &self.inner + } +} +impl DerefMut for ServerState { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} pub struct InnerServerState { dh: DisplayHandle, @@ -451,7 +463,7 @@ pub struct InnerServerState { new_scale: Option, } -impl ServerState> { +impl ServerState> { pub fn new( mut dh: DisplayHandle, server_connection: Option, @@ -548,7 +560,7 @@ impl ServerState> { }; Self { inner, - connection: EarlyConnection { + connection: NoConnection { _p: std::marker::PhantomData, }, } @@ -566,103 +578,18 @@ impl ServerState> { } impl ServerState { - pub fn inner_mut(&mut self) -> &mut InnerServerState { - &mut self.inner - } - - pub fn clientside_fd(&self) -> BorrowedFd<'_> { - self.inner.clientside_fd() - } - - fn handle_new_globals(&mut self) { - self.inner.handle_new_globals() - } - - pub fn new_window( - &mut self, - window: x::Window, - override_redirect: bool, - dims: WindowDims, - pid: Option, - ) { - self.inner.new_window(window, override_redirect, dims, pid) - } - - pub fn set_popup(&mut self, window: x::Window, is_popup: bool) { - self.inner.set_popup(window, is_popup) - } - - pub fn set_win_title(&mut self, window: x::Window, name: WmName) { - self.inner.set_win_title(window, name); - } - - pub fn set_win_class(&mut self, window: x::Window, class: String) { - self.inner.set_win_class(window, class) - } - - pub fn set_win_hints(&mut self, window: x::Window, hints: WmHints) { - self.inner.set_win_hints(window, hints) - } - - pub fn set_size_hints(&mut self, window: x::Window, hints: WmNormalHints) { - self.inner.set_size_hints(window, hints) - } - - pub fn set_win_decorations(&mut self, window: x::Window, decorations: Decorations) { - self.inner.set_win_decorations(window, decorations) - } - - pub fn set_window_serial(&mut self, window: x::Window, serial: [u32; 2]) { - self.inner.set_window_serial(window, serial) - } - - pub fn can_change_position(&self, window: x::Window) -> bool { - self.inner.can_change_position(window) - } - - pub fn reconfigure_window(&mut self, event: x::ConfigureNotifyEvent) { - self.inner.reconfigure_window(event) - } - - pub fn map_window(&mut self, window: x::Window) { - self.inner.map_window(window) - } - - pub fn unmap_window(&mut self, window: x::Window) { - self.inner.unmap_window(window) - } - - pub fn set_fullscreen(&mut self, window: x::Window, state: super::xstate::SetState) { - self.inner.set_fullscreen(window, state) - } - - pub fn set_transient_for(&mut self, window: x::Window, parent: x::Window) { - self.inner.set_transient_for(window, parent) - } - - pub fn activate_window(&mut self, window: x::Window) { - self.inner.activate_window(window) - } - - pub fn destroy_window(&mut self, window: x::Window) { - self.inner.destroy_window(window) - } - - pub(crate) fn set_copy_paste_source(&mut self, selection: &Rc) { - self.inner.set_copy_paste_source(selection) - } - pub fn run(&mut self) { - if let Some(r) = self.inner.queue.prepare_read() { + if let Some(r) = self.queue.prepare_read() { let fd = r.connection_fd(); let pollfd = PollFd::new(&fd, PollFlags::IN); if poll(&mut [pollfd], 0).unwrap() > 0 { let _ = r.read(); } } - self.inner + let state = self.deref_mut(); + state .queue - .dispatch_pending(&mut self.inner.world) + .dispatch_pending(&mut state.world) .expect("Failed dispatching client side Wayland events"); self.handle_clientside_events(); } @@ -670,42 +597,43 @@ impl ServerState { pub fn handle_clientside_events(&mut self) { self.handle_new_globals(); - for (target, event) in self.inner.world.read_events() { - if !self.inner.world.contains(target) { + for (target, event) in self.world.read_events() { + if !self.world.contains(target) { warn!("could not handle clientside event: stale object"); continue; } event.handle(target, self); } - if self.inner.global_offset_updated { - if self.inner.global_output_offset.x.owner.is_none() - || self.inner.global_output_offset.y.owner.is_none() + if self.global_offset_updated { + if self.global_output_offset.x.owner.is_none() + || self.global_output_offset.y.owner.is_none() { self.calc_global_output_offset(); } debug!( "updated global output offset: {}x{}", - self.inner.global_output_offset.x.value, self.inner.global_output_offset.y.value + self.global_output_offset.x.value, self.global_output_offset.y.value ); - for (e, _) in self.inner.world.query::<&WlOutput>().iter() { + let state = &self.inner; + for (e, _) in state.world.query::<&WlOutput>().iter() { event::update_global_output_offset( e, - &self.inner.global_output_offset, - &self.inner.world, + &state.global_output_offset, + &state.world, &mut self.connection, ); } - self.inner.global_offset_updated = false; + self.global_offset_updated = false; } - if !self.inner.updated_outputs.is_empty() { - for output in self.inner.updated_outputs.drain(..) { - let output_scale = self.inner.world.get::<&OutputScaleFactor>(output).unwrap(); + if !self.updated_outputs.is_empty() { + let state = self.deref_mut(); + for output in state.updated_outputs.drain(..) { + let output_scale = state.world.get::<&OutputScaleFactor>(output).unwrap(); if matches!(*output_scale, OutputScaleFactor::Output(..)) { - let mut surface_query = self - .inner + let mut surface_query = state .world .query::<(&OnOutput, &mut SurfaceScaleFactor)>() .with::<(&WindowData, &WlSurface)>(); @@ -720,7 +648,7 @@ impl ServerState { drop(surface_query); for surface in surfaces { - update_surface_viewport(self.inner.world.query_one(surface).unwrap()); + update_surface_viewport(state.world.query_one(surface).unwrap()); } } } @@ -728,11 +656,7 @@ impl ServerState { let mut mixed_scale = false; let mut scale; - let mut outputs = self - .inner - .world - .query_mut::<&OutputScaleFactor>() - .into_iter(); + let mut outputs = self.world.query_mut::<&OutputScaleFactor>().into_iter(); let (_, output_scale) = outputs.next().unwrap(); scale = output_scale.get(); @@ -749,70 +673,45 @@ impl ServerState { } debug!("Using new scale {scale}"); - self.inner.new_scale = Some(scale); + self.new_scale = Some(scale); } { if let Some(FocusData { window, output_name, - }) = self.inner.to_focus.take() + }) = self.to_focus.take() { debug!("focusing window {window:?}"); self.connection.focus_window(window, output_name); - self.inner.last_focused_toplevel = Some(window); - } else if self.inner.unfocus { + self.last_focused_toplevel = Some(window); + } else if self.unfocus { self.connection.focus_window(x::WINDOW_NONE, None); } - self.inner.unfocus = false; + self.unfocus = false; } self.handle_clipboard_events(); self.handle_activations(); - self.inner - .queue + self.queue .flush() .expect("Failed flushing clientside events"); } - pub fn new_global_scale(&mut self) -> Option { - self.inner.new_global_scale() - } - - pub fn new_selection(&mut self) -> Option { - self.inner.new_selection() - } - - fn handle_clipboard_events(&mut self) { - self.inner.handle_clipboard_events() - } - - fn handle_activations(&mut self) { - self.inner.handle_activations() - } - - fn calc_global_output_offset(&mut self) { - self.inner.calc_global_output_offset() - } - - // create_role_window is only called in a Dispatch impl, a trait impl necessarily moved to be - // on the ineer value. create_toplevel and create_popup are only called by that create_role_window - // call, so none of them need wrapper functions. - fn close_x_window(&mut self, window: x::Window) { debug!("sending close request to {window:?}"); self.connection.close_window(window); - if self.inner.last_focused_toplevel == Some(window) { - self.inner.last_focused_toplevel.take(); + if self.last_focused_toplevel == Some(window) { + self.last_focused_toplevel.take(); } - if self.inner.last_hovered == Some(window) { - self.inner.last_hovered.take(); + if self.last_hovered == Some(window) { + self.last_hovered.take(); } } } impl InnerServerState { - fn clientside_fd(&self) -> BorrowedFd<'_> { + pub fn clientside_fd(&self) -> BorrowedFd<'_> { self.queue.as_fd() } @@ -821,7 +720,7 @@ impl InnerServerState { handle_globals::(&self.dh, globals.iter()); } - fn new_window( + pub fn new_window( &mut self, window: x::Window, override_redirect: bool, @@ -846,7 +745,7 @@ impl InnerServerState { self.windows.insert(window, id); } - fn set_popup(&mut self, window: x::Window, is_popup: bool) { + pub fn set_popup(&mut self, window: x::Window, is_popup: bool) { let Some(id) = self.windows.get(&window).copied() else { debug!("not setting popup for unknown window {window:?}"); return; @@ -859,7 +758,7 @@ impl InnerServerState { .is_popup = is_popup; } - fn set_win_title(&mut self, window: x::Window, name: WmName) { + pub fn set_win_title(&mut self, window: x::Window, name: WmName) { let Some(data) = self .windows .get(&window) @@ -897,7 +796,7 @@ impl InnerServerState { } } - fn set_win_class(&mut self, window: x::Window, class: String) { + pub fn set_win_class(&mut self, window: x::Window, class: String) { let Some(data) = self .windows .get(&window) @@ -918,7 +817,7 @@ impl InnerServerState { } } - fn set_win_hints(&mut self, window: x::Window, hints: WmHints) { + pub fn set_win_hints(&mut self, window: x::Window, hints: WmHints) { let Some(id) = self.windows.get(&window).copied() else { debug!("not setting hints for unknown window {window:?}"); return; @@ -927,7 +826,7 @@ impl InnerServerState { self.world.get::<&mut WindowData>(id).unwrap().attrs.group = hints.window_group; } - fn set_size_hints(&mut self, window: x::Window, hints: WmNormalHints) { + pub fn set_size_hints(&mut self, window: x::Window, hints: WmNormalHints) { let Some(data) = self .windows .get(&window) @@ -961,7 +860,7 @@ impl InnerServerState { } } - fn set_win_decorations(&mut self, window: x::Window, decorations: Decorations) { + pub fn set_win_decorations(&mut self, window: x::Window, decorations: Decorations) { if self.decoration_manager.is_none() { return; }; @@ -992,7 +891,7 @@ impl InnerServerState { } } - fn set_window_serial(&mut self, window: x::Window, serial: [u32; 2]) { + pub fn set_window_serial(&mut self, window: x::Window, serial: [u32; 2]) { let Some(id) = self.windows.get(&window).copied() else { warn!("Tried to set serial for unknown window {window:?}"); return; @@ -1001,7 +900,7 @@ impl InnerServerState { self.world.insert(id, (SurfaceSerial(serial),)).unwrap(); } - fn can_change_position(&self, window: x::Window) -> bool { + pub fn can_change_position(&self, window: x::Window) -> bool { let Some(win) = self .windows .get(&window) @@ -1015,7 +914,7 @@ impl InnerServerState { !win.mapped || win.attrs.is_popup } - fn reconfigure_window(&mut self, event: x::ConfigureNotifyEvent) { + pub fn reconfigure_window(&mut self, event: x::ConfigureNotifyEvent) { let Some((mut win, data)) = self .windows .get(&event.window()) @@ -1074,7 +973,7 @@ impl InnerServerState { } } - fn map_window(&mut self, window: x::Window) { + pub fn map_window(&mut self, window: x::Window) { debug!("mapping {window:?}"); let Some(mut win) = self @@ -1091,7 +990,7 @@ impl InnerServerState { win.mapped = true; } - fn unmap_window(&mut self, window: x::Window) { + pub fn unmap_window(&mut self, window: x::Window) { let entity = self.windows.get(&window).copied(); { @@ -1119,7 +1018,7 @@ impl InnerServerState { } } - fn set_fullscreen(&mut self, window: x::Window, state: super::xstate::SetState) { + pub fn set_fullscreen(&mut self, window: x::Window, state: super::xstate::SetState) { let Some(data) = self .windows .get(&window) @@ -1154,7 +1053,7 @@ impl InnerServerState { } } - fn set_transient_for(&mut self, window: x::Window, parent: x::Window) { + pub fn set_transient_for(&mut self, window: x::Window, parent: x::Window) { let Some(mut win) = self .windows .get(&window) @@ -1168,7 +1067,7 @@ impl InnerServerState { win.attrs.transient_for = Some(parent); } - fn activate_window(&mut self, window: x::Window) { + pub fn activate_window(&mut self, window: x::Window) { let Some(activation_state) = self.activation_state.as_ref() else { return; }; @@ -1205,7 +1104,7 @@ impl InnerServerState { ); } - fn destroy_window(&mut self, window: x::Window) { + pub fn destroy_window(&mut self, window: x::Window) { if let Some(id) = self.windows.remove(&window) { self.world.remove::<(x::Window, WindowData)>(id).unwrap(); if self.world.entity(id).unwrap().is_empty() { @@ -1214,7 +1113,7 @@ impl InnerServerState { } } - fn set_copy_paste_source(&mut self, selection: &Rc) { + pub(crate) fn set_copy_paste_source(&mut self, selection: &Rc) { if let Some(d) = &mut self.clipboard_data { let src = d .manager @@ -1237,11 +1136,11 @@ impl InnerServerState { } } - fn new_global_scale(&mut self) -> Option { + pub fn new_global_scale(&mut self) -> Option { self.new_scale.take() } - fn new_selection(&mut self) -> Option { + pub fn new_selection(&mut self) -> Option { self.clipboard_data.as_mut().and_then(|c| { c.source.take().and_then(|s| match s { CopyPasteData::Foreign(f) => Some(f), diff --git a/src/server/tests.rs b/src/server/tests.rs index c164a92..badde7a 100644 --- a/src/server/tests.rs +++ b/src/server/tests.rs @@ -1,4 +1,4 @@ -use super::{EarlyConnection, InnerServerState, ServerState, WindowDims}; +use super::{InnerServerState, NoConnection, ServerState, WindowDims}; use crate::xstate::{SetState, WinSize, WmName}; use crate::XConnection; use rustix::event::{poll, PollFd, PollFlags}; @@ -240,8 +240,7 @@ impl super::XConnection for FakeXConnection { } } -type EarlyServerState = ServerState>; -type EarlyTestFixture = TestFixture>; +type EarlyTestFixture = TestFixture>; struct TestFixture { testwl: testwl::Server, @@ -368,7 +367,7 @@ impl EarlyTestFixture { }); let (fake_client, xwls_server) = UnixStream::pair().unwrap(); - let satellite = EarlyServerState::new(display.handle(), Some(client_s), xwls_server); + let satellite = ServerState::new(display.handle(), Some(client_s), xwls_server); let testwl = thread.join().unwrap(); let xwls_connection = Connection::from_socket(fake_client).unwrap(); @@ -467,7 +466,7 @@ impl TestFixture { // Have satellite dispatch our requests self.xwls_display - .dispatch_clients(self.satellite.inner_mut()) + .dispatch_clients(&mut *self.satellite) .unwrap(); self.xwls_display.flush_clients().unwrap(); @@ -1414,12 +1413,12 @@ fn raise_window_on_pointer_event() { f.testwl.move_pointer_to(id2, 0.0, 0.0); f.run(); assert_eq!(f.connection().focused_window, Some(win2)); - assert_eq!(f.satellite.inner.last_hovered, Some(win2)); + assert_eq!(f.satellite.last_hovered, Some(win2)); f.testwl.move_pointer_to(id1, 0.0, 0.0); f.run(); assert_eq!(f.connection().focused_window, Some(win2)); - assert_eq!(f.satellite.inner.last_hovered, Some(win1)); + assert_eq!(f.satellite.last_hovered, Some(win1)); } #[test] @@ -1436,7 +1435,7 @@ fn override_redirect_choose_hover_window() { f.testwl.move_pointer_to(id1, 0.0, 0.0); f.run(); - assert_eq!(f.satellite.inner.last_hovered, Some(win1)); + assert_eq!(f.satellite.last_hovered, Some(win1)); let win3 = unsafe { Window::new(3) }; let (buffer, surface) = comp.create_surface();