feat(cli): add close-workspace cmd

This commit introduces a new komorebic command, close-workspace. This
command will remove the focused workspace from the window manager state
if the following conditions are met:

1. The number of workspaces on the focused monitor are >1
2. The workspace is empty
3. The workspace is unnamed

The third condition is to ensure that we are not removing workspaces
which have been declared in the static configuration file.
This commit is contained in:
LGUG2Z
2024-11-04 12:39:06 -08:00
parent dc1eb8ff50
commit 0f022d47df
4 changed files with 55 additions and 11 deletions

22
Cargo.lock generated
View File

@@ -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",

View File

@@ -114,6 +114,7 @@ pub enum SocketMessage {
CycleFocusWorkspace(CycleDirection),
FocusMonitorNumber(usize),
FocusLastWorkspace,
CloseWorkspace,
FocusWorkspaceNumber(usize),
FocusWorkspaceNumbers(usize),
FocusMonitorWorkspaceNumber(usize, usize),

View File

@@ -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

View File

@@ -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))?;
}