diff --git a/src/config/handler.rs b/src/config/handler.rs index 77c95937..f35c206e 100644 --- a/src/config/handler.rs +++ b/src/config/handler.rs @@ -93,6 +93,7 @@ mod matchers; mod outputs; mod theme; mod windows; +mod workspaces; pub(super) struct ConfigProxyHandler { pub client_data: Cell<*const u8>, @@ -219,20 +220,6 @@ impl ConfigProxyHandler { self.next_id.fetch_add(1) } - 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) - } - fn handle_log_request( &self, level: ConfigLogLevel, @@ -447,14 +434,6 @@ impl ConfigProxyHandler { self.respond(Response::GetConfigDir { dir }); } - 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 }); - } - fn handle_program_timer( &self, timer: JayTimer, @@ -567,24 +546,6 @@ impl ConfigProxyHandler { Ok(()) } - fn get_workspace(&self, ws: Workspace) -> Result, CphError> { - match self.workspaces_by_id.get(&ws.0) { - Some(ws) => Ok(ws), - _ => Err(CphError::WorkspaceDoesNotExist(ws)), - } - } - - 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() - }) - } - fn get_device_handler_data( &self, device: InputDevice, @@ -667,34 +628,6 @@ impl ConfigProxyHandler { self.state.set_ei_socket_enabled(enabled); } - fn handle_get_workspace(&self, name: &str) { - self.respond(Response::GetWorkspace { - workspace: self.get_workspace_by_name(&name.to_owned()), - }); - } - - 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(()) - } - - 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(()) - } - fn handle_set_gfx_api(&self, device: Option, api: GfxApi) -> Result<(), CphError> { let Ok(api) = api.try_into() else { return Err(CphError::UnknownGfxApi(api)); @@ -776,16 +709,6 @@ impl ConfigProxyHandler { Ok(()) } - fn handle_get_default_workspace_capture(&self) { - self.respond(Response::GetDefaultWorkspaceCapture { - capture: self.state.default_workspace_capture.get(), - }); - } - - fn handle_set_default_workspace_capture(&self, capture: bool) { - self.state.default_workspace_capture.set(capture); - } - fn handle_set_double_click_interval_usec(&self, usec: u64) { self.state.double_click_interval_usec.set(usec); } @@ -794,93 +717,6 @@ impl ConfigProxyHandler { self.state.double_click_distance.set(dist); } - 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(()) - } - - 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(()) - } - - 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(()) - } - - 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(()) - } - - 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(()) - } - - 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(()) - } - fn handle_set_idle(&self, timeout: Duration) { self.state.idle.set_timeout(&self.state, timeout); } @@ -931,10 +767,6 @@ impl ConfigProxyHandler { Ok(()) } - fn handle_set_workspace_display_order(&self, order: WorkspaceDisplayOrder) { - self.state.set_workspace_display_order(order.into()); - } - fn handle_get_seat_float_pinned(&self, seat: Seat) -> Result<(), CphError> { let seat = self.get_seat(seat)?; self.respond(Response::GetFloatPinned { diff --git a/src/config/handler/workspaces.rs b/src/config/handler/workspaces.rs new file mode 100644 index 00000000..814bd016 --- /dev/null +++ b/src/config/handler/workspaces.rs @@ -0,0 +1,186 @@ +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()); + } +}