mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-01-11 22:12:53 +01:00
feat(cli): add cycle-empty-workspace cmd
This commit adds a variation of the cycle-workspace command which will attempt to focus the next empty workspace in the given direction (with the usual wraparound). If there are no empty workspaces available, this command will do nothing.
This commit is contained in:
16
docs/cli/cycle-empty-workspace.md
Normal file
16
docs/cli/cycle-empty-workspace.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# cycle-empty-workspace
|
||||
|
||||
```
|
||||
Focus the next empty workspace in the given cycle direction (if one exists)
|
||||
|
||||
Usage: komorebic.exe cycle-empty-workspace <CYCLE_DIRECTION>
|
||||
|
||||
Arguments:
|
||||
<CYCLE_DIRECTION>
|
||||
[possible values: previous, next]
|
||||
|
||||
Options:
|
||||
-h, --help
|
||||
Print help
|
||||
|
||||
```
|
||||
@@ -122,6 +122,7 @@ pub enum SocketMessage {
|
||||
Load(PathBuf),
|
||||
CycleFocusMonitor(CycleDirection),
|
||||
CycleFocusWorkspace(CycleDirection),
|
||||
CycleFocusEmptyWorkspace(CycleDirection),
|
||||
FocusMonitorNumber(usize),
|
||||
FocusMonitorAtCursor,
|
||||
FocusLastWorkspace,
|
||||
|
||||
@@ -205,7 +205,9 @@ impl WindowManager {
|
||||
let initial_state = State::from(self.as_ref());
|
||||
|
||||
match message {
|
||||
SocketMessage::CycleFocusWorkspace(_) | SocketMessage::FocusWorkspaceNumber(_) => {
|
||||
SocketMessage::CycleFocusEmptyWorkspace(_)
|
||||
| SocketMessage::CycleFocusWorkspace(_)
|
||||
| SocketMessage::FocusWorkspaceNumber(_) => {
|
||||
if let Some(monitor) = self.focused_monitor_mut() {
|
||||
let idx = monitor.focused_workspace_idx();
|
||||
monitor.set_last_focused_workspace(Option::from(idx));
|
||||
@@ -900,6 +902,55 @@ impl WindowManager {
|
||||
|
||||
self.focus_workspace(workspace_idx)?;
|
||||
}
|
||||
SocketMessage::CycleFocusEmptyWorkspace(direction) => {
|
||||
// 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() {
|
||||
if monitor_idx != self.focused_monitor_idx() {
|
||||
if let Some(monitor) = self.monitors().get(monitor_idx) {
|
||||
if let Some(workspace) = monitor.focused_workspace() {
|
||||
if workspace.is_empty() {
|
||||
self.focus_monitor(monitor_idx)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let focused_monitor = self
|
||||
.focused_monitor()
|
||||
.ok_or_else(|| anyhow!("there is no monitor"))?;
|
||||
|
||||
let focused_workspace_idx = focused_monitor.focused_workspace_idx();
|
||||
let workspaces = focused_monitor.workspaces().len();
|
||||
|
||||
let mut empty_workspaces = vec![];
|
||||
|
||||
for (idx, w) in focused_monitor.workspaces().iter().enumerate() {
|
||||
if w.is_empty() {
|
||||
empty_workspaces.push(idx);
|
||||
}
|
||||
}
|
||||
|
||||
if !empty_workspaces.is_empty() {
|
||||
let mut workspace_idx = direction.next_idx(
|
||||
focused_workspace_idx,
|
||||
NonZeroUsize::new(workspaces)
|
||||
.ok_or_else(|| anyhow!("there must be at least one workspace"))?,
|
||||
);
|
||||
|
||||
while !empty_workspaces.contains(&workspace_idx) {
|
||||
workspace_idx = direction.next_idx(
|
||||
workspace_idx,
|
||||
NonZeroUsize::new(workspaces)
|
||||
.ok_or_else(|| anyhow!("there must be at least one workspace"))?,
|
||||
);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -155,6 +155,7 @@ gen_enum_subcommand_args! {
|
||||
CycleMoveToMonitor: CycleDirection,
|
||||
CycleMonitor: CycleDirection,
|
||||
CycleWorkspace: CycleDirection,
|
||||
CycleEmptyWorkspace: CycleDirection,
|
||||
CycleMoveWorkspaceToMonitor: CycleDirection,
|
||||
Stack: OperationDirection,
|
||||
CycleStack: CycleDirection,
|
||||
@@ -1129,6 +1130,9 @@ enum SubCommand {
|
||||
/// Focus the workspace in the given cycle direction
|
||||
#[clap(arg_required_else_help = true)]
|
||||
CycleWorkspace(CycleWorkspace),
|
||||
/// Focus the next empty workspace in the given cycle direction (if one exists)
|
||||
#[clap(arg_required_else_help = true)]
|
||||
CycleEmptyWorkspace(CycleWorkspace),
|
||||
/// Move the focused workspace to the specified monitor
|
||||
#[clap(arg_required_else_help = true)]
|
||||
MoveWorkspaceToMonitor(MoveWorkspaceToMonitor),
|
||||
@@ -2624,6 +2628,11 @@ if (Get-Command Get-CimInstance -ErrorAction SilentlyContinue) {
|
||||
SubCommand::CycleWorkspace(arg) => {
|
||||
send_message(&SocketMessage::CycleFocusWorkspace(arg.cycle_direction))?;
|
||||
}
|
||||
SubCommand::CycleEmptyWorkspace(arg) => {
|
||||
send_message(&SocketMessage::CycleFocusEmptyWorkspace(
|
||||
arg.cycle_direction,
|
||||
))?;
|
||||
}
|
||||
SubCommand::NewWorkspace => {
|
||||
send_message(&SocketMessage::NewWorkspace)?;
|
||||
}
|
||||
|
||||
@@ -136,6 +136,7 @@ nav:
|
||||
- cli/close-workspace.md
|
||||
- cli/cycle-monitor.md
|
||||
- cli/cycle-workspace.md
|
||||
- cli/cycle-empty-workspace.md
|
||||
- cli/move-workspace-to-monitor.md
|
||||
- cli/cycle-move-workspace-to-monitor.md
|
||||
- cli/swap-workspaces-with-monitor.md
|
||||
|
||||
Reference in New Issue
Block a user