From a29937ebe8ba6a88c6c952a27e9f22651cfbd970 Mon Sep 17 00:00:00 2001 From: kossLAN Date: Sat, 16 May 2026 18:34:20 -0400 Subject: [PATCH] seperate workspaces by monitor --- src/config/handler.rs | 25 ++++++++++++------- src/ifs/jay_tree_query.rs | 10 +++++++- .../ext_workspace_manager_v1.rs | 9 ++++--- src/state.rs | 7 +++--- src/tree/output.rs | 13 +++++++--- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/config/handler.rs b/src/config/handler.rs index c03bc8e3..526c1cde 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -698,8 +698,14 @@ impl ConfigProxyHandler { } fn get_existing_workspace(&self, ws: Workspace) -> Result>, CphError> { - self.get_workspace(ws) - .map(|ws| self.state.workspaces.get(&*ws)) + self.get_workspace(ws).map(|name| { + self.state + .workspaces + .lock() + .values() + .find(|ws| ws.name.as_str() == name.as_str()) + .cloned() + }) } fn get_device_handler_data( @@ -1054,9 +1060,10 @@ impl ConfigProxyHandler { fn handle_set_seat_workspace(&self, seat: Seat, ws: Workspace) -> Result<(), CphError> { let seat = self.get_seat(seat)?; let name = self.get_workspace(ws)?; - let workspace = match self.state.workspaces.get(name.deref()) { + let output = seat.get_fallback_output(); + let workspace = match output.find_workspace(name.deref()) { Some(ws) => ws, - _ => seat.get_fallback_output().create_workspace(name.deref()), + _ => output.create_workspace(name.deref()), }; seat.set_workspace(&workspace); Ok(()) @@ -1065,12 +1072,12 @@ impl ConfigProxyHandler { fn handle_set_window_workspace(&self, window: Window, ws: Workspace) -> Result<(), CphError> { let window = self.get_window(window)?; let name = self.get_workspace(ws)?; - let workspace = match self.state.workspaces.get(name.deref()) { + let Some(output) = window.node_output() else { + return Ok(()); + }; + let workspace = match output.find_workspace(name.deref()) { Some(ws) => ws, - _ => match window.node_output() { - Some(o) => o.create_workspace(name.deref()), - _ => return Ok(()), - }, + _ => output.create_workspace(name.deref()), }; toplevel_set_workspace(&self.state, window, &workspace); Ok(()) diff --git a/src/ifs/jay_tree_query.rs b/src/ifs/jay_tree_query.rs index 27493eb5..45c90fa7 100644 --- a/src/ifs/jay_tree_query.rs +++ b/src/ifs/jay_tree_query.rs @@ -265,7 +265,15 @@ impl JayTreeQueryRequestHandler for JayTreeQuery { Some(n) => Visitor(self).visit_workspace(&n), None => self.send_not_found(), }, - Root::WorkspaceName(n) => match self.client.state.workspaces.get(n) { + Root::WorkspaceName(n) => match self + .client + .state + .workspaces + .lock() + .values() + .find(|ws| ws.name.as_str() == n.as_str()) + .cloned() + { Some(n) => Visitor(self).visit_workspace(&n), None => self.send_not_found(), }, diff --git a/src/ifs/workspace_manager/ext_workspace_manager_v1.rs b/src/ifs/workspace_manager/ext_workspace_manager_v1.rs index a22169cc..dfa36189 100644 --- a/src/ifs/workspace_manager/ext_workspace_manager_v1.rs +++ b/src/ifs/workspace_manager/ext_workspace_manager_v1.rs @@ -151,7 +151,8 @@ impl ExtWorkspaceManagerV1 { workspace.ext_workspaces.set(self.manager_id, ws.clone()); self.send_workspace(&ws); ws.send_capabilities(); - ws.send_id(&workspace.name); + let workspace_id = format!("{:?}/{}", output.global.output_id.hash, workspace.name); + ws.send_id(&workspace_id); ws.send_name(&workspace.name); ws.send_coordinates(&[workspace_coordinate(output, workspace)]); ws.send_current_state(); @@ -307,12 +308,12 @@ impl ExtWorkspaceManagerV1RequestHandler for ExtWorkspaceManagerV1 { self.client.state.tree_changed(); } WorkspaceChange::CreateWorkspace(name, output) => { - if self.client.state.workspaces.contains(&name) { - return Ok(()); - } let Some(output) = output.node() else { return Ok(()); }; + if output.find_workspace(&name).is_some() { + return Ok(()); + } output.create_workspace(&name); } } diff --git a/src/state.rs b/src/state.rs index ca60f01e..4ae761a0 100644 --- a/src/state.rs +++ b/src/state.rs @@ -105,6 +105,7 @@ use { FoundNode, LatchListener, Node, NodeIds, NodeVisitorBase, OutputNode, PlaceholderNode, TearingMode, TileState, ToplevelData, ToplevelIdentifier, ToplevelNode, ToplevelNodeBase, Transform, VrrMode, WorkspaceDisplayOrder, WorkspaceNode, + WorkspaceNodeId, WsMoveConfig, generic_node_visitor, move_ws_to_output, }, udmabuf::UdmabufHolder, @@ -177,7 +178,7 @@ pub struct State { pub input_device_ids: InputDeviceIds, pub node_ids: NodeIds, pub root: Rc, - pub workspaces: CopyHashMap>, + pub workspaces: CopyHashMap>, pub dummy_output: CloneCell>>, pub backend_events: AsyncQueue, pub input_device_handlers: RefCell>, @@ -936,10 +937,10 @@ impl State { name: &str, output: Option>, ) { - let ws = match self.workspaces.get(name) { + let output = output.unwrap_or_else(|| seat.get_fallback_output()); + let ws = match output.find_workspace(name) { Some(ws) => ws, _ => { - let output = output.unwrap_or_else(|| seat.get_fallback_output()); if output.is_dummy { log::warn!("Not showing workspace because seat is on dummy output"); return; diff --git a/src/tree/output.rs b/src/tree/output.rs index bb4d23f0..d21b3e5e 100644 --- a/src/tree/output.rs +++ b/src/tree/output.rs @@ -677,7 +677,7 @@ impl OutputNode { let name = 'name: { for i in 1.. { let name = i.to_string(); - if !self.state.workspaces.contains(&name) { + if self.find_workspace(&name).is_none() { break 'name name; } } @@ -686,6 +686,13 @@ impl OutputNode { self.create_workspace(&name) } + pub fn find_workspace(&self, name: &str) -> Option> { + self.workspaces + .iter() + .find(|ws| ws.name.as_str() == name) + .map(|ws| (*ws).clone()) + } + pub fn show_workspace(&self, ws: &Rc) -> bool { let mut seats = SmallVec::new(); if let Some(old) = self.workspace.set(Some(ws.clone())) { @@ -705,7 +712,7 @@ impl OutputNode { wh.handle_destroyed(); } old.clear(); - self.state.workspaces.remove(&old.name); + self.state.workspaces.remove(&old.id); } else { old.set_visible(false); old.flush_jay_workspaces(); @@ -747,7 +754,7 @@ impl OutputNode { self.workspaces.add_last(ws.clone()) }; *ws.output_link.borrow_mut() = Some(link); - self.state.workspaces.set(name.to_string(), ws.clone()); + self.state.workspaces.set(ws.id, ws.clone()); if self.workspace.is_none() { self.show_workspace(&ws); }