From b985659e30b90d43ff6c68ffb1cb5da6d9e37370 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Wed, 26 Jun 2024 11:45:47 -0700 Subject: [PATCH] feat(wm): dynamic lookup for container behaviour This commit adds a dynamic lookup method for the window_container_behaviour configuration option. Previously if the behaviour was set to Append, and the workspace did not have any containers, an error would be logged. Now, in the same situation, the behaviour will be dynamically switched to Create when there are no containers on a workspace, and subsequent windows will be handled with the Append behaviour if set. This commit also makes some tweaks to ensure that when a windows in a container stack are closed, the container itself will remain focused if it has at least one remaining window. resolve #889 --- komorebi/src/process_event.rs | 11 +++++++---- komorebi/src/window_manager.rs | 18 ++++++++++++++++++ komorebi/src/workspace.rs | 3 +++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index f2a4db0b..d545ef1a 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -329,7 +329,8 @@ impl WindowManager { } if proceed { - let behaviour = self.window_container_behaviour; + let behaviour = + self.window_container_behaviour(focused_monitor_idx, focused_workspace_idx); let workspace = self.focused_workspace_mut()?; let workspace_contains_window = workspace.contains_window(window.hwnd); let monocle_container = workspace.monocle_container().clone(); @@ -399,10 +400,12 @@ impl WindowManager { .monitor_idx_from_current_pos() .ok_or_else(|| anyhow!("cannot get monitor idx from current position"))?; - let new_window_behaviour = self.window_container_behaviour; + let focused_monitor_idx = self.focused_monitor_idx(); + let focused_workspace_idx = self.focused_workspace_idx().unwrap_or_default(); + let window_container_behaviour = + self.window_container_behaviour(focused_monitor_idx, focused_workspace_idx); let workspace = self.focused_workspace_mut()?; - let focused_container_idx = workspace.focused_container_idx(); let new_position = WindowsApi::window_rect(window.hwnd())?; let old_position = *workspace @@ -519,7 +522,7 @@ impl WindowManager { // Here we handle a simple move on the same monitor which is treated as // a container swap } else { - match new_window_behaviour { + match window_container_behaviour { WindowContainerBehaviour::Create => { match workspace.container_idx_from_current_point() { Some(target_idx) => { diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 53a0e026..d2cf2203 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -303,6 +303,24 @@ impl WindowManager { StaticConfig::reload(pathbuf, self) } + pub fn window_container_behaviour( + &self, + monitor_idx: usize, + workspace_idx: usize, + ) -> WindowContainerBehaviour { + if let Some(monitor) = self.monitors().get(monitor_idx) { + if let Some(workspace) = monitor.workspaces().get(workspace_idx) { + return if workspace.containers().is_empty() { + WindowContainerBehaviour::Create + } else { + self.window_container_behaviour + }; + } + } + + WindowContainerBehaviour::Create + } + #[tracing::instrument(skip(self))] pub fn watch_configuration(&mut self, enable: bool) -> Result<()> { let config_pwsh = HOME_DIR.join("komorebi.ps1"); diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index 44982143..672bd61f 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -748,6 +748,9 @@ impl Workspace { self.focus_previous_container(); } else { container.load_focused_window(); + if let Some(window) = container.focused_window() { + window.focus(false)?; + } } Ok(())