From f722905be1caf8003ba43f584df823a889d4b875 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Fri, 2 Aug 2024 12:26:03 -0700 Subject: [PATCH] feat(cli): add focus-stack-window cmd This commit adds a new command, focus-stack-window, which allows users to focus windows in the focused container stack by their index (zero-indexed) within the stack. If the user tries to focus an index which does not correspond to a window within the container stack, an error will be logged. --- komorebi/src/core/mod.rs | 5 +++-- komorebi/src/process_command.rs | 4 ++++ komorebi/src/window_manager.rs | 25 +++++++++++++++++++++++++ komorebic/src/main.rs | 17 ++++++++++++----- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/komorebi/src/core/mod.rs b/komorebi/src/core/mod.rs index 036250fa..1f05edae 100644 --- a/komorebi/src/core/mod.rs +++ b/komorebi/src/core/mod.rs @@ -45,12 +45,13 @@ pub enum SocketMessage { CycleFocusWindow(CycleDirection), CycleMoveWindow(CycleDirection), StackWindow(OperationDirection), + UnstackWindow, + CycleStack(CycleDirection), + FocusStackWindow(usize), StackAll, UnstackAll, ResizeWindowEdge(OperationDirection, Sizing), ResizeWindowAxis(Axis, Sizing), - UnstackWindow, - CycleStack(CycleDirection), MoveContainerToMonitorNumber(usize), CycleMoveContainerToMonitor(CycleDirection), MoveContainerToWorkspaceNumber(usize), diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index b180d6d4..a1453f8f 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -228,6 +228,10 @@ impl WindowManager { self.cycle_container_window_in_direction(direction)?; self.focused_window()?.focus(self.mouse_follows_focus)?; } + SocketMessage::FocusStackWindow(idx) => { + self.focus_container_window(idx)?; + self.focused_window()?.focus(self.mouse_follows_focus)?; + } SocketMessage::ForceFocus => { let focused_window = self.focused_window()?; let focused_window_rect = WindowsApi::window_rect(focused_window.hwnd())?; diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 8044f477..c42a8b3f 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -1534,6 +1534,31 @@ impl WindowManager { self.update_focused_workspace(self.mouse_follows_focus, true) } + #[tracing::instrument(skip(self))] + pub fn focus_container_window(&mut self, idx: usize) -> Result<()> { + self.handle_unmanaged_window_behaviour()?; + + tracing::info!("focusing container window at index {idx}"); + + let container = self.focused_container_mut()?; + + let len = NonZeroUsize::new(container.windows().len()) + .ok_or_else(|| anyhow!("there must be at least one window in a container"))?; + + if len.get() == 1 { + bail!("there is only one window in this container"); + } + + if container.windows().get(idx).is_none() { + bail!("there is no window in this container at index {idx}"); + } + + container.focus_window(idx); + container.load_focused_window(); + + self.update_focused_workspace(self.mouse_follows_focus, true) + } + #[tracing::instrument(skip(self))] pub fn stack_all(&mut self) -> Result<()> { self.handle_unmanaged_window_behaviour()?; diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 437385d6..8ede41a0 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -190,6 +190,7 @@ gen_target_subcommand_args! { FocusWorkspaces, MoveWorkspaceToMonitor, SwapWorkspacesWithMonitor, + FocusStackWindow, } macro_rules! gen_named_target_subcommand_args { @@ -944,6 +945,14 @@ enum SubCommand { /// Stack the focused window in the specified direction #[clap(arg_required_else_help = true)] Stack(Stack), + /// Unstack the focused window + Unstack, + /// Cycle the focused stack in the specified cycle direction + #[clap(arg_required_else_help = true)] + CycleStack(CycleStack), + /// Focus the specified window index in the focused stack + #[clap(arg_required_else_help = true)] + FocusStackWindow(FocusStackWindow), /// Stack all windows on the focused workspace StackAll, /// Unstack all windows in the focused container @@ -955,11 +964,6 @@ enum SubCommand { /// Resize the focused window or primary column along the specified axis #[clap(arg_required_else_help = true)] ResizeAxis(ResizeAxis), - /// Unstack the focused window - Unstack, - /// Cycle the focused stack in the specified cycle direction - #[clap(arg_required_else_help = true)] - CycleStack(CycleStack), /// Move the focused window to the specified monitor #[clap(arg_required_else_help = true)] MoveToMonitor(MoveToMonitor), @@ -2103,6 +2107,9 @@ Stop-Process -Name:komorebi -ErrorAction SilentlyContinue SubCommand::UnstackAll => { send_message(&SocketMessage::UnstackAll)?; } + SubCommand::FocusStackWindow(arg) => { + send_message(&SocketMessage::FocusStackWindow(arg.target))?; + } SubCommand::CycleStack(arg) => { send_message(&SocketMessage::CycleStack(arg.cycle_direction))?; }