From 0016bc8cf0ff4c3dcd7459970e9e01e7059e16df Mon Sep 17 00:00:00 2001 From: kossLAN Date: Fri, 29 May 2026 18:48:33 -0400 Subject: [PATCH] config: split window handling --- src/config/handler.rs | 199 +-------------------------------- src/config/handler/windows.rs | 200 ++++++++++++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 198 deletions(-) create mode 100644 src/config/handler/windows.rs diff --git a/src/config/handler.rs b/src/config/handler.rs index 21e3848e..d0daf09e 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -89,6 +89,7 @@ use { mod dispatch; mod matchers; +mod windows; pub(super) struct ConfigProxyHandler { pub client_data: Cell<*const u8>, @@ -2050,28 +2051,6 @@ impl ConfigProxyHandler { Ok(()) } - fn tl_to_window(&self, tl: &dyn ToplevelNode) -> Window { - self.tl_id_to_window(tl.tl_data().identifier.get()) - } - - fn tl_id_to_window(&self, tl: ToplevelIdentifier) -> Window { - if let Some(win) = self.windows_from_tl_id.get(&tl) { - return win; - } - let id = Window(self.window_ids.fetch_add(1)); - self.windows_from_tl_id.set(tl, id); - self.windows_to_tl_id.set(id, tl); - id - } - - fn get_window(&self, window: Window) -> Result, CphError> { - self.windows_to_tl_id - .get(&window) - .and_then(|id| self.state.toplevels.get(&id)) - .and_then(|tl| tl.upgrade()) - .ok_or(CphError::WindowDoesNotExist(window)) - } - fn handle_set_pointer_revert_key(&self, seat: Seat, key: KeySym) -> Result<(), CphError> { self.get_seat(seat)?.set_pointer_revert_key(key); Ok(()) @@ -2337,182 +2316,6 @@ impl ConfigProxyHandler { self.keymaps.remove(&keymap); } - fn get_client(&self, client: ConfigClient) -> Result, CphError> { - self.state - .clients - .get(ClientId::from_raw(client.0)) - .ok() - .ok_or(CphError::ClientDoesNotExist(client)) - } - - fn handle_get_clients(&self) { - let mut clients = vec![]; - for client in self.state.clients.clients.borrow().values() { - clients.push(ConfigClient(client.data.id.raw())); - } - self.respond(Response::GetClients { clients }); - } - - fn handle_client_exists(&self, client: ConfigClient) { - self.respond(Response::ClientExists { - exists: self.get_client(client).is_ok(), - }); - } - - fn handle_client_is_xwayland(&self, client: ConfigClient) -> Result<(), CphError> { - self.respond(Response::ClientIsXwayland { - is_xwayland: self.get_client(client)?.is_xwayland, - }); - Ok(()) - } - - fn handle_client_kill(&self, client: ConfigClient) { - self.state.clients.kill(ClientId::from_raw(client.0)); - } - - fn handle_get_workspace_window(&self, ws: Workspace) -> Result<(), CphError> { - let window = self - .get_existing_workspace(ws)? - .and_then(|ws| ws.container.get()) - .map(|c| self.tl_to_window(&*c)) - .unwrap_or(Window(0)); - self.respond(Response::GetWorkspaceWindow { window }); - Ok(()) - } - - fn handle_get_seat_keyboard_window(&self, seat: Seat) -> Result<(), CphError> { - let window = self - .get_seat(seat)? - .get_keyboard_node() - .node_toplevel() - .map(|tl| self.tl_to_window(&*tl)) - .unwrap_or(Window(0)); - self.respond(Response::GetSeatKeyboardWindow { window }); - Ok(()) - } - - fn handle_seat_focus_window(&self, seat: Seat, window_id: Window) -> Result<(), CphError> { - let seat = self.get_seat(seat)?; - let window = self.get_window(window_id)?; - if !window.node_visible() { - return Err(CphError::WindowNotVisible(window_id)); - } - seat.focus_toplevel(window); - seat.maybe_schedule_warp_mouse_to_focus(); - Ok(()) - } - - fn handle_get_window_title(&self, window: Window) -> Result<(), CphError> { - let title = self.get_window(window)?.tl_data().title.borrow().clone(); - self.respond(Response::GetWindowTitle { title }); - Ok(()) - } - - fn handle_get_window_type(&self, window: Window) -> Result<(), CphError> { - let kind = self.get_window(window)?.tl_data().kind.to_window_type(); - self.respond(Response::GetWindowType { kind }); - Ok(()) - } - - fn handle_get_content_type(&self, window: Window) -> Result<(), CphError> { - let kind = self - .get_window(window)? - .tl_data() - .content_type - .get() - .to_config(); - self.respond(Response::GetContentType { kind }); - Ok(()) - } - - fn handle_window_resize( - &self, - window: Window, - dx1: i32, - dy1: i32, - dx2: i32, - dy2: i32, - ) -> Result<(), CphError> { - self.state.with_layout_animations(|| { - self.get_window(window)?.tl_resize(dx1, dy1, dx2, dy2); - Ok(()) - }) - } - - fn handle_window_exists(&self, window: Window) { - self.respond(Response::WindowExists { - exists: self.get_window(window).is_ok(), - }); - } - - fn handle_get_window_id(&self, window: Window) -> Result<(), CphError> { - let id = self - .get_window(window)? - .tl_data() - .identifier - .get() - .to_string(); - self.respond(Response::GetWindowId { id: id.to_string() }); - Ok(()) - } - - fn handle_get_window_is_visible(&self, window: Window) -> Result<(), CphError> { - let window = self.get_window(window)?; - self.respond(Response::GetWindowIsVisible { - visible: window.node_visible(), - }); - Ok(()) - } - - fn handle_get_window_client(&self, window: Window) -> Result<(), CphError> { - let window = self.get_window(window)?; - self.respond(Response::GetWindowClient { - client: window - .tl_data() - .client - .as_ref() - .map(|c| ConfigClient(c.id.raw())) - .unwrap_or(ConfigClient(0)), - }); - Ok(()) - } - - fn handle_get_window_parent(&self, window: Window) -> Result<(), CphError> { - let window = self - .get_window(window)? - .tl_data() - .parent - .get() - .and_then(|tl| tl.node_into_toplevel()) - .map(|tl| self.tl_to_window(&*tl)) - .unwrap_or(Window(0)); - self.respond(Response::GetWindowParent { window }); - Ok(()) - } - - fn handle_get_window_workspace(&self, window: Window) -> Result<(), CphError> { - let workspace = self - .get_window(window)? - .tl_data() - .workspace - .get() - .map(|ws| self.get_workspace_by_name(&ws.name)) - .unwrap_or(Workspace(0)); - self.respond(Response::GetWindowWorkspace { workspace }); - Ok(()) - } - - fn handle_get_window_children(&self, window: Window) -> Result<(), CphError> { - let mut windows = vec![]; - if let Some(c) = self.get_window(window)?.node_into_container() { - for c in c.children.iter() { - windows.push(self.tl_to_window(&*c.node)); - } - } - self.respond(Response::GetWindowChildren { windows }); - Ok(()) - } - pub fn auto_focus(&self, data: &ToplevelData) -> bool { for matcher in self.window_matcher_no_auto_focus.lock().values() { if matcher.node.pull(data) { diff --git a/src/config/handler/windows.rs b/src/config/handler/windows.rs new file mode 100644 index 00000000..8df729e8 --- /dev/null +++ b/src/config/handler/windows.rs @@ -0,0 +1,200 @@ +use super::*; + +impl ConfigProxyHandler { + pub(super) fn tl_to_window(&self, tl: &dyn ToplevelNode) -> Window { + self.tl_id_to_window(tl.tl_data().identifier.get()) + } + + pub(super) fn tl_id_to_window(&self, tl: ToplevelIdentifier) -> Window { + if let Some(win) = self.windows_from_tl_id.get(&tl) { + return win; + } + let id = Window(self.window_ids.fetch_add(1)); + self.windows_from_tl_id.set(tl, id); + self.windows_to_tl_id.set(id, tl); + id + } + + pub(super) fn get_window(&self, window: Window) -> Result, CphError> { + self.windows_to_tl_id + .get(&window) + .and_then(|id| self.state.toplevels.get(&id)) + .and_then(|tl| tl.upgrade()) + .ok_or(CphError::WindowDoesNotExist(window)) + } + pub(super) fn get_client(&self, client: ConfigClient) -> Result, CphError> { + self.state + .clients + .get(ClientId::from_raw(client.0)) + .ok() + .ok_or(CphError::ClientDoesNotExist(client)) + } + + pub(super) fn handle_get_clients(&self) { + let mut clients = vec![]; + for client in self.state.clients.clients.borrow().values() { + clients.push(ConfigClient(client.data.id.raw())); + } + self.respond(Response::GetClients { clients }); + } + + pub(super) fn handle_client_exists(&self, client: ConfigClient) { + self.respond(Response::ClientExists { + exists: self.get_client(client).is_ok(), + }); + } + + pub(super) fn handle_client_is_xwayland(&self, client: ConfigClient) -> Result<(), CphError> { + self.respond(Response::ClientIsXwayland { + is_xwayland: self.get_client(client)?.is_xwayland, + }); + Ok(()) + } + + pub(super) fn handle_client_kill(&self, client: ConfigClient) { + self.state.clients.kill(ClientId::from_raw(client.0)); + } + + pub(super) fn handle_get_workspace_window(&self, ws: Workspace) -> Result<(), CphError> { + let window = self + .get_existing_workspace(ws)? + .and_then(|ws| ws.container.get()) + .map(|c| self.tl_to_window(&*c)) + .unwrap_or(Window(0)); + self.respond(Response::GetWorkspaceWindow { window }); + Ok(()) + } + + pub(super) fn handle_get_seat_keyboard_window(&self, seat: Seat) -> Result<(), CphError> { + let window = self + .get_seat(seat)? + .get_keyboard_node() + .node_toplevel() + .map(|tl| self.tl_to_window(&*tl)) + .unwrap_or(Window(0)); + self.respond(Response::GetSeatKeyboardWindow { window }); + Ok(()) + } + + pub(super) fn handle_seat_focus_window(&self, seat: Seat, window_id: Window) -> Result<(), CphError> { + let seat = self.get_seat(seat)?; + let window = self.get_window(window_id)?; + if !window.node_visible() { + return Err(CphError::WindowNotVisible(window_id)); + } + seat.focus_toplevel(window); + seat.maybe_schedule_warp_mouse_to_focus(); + Ok(()) + } + + pub(super) fn handle_get_window_title(&self, window: Window) -> Result<(), CphError> { + let title = self.get_window(window)?.tl_data().title.borrow().clone(); + self.respond(Response::GetWindowTitle { title }); + Ok(()) + } + + pub(super) fn handle_get_window_type(&self, window: Window) -> Result<(), CphError> { + let kind = self.get_window(window)?.tl_data().kind.to_window_type(); + self.respond(Response::GetWindowType { kind }); + Ok(()) + } + + pub(super) fn handle_get_content_type(&self, window: Window) -> Result<(), CphError> { + let kind = self + .get_window(window)? + .tl_data() + .content_type + .get() + .to_config(); + self.respond(Response::GetContentType { kind }); + Ok(()) + } + + pub(super) fn handle_window_resize( + &self, + window: Window, + dx1: i32, + dy1: i32, + dx2: i32, + dy2: i32, + ) -> Result<(), CphError> { + self.state.with_layout_animations(|| { + self.get_window(window)?.tl_resize(dx1, dy1, dx2, dy2); + Ok(()) + }) + } + + pub(super) fn handle_window_exists(&self, window: Window) { + self.respond(Response::WindowExists { + exists: self.get_window(window).is_ok(), + }); + } + + pub(super) fn handle_get_window_id(&self, window: Window) -> Result<(), CphError> { + let id = self + .get_window(window)? + .tl_data() + .identifier + .get() + .to_string(); + self.respond(Response::GetWindowId { id: id.to_string() }); + Ok(()) + } + + pub(super) fn handle_get_window_is_visible(&self, window: Window) -> Result<(), CphError> { + let window = self.get_window(window)?; + self.respond(Response::GetWindowIsVisible { + visible: window.node_visible(), + }); + Ok(()) + } + + pub(super) fn handle_get_window_client(&self, window: Window) -> Result<(), CphError> { + let window = self.get_window(window)?; + self.respond(Response::GetWindowClient { + client: window + .tl_data() + .client + .as_ref() + .map(|c| ConfigClient(c.id.raw())) + .unwrap_or(ConfigClient(0)), + }); + Ok(()) + } + + pub(super) fn handle_get_window_parent(&self, window: Window) -> Result<(), CphError> { + let window = self + .get_window(window)? + .tl_data() + .parent + .get() + .and_then(|tl| tl.node_into_toplevel()) + .map(|tl| self.tl_to_window(&*tl)) + .unwrap_or(Window(0)); + self.respond(Response::GetWindowParent { window }); + Ok(()) + } + + pub(super) fn handle_get_window_workspace(&self, window: Window) -> Result<(), CphError> { + let workspace = self + .get_window(window)? + .tl_data() + .workspace + .get() + .map(|ws| self.get_workspace_by_name(&ws.name)) + .unwrap_or(Workspace(0)); + self.respond(Response::GetWindowWorkspace { workspace }); + Ok(()) + } + + pub(super) fn handle_get_window_children(&self, window: Window) -> Result<(), CphError> { + let mut windows = vec![]; + if let Some(c) = self.get_window(window)?.node_into_container() { + for c in c.children.iter() { + windows.push(self.tl_to_window(&*c.node)); + } + } + self.respond(Response::GetWindowChildren { windows }); + Ok(()) + } +}