From 7df3daba7087a1d5c12f01c8837a4048fe6b72cb Mon Sep 17 00:00:00 2001 From: Shawn Wallace Date: Wed, 12 Mar 2025 00:55:39 -0400 Subject: [PATCH] Remove ExtraData type from XConnection trait This was being used to pass the X11 atoms all over the place, but I realize this is no longer necessary - we can just pass them directly to our RealConnection when creating it. --- src/lib.rs | 16 ++------ src/server/event.rs | 14 +++---- src/server/mod.rs | 14 ++----- src/server/tests.rs | 11 ++---- src/xstate/mod.rs | 96 +++++++++++++++++++++------------------------ 5 files changed, 60 insertions(+), 91 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 381cd04..416fedd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,27 +16,17 @@ use wayland_server::{Display, ListeningSocket}; use xcb::x; pub trait XConnection: Sized + 'static { - type ExtraData: FromServerState; type X11Selection: X11Selection; fn root_window(&self) -> x::Window; fn set_window_dims(&mut self, window: x::Window, dims: PendingSurfaceState); - fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool, data: Self::ExtraData); - fn focus_window( - &mut self, - window: x::Window, - output_name: Option, - data: Self::ExtraData, - ); - fn close_window(&mut self, window: x::Window, data: Self::ExtraData); + fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool); + fn focus_window(&mut self, window: x::Window, output_name: Option); + fn close_window(&mut self, window: x::Window); fn unmap_window(&mut self, window: x::Window); fn raise_to_top(&mut self, window: x::Window); } -pub trait FromServerState { - fn create(state: &ServerState) -> Self; -} - pub trait X11Selection { fn mime_types(&self) -> Vec<&str>; fn write_to(&self, mime: &str, pipe: WritePipe); diff --git a/src/server/event.rs b/src/server/event.rs index a60aa15..a0fe33b 100644 --- a/src/server/event.rs +++ b/src/server/event.rs @@ -139,11 +139,10 @@ impl SurfaceData { let window = win_data.window; output.windows.insert(window); if self.window.is_some() && state.last_focused_toplevel == self.window { - let data = C::ExtraData::create(state); let output = self.get_output_name(state); let conn = state.connection.as_mut().unwrap(); debug!("focused window changed outputs - resetting primary output"); - conn.focus_window(window, output, data); + conn.focus_window(window, output); } } } @@ -233,12 +232,11 @@ impl SurfaceData { states.contains(&(u32::from(xdg_toplevel::State::Fullscreen) as u8)); if toplevel.fullscreen != prev_fs { let window = state.associated_windows[self.key]; - let data = C::ExtraData::create(state); - state.connection.as_mut().unwrap().set_fullscreen( - window, - toplevel.fullscreen, - data, - ); + state + .connection + .as_mut() + .unwrap() + .set_fullscreen(window, toplevel.fullscreen); } }; diff --git a/src/server/mod.rs b/src/server/mod.rs index c79edce..f24d11e 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -5,9 +5,8 @@ mod event; mod tests; use self::event::*; -use super::FromServerState; use crate::clientside::*; -use crate::xstate::{Atoms, WindowDims, WmHints, WmName, WmNormalHints}; +use crate::xstate::{WindowDims, WmHints, WmName, WmNormalHints}; use crate::{X11Selection, XConnection}; use log::{debug, warn}; use rustix::event::{poll, PollFd, PollFlags}; @@ -475,7 +474,6 @@ struct FocusData { } pub struct ServerState { - pub atoms: Option, dh: DisplayHandle, clientside: ClientState, objects: ObjectMap, @@ -531,7 +529,6 @@ impl ServerState { windows: HashMap::new(), clientside, client: None, - atoms: None, qh, dh, to_focus: None, @@ -862,15 +859,13 @@ impl ServerState { output_name, }) = self.to_focus.take() { - let data = C::ExtraData::create(self); let conn = self.connection.as_mut().unwrap(); debug!("focusing window {window:?}"); - conn.focus_window(window, output_name, data); + conn.focus_window(window, output_name); self.last_focused_toplevel = Some(window); } else if self.unfocus { - let data = C::ExtraData::create(self); let conn = self.connection.as_mut().unwrap(); - conn.focus_window(x::WINDOW_NONE, None, data); + conn.focus_window(x::WINDOW_NONE, None); } self.unfocus = false; } @@ -1099,8 +1094,7 @@ impl ServerState { fn close_x_window(&mut self, window: x::Window) { debug!("sending close request to {window:?}"); - let data = C::ExtraData::create(self); - self.connection.as_mut().unwrap().close_window(window, data); + self.connection.as_mut().unwrap().close_window(window); if self.last_focused_toplevel == Some(window) { self.last_focused_toplevel.take(); } diff --git a/src/server/tests.rs b/src/server/tests.rs index 2d163bc..75e63f0 100644 --- a/src/server/tests.rs +++ b/src/server/tests.rs @@ -179,10 +179,6 @@ impl Default for FakeXConnection { } } -impl super::FromServerState for () { - fn create(_: &FakeServerState) -> Self {} -} - impl crate::X11Selection for Vec { fn mime_types(&self) -> Vec<&str> { self.iter().map(|data| data.mime_type.as_str()).collect() @@ -205,20 +201,19 @@ impl crate::X11Selection for Vec { } impl super::XConnection for FakeXConnection { - type ExtraData = (); type X11Selection = Vec; fn root_window(&self) -> Window { self.root } #[track_caller] - fn close_window(&mut self, window: Window, _: ()) { + fn close_window(&mut self, window: Window) { log::debug!("closing window {window:?}"); self.window(window).mapped = false; } #[track_caller] - fn set_fullscreen(&mut self, window: xcb::x::Window, fullscreen: bool, _: ()) { + fn set_fullscreen(&mut self, window: xcb::x::Window, fullscreen: bool) { self.window(window).fullscreen = fullscreen; } @@ -233,7 +228,7 @@ impl super::XConnection for FakeXConnection { } #[track_caller] - fn focus_window(&mut self, window: Window, _output_name: Option, _: ()) { + fn focus_window(&mut self, window: Window, _output_name: Option) { assert!( self.windows.contains_key(&window), "Unknown window: {window:?}" diff --git a/src/xstate/mod.rs b/src/xstate/mod.rs index c52b4ba..e2df1cc 100644 --- a/src/xstate/mod.rs +++ b/src/xstate/mod.rs @@ -209,10 +209,9 @@ impl XState { } pub fn server_state_setup(&self, server_state: &mut super::RealServerState) { - let mut c = RealConnection::new(self.connection.clone()); + let mut c = RealConnection::new(self.connection.clone(), self.atoms.clone()); c.update_outputs(self.root); server_state.set_x_connection(c); - server_state.atoms = Some(self.atoms.clone()); } fn set_root_property(&self, property: x::Atom, r#type: x::Atom, data: &[P]) { @@ -359,11 +358,11 @@ impl XState { let active_win: &[x::Window] = active_win.value(); if active_win[0] == e.window() { // The connection on the server state stores state. - server_state.connection.as_mut().unwrap().focus_window( - x::Window::none(), - None, - self.atoms.clone(), - ); + server_state + .connection + .as_mut() + .unwrap() + .focus_window(x::Window::none(), None); } unwrap_or_skip_bad_window_cont!(self.connection.send_and_check_request( @@ -707,28 +706,28 @@ impl XState { xcb::atoms_struct! { #[derive(Clone, Debug)] - pub struct Atoms { - pub wl_surface_id => b"WL_SURFACE_ID" only_if_exists = false, - pub wl_surface_serial => b"WL_SURFACE_SERIAL" only_if_exists = false, - pub wm_protocols => b"WM_PROTOCOLS" only_if_exists = false, - pub wm_delete_window => b"WM_DELETE_WINDOW" only_if_exists = false, - pub wm_transient_for => b"WM_TRANSIENT_FOR" only_if_exists = false, - pub wm_check => b"_NET_SUPPORTING_WM_CHECK" only_if_exists = false, - pub net_wm_name => b"_NET_WM_NAME" only_if_exists = false, - pub wm_pid => b"_NET_WM_PID" only_if_exists = false, - pub net_wm_state => b"_NET_WM_STATE" only_if_exists = false, - pub wm_fullscreen => b"_NET_WM_STATE_FULLSCREEN" only_if_exists = false, - pub active_win => b"_NET_ACTIVE_WINDOW" only_if_exists = false, - pub client_list => b"_NET_CLIENT_LIST" only_if_exists = false, - pub supported => b"_NET_SUPPORTED" only_if_exists = false, - pub utf8_string => b"UTF8_STRING" only_if_exists = false, - pub clipboard => b"CLIPBOARD" only_if_exists = false, - pub targets => b"TARGETS" only_if_exists = false, - pub save_targets => b"SAVE_TARGETS" only_if_exists = false, - pub multiple => b"MULTIPLE" only_if_exists = false, - pub timestamp => b"TIMESTAMP" only_if_exists = false, - pub selection_reply => b"_selection_reply" only_if_exists = false, - pub incr => b"INCR" only_if_exists = false, + struct Atoms { + wl_surface_id => b"WL_SURFACE_ID" only_if_exists = false, + wl_surface_serial => b"WL_SURFACE_SERIAL" only_if_exists = false, + wm_protocols => b"WM_PROTOCOLS" only_if_exists = false, + wm_delete_window => b"WM_DELETE_WINDOW" only_if_exists = false, + wm_transient_for => b"WM_TRANSIENT_FOR" only_if_exists = false, + wm_check => b"_NET_SUPPORTING_WM_CHECK" only_if_exists = false, + net_wm_name => b"_NET_WM_NAME" only_if_exists = false, + wm_pid => b"_NET_WM_PID" only_if_exists = false, + net_wm_state => b"_NET_WM_STATE" only_if_exists = false, + wm_fullscreen => b"_NET_WM_STATE_FULLSCREEN" only_if_exists = false, + active_win => b"_NET_ACTIVE_WINDOW" only_if_exists = false, + client_list => b"_NET_CLIENT_LIST" only_if_exists = false, + supported => b"_NET_SUPPORTED" only_if_exists = false, + utf8_string => b"UTF8_STRING" only_if_exists = false, + clipboard => b"CLIPBOARD" only_if_exists = false, + targets => b"TARGETS" only_if_exists = false, + save_targets => b"SAVE_TARGETS" only_if_exists = false, + multiple => b"MULTIPLE" only_if_exists = false, + timestamp => b"TIMESTAMP" only_if_exists = false, + selection_reply => b"_selection_reply" only_if_exists = false, + incr => b"INCR" only_if_exists = false, } } @@ -840,14 +839,16 @@ impl TryFrom for SetState { } pub struct RealConnection { + atoms: Atoms, connection: Rc, outputs: HashMap, primary_output: xcb::randr::Output, } impl RealConnection { - fn new(connection: Rc) -> Self { + fn new(connection: Rc, atoms: Atoms) -> Self { Self { + atoms, connection, outputs: Default::default(), primary_output: Xid::none(), @@ -896,7 +897,6 @@ impl RealConnection { } impl XConnection for RealConnection { - type ExtraData = Atoms; type X11Selection = Selection; fn root_window(&self) -> x::Window { @@ -916,9 +916,9 @@ impl XConnection for RealConnection { })); } - fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool, atoms: Self::ExtraData) { + fn set_fullscreen(&mut self, window: x::Window, fullscreen: bool) { let data = if fullscreen { - std::slice::from_ref(&atoms.wm_fullscreen) + std::slice::from_ref(&self.atoms.wm_fullscreen) } else { &[] }; @@ -928,7 +928,7 @@ impl XConnection for RealConnection { .send_and_check_request(&x::ChangeProperty:: { mode: x::PropMode::Replace, window, - property: atoms.net_wm_state, + property: self.atoms.net_wm_state, r#type: x::ATOM_ATOM, data, }) @@ -937,12 +937,7 @@ impl XConnection for RealConnection { } } - fn focus_window( - &mut self, - window: x::Window, - output_name: Option, - atoms: Self::ExtraData, - ) { + fn focus_window(&mut self, window: x::Window, output_name: Option) { trace!("{window:?} {output_name:?}"); if let Err(e) = self.connection.send_and_check_request(&x::SetInputFocus { focus: window, @@ -955,7 +950,7 @@ impl XConnection for RealConnection { if let Err(e) = self.connection.send_and_check_request(&x::ChangeProperty { mode: x::PropMode::Replace, window: self.root_window(), - property: atoms.active_win, + property: self.atoms.active_win, r#type: x::ATOM_WINDOW, data: &[window], }) { @@ -992,22 +987,25 @@ impl XConnection for RealConnection { } } - fn close_window(&mut self, window: x::Window, atoms: Self::ExtraData) { + fn close_window(&mut self, window: x::Window) { let cookie = self.connection.send_request(&x::GetProperty { window, delete: false, - property: atoms.wm_protocols, + property: self.atoms.wm_protocols, r#type: x::ATOM_ATOM, long_offset: 0, long_length: 10, }); let reply = unwrap_or_skip_bad_window!(self.connection.wait_for_reply(cookie)); - if reply.value::().contains(&atoms.wm_delete_window) { - let data = [atoms.wm_delete_window.resource_id(), 0, 0, 0, 0]; + if reply + .value::() + .contains(&self.atoms.wm_delete_window) + { + let data = [self.atoms.wm_delete_window.resource_id(), 0, 0, 0, 0]; let event = &x::ClientMessageEvent::new( window, - atoms.wm_protocols, + self.atoms.wm_protocols, x::ClientMessageData::Data32(data), ); @@ -1038,12 +1036,6 @@ impl XConnection for RealConnection { } } -impl super::FromServerState for Atoms { - fn create(state: &super::RealServerState) -> Self { - state.atoms.as_ref().unwrap().clone() - } -} - fn get_atom_name(connection: &xcb::Connection, atom: x::Atom) -> String { match connection.wait_for_reply(connection.send_request(&x::GetAtomName { atom })) { Ok(reply) => reply.name().to_string(),