use super::*; impl ConfigProxyHandler { pub(super) fn get_workspace_by_name(&self, name: &String) -> Workspace { let id = match self.workspaces_by_name.get(name) { None => { let id = self.workspace_ids.fetch_add(1); let name = Rc::new(name.clone()); self.workspaces_by_name.set(name.clone(), id); self.workspaces_by_id.set(id, name); id } Some(id) => id, }; Workspace(id) } pub(super) fn get_workspace(&self, ws: Workspace) -> Result, CphError> { match self.workspaces_by_id.get(&ws.0) { Some(ws) => Ok(ws), _ => Err(CphError::WorkspaceDoesNotExist(ws)), } } pub(super) fn get_existing_workspace( &self, ws: Workspace, ) -> Result>, CphError> { self.get_workspace(ws).map(|name| { self.state .workspaces .lock() .values() .find(|ws| ws.name.as_str() == name.as_str()) .cloned() }) } pub(super) fn handle_get_workspaces(&self) { let mut workspaces = vec![]; for ws in self.state.workspaces.lock().values() { workspaces.push(self.get_workspace_by_name(&ws.name)); } self.respond(Response::GetWorkspaces { workspaces }); } pub(super) fn handle_get_workspace(&self, name: &str) { self.respond(Response::GetWorkspace { workspace: self.get_workspace_by_name(&name.to_owned()), }); } pub(super) fn handle_get_workspace_capture( &self, workspace: Workspace, ) -> Result<(), CphError> { let ws = self.get_existing_workspace(workspace)?; let capture = match ws { Some(ws) => ws.may_capture.get(), None => self.state.default_workspace_capture.get(), }; self.respond(Response::GetWorkspaceCapture { capture }); Ok(()) } pub(super) fn handle_set_workspace_capture( &self, workspace: Workspace, capture: bool, ) -> Result<(), CphError> { if let Some(ws) = self.get_existing_workspace(workspace)? { ws.may_capture.set(capture); ws.update_has_captures(); } Ok(()) } pub(super) fn handle_get_default_workspace_capture(&self) { self.respond(Response::GetDefaultWorkspaceCapture { capture: self.state.default_workspace_capture.get(), }); } pub(super) fn handle_set_default_workspace_capture(&self, capture: bool) { self.state.default_workspace_capture.set(capture); } pub(super) fn handle_get_seat_cursor_workspace(&self, seat: Seat) -> Result<(), CphError> { let seat = self.get_seat(seat)?; let output = seat.get_cursor_output(); let mut workspace = Workspace(0); if !output.is_dummy && let Some(ws) = output.workspace.get() { workspace = self.get_workspace_by_name(&ws.name); } self.respond(Response::GetSeatCursorWorkspace { workspace }); Ok(()) } pub(super) fn handle_get_seat_keyboard_workspace(&self, seat: Seat) -> Result<(), CphError> { let seat = self.get_seat(seat)?; let mut workspace = Workspace(0); if let Some(output) = seat.get_keyboard_output() && !output.is_dummy && let Some(ws) = output.workspace.get() { workspace = self.get_workspace_by_name(&ws.name); } self.respond(Response::GetSeatKeyboardWorkspace { workspace }); Ok(()) } pub(super) fn handle_show_workspace( &self, seat: Seat, ws: Workspace, output: Option, ) -> Result<(), CphError> { let seat = self.get_seat(seat)?; let name = self.get_workspace(ws)?; let output = output.map(|o| self.get_output_node(o)).transpose()?; self.state.show_workspace(&seat, &name, output); Ok(()) } pub(super) 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 output = seat.get_fallback_output(); let workspace = match output.find_workspace(name.deref()) { Some(ws) => ws, _ => output.create_workspace(name.deref()), }; seat.set_workspace(&workspace); Ok(()) } pub(super) 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 Some(output) = window.node_output() else { return Ok(()); }; let workspace = match output.find_workspace(name.deref()) { Some(ws) => ws, _ => output.create_workspace(name.deref()), }; toplevel_set_workspace(&self.state, window, &workspace); Ok(()) } pub(super) fn handle_move_to_output( &self, workspace: WorkspaceSource, connector: Connector, ) -> Result<(), CphError> { let output = self.get_output_node(connector)?; let ws = match workspace { WorkspaceSource::Explicit(ws) => match self.get_existing_workspace(ws)? { Some(ws) => ws, _ => return Ok(()), }, WorkspaceSource::Seat(s) => { match self.get_seat(s)?.get_fallback_output().workspace.get() { Some(ws) => ws, _ => return Ok(()), } } }; self.state.move_ws_to_output(&ws, &output); Ok(()) } pub(super) fn handle_set_workspace_display_order(&self, order: WorkspaceDisplayOrder) { self.state.set_workspace_display_order(order.into()); } }