diff --git a/Cargo.lock b/Cargo.lock index edc2ac3c..fef409ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -222,9 +222,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.17" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -277,9 +277,9 @@ checksum = "74f37166d7d48a0284b99dd824694c26119c700b53bf0d1540cdb147dbdaaf13" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "775a8770d29db3dadcb858482cc240af7b2ffde4ac4de67d1d4955728103f0e2" [[package]] name = "arboard" @@ -2117,9 +2117,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" [[package]] name = "hassle-rs" @@ -2532,7 +2532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.1", ] [[package]] @@ -5091,18 +5091,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3c6efbfc763e64eb85c11c25320f0737cb7364c4b6336db90aa9ebe27a0bbd" +checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.67" +version = "1.0.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b607164372e89797d78b8e23a6d67d5d1038c1c65efd52e1389ef8b77caba2a6" +checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" dependencies = [ "proc-macro2", "quote", diff --git a/komorebi/src/core/mod.rs b/komorebi/src/core/mod.rs index 6e18aa7d..3f2a2399 100644 --- a/komorebi/src/core/mod.rs +++ b/komorebi/src/core/mod.rs @@ -114,6 +114,7 @@ pub enum SocketMessage { CycleFocusWorkspace(CycleDirection), FocusMonitorNumber(usize), FocusLastWorkspace, + CloseWorkspace, FocusWorkspaceNumber(usize), FocusWorkspaceNumbers(usize), FocusMonitorWorkspaceNumber(usize, usize), diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index c45a07fb..18fe5661 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -761,6 +761,44 @@ impl WindowManager { self.focus_workspace(workspace_idx)?; } + SocketMessage::CloseWorkspace => { + // This is to ensure that even on an empty workspace on a secondary monitor, the + // secondary monitor where the cursor is focused will be used as the target for + // the workspace switch op + if let Some(monitor_idx) = self.monitor_idx_from_current_pos() { + self.focus_monitor(monitor_idx)?; + } + + let mut can_close = false; + + if let Some(monitor) = self.focused_monitor_mut() { + let focused_workspace_idx = monitor.focused_workspace_idx(); + let last_focused_workspace = monitor + .last_focused_workspace() + .unwrap_or(focused_workspace_idx.saturating_sub(1)); + + if let Some(workspace) = monitor.focused_workspace() { + if monitor.workspaces().len() > 1 + && workspace.containers().is_empty() + && workspace.floating_windows().is_empty() + && workspace.monocle_container().is_none() + && workspace.maximized_window().is_none() + && workspace.name().is_none() + { + can_close = true; + } + } + + if can_close + && monitor + .workspaces_mut() + .remove(focused_workspace_idx) + .is_some() + { + self.focus_workspace(last_focused_workspace)?; + } + } + } SocketMessage::FocusLastWorkspace => { // This is to ensure that even on an empty workspace on a secondary monitor, the // secondary monitor where the cursor is focused will be used as the target for diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 5451ac9d..7c60031e 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -1052,6 +1052,8 @@ enum SubCommand { /// Focus the specified workspace #[clap(arg_required_else_help = true)] FocusNamedWorkspace(FocusNamedWorkspace), + /// Close the focused workspace (must be empty and unnamed) + CloseWorkspace, /// Focus the monitor in the given cycle direction #[clap(arg_required_else_help = true)] CycleMonitor(CycleMonitor), @@ -2338,6 +2340,9 @@ Stop-Process -Name:komorebi -ErrorAction SilentlyContinue SubCommand::FocusNamedWorkspace(arg) => { send_message(&SocketMessage::FocusNamedWorkspace(arg.workspace))?; } + SubCommand::CloseWorkspace => { + send_message(&SocketMessage::CloseWorkspace)?; + } SubCommand::CycleMonitor(arg) => { send_message(&SocketMessage::CycleFocusMonitor(arg.cycle_direction))?; }