From c3f135703eb4ea1263311e509af2afb897662030 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Sun, 22 Sep 2024 11:47:07 -0700 Subject: [PATCH] fix(wm): cross-border focus direction awareness This commit ensures that when focusing across a monitor boundary to the left, the container at the back of the Ring in the target workspace will be focused, and when focusing across a monitor boundary to the right, the one at the front will be focused. --- komorebi/src/window_manager.rs | 37 ++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 7ac5c7023..99d33079a 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -1259,6 +1259,7 @@ impl WindowManager { let mut cross_monitor_monocle = false; + // this is for when we are scrolling across workspaces like PaperWM if new_idx.is_none() && matches!( self.cross_boundary_behaviour, @@ -1289,6 +1290,22 @@ impl WindowManager { self.focus_workspace(next_idx)?; + if let Ok(focused_workspace) = self.focused_workspace_mut() { + if focused_workspace.monocle_container().is_none() { + match direction { + OperationDirection::Left => { + focused_workspace.focus_container( + focused_workspace.containers().len().saturating_sub(1), + ); + } + OperationDirection::Right => { + focused_workspace.focus_container(0); + } + _ => {} + }; + } + } + return Ok(()); } @@ -1300,17 +1317,30 @@ impl WindowManager { .ok_or_else(|| anyhow!("there is no container or monitor in this direction"))?; self.focus_monitor(monitor_idx)?; + let mouse_follows_focus = self.mouse_follows_focus; - if let Ok(focused_workspace) = self.focused_workspace() { + if let Ok(focused_workspace) = self.focused_workspace_mut() { if let Some(monocle) = focused_workspace.monocle_container() { if let Some(window) = monocle.focused_window() { - window.focus(self.mouse_follows_focus)?; + window.focus(mouse_follows_focus)?; WindowsApi::center_cursor_in_rect(&WindowsApi::window_rect( window.hwnd(), )?)?; cross_monitor_monocle = true; } + } else { + match direction { + OperationDirection::Left => { + focused_workspace.focus_container( + focused_workspace.containers().len().saturating_sub(1), + ); + } + OperationDirection::Right => { + focused_workspace.focus_container(0); + } + _ => {} + }; } } } @@ -1348,6 +1378,7 @@ impl WindowManager { let origin_monitor_idx = self.focused_monitor_idx(); let target_container_idx = workspace.new_idx_for_direction(direction); + // this is for when we are scrolling across workspaces like PaperWM if target_container_idx.is_none() && matches!( self.cross_boundary_behaviour, @@ -1376,6 +1407,8 @@ impl WindowManager { _ => workspace_idx, }; + // passing the direction here is how we handle whether to insert at the front + // or the back of the container vecdeque in the target workspace self.move_container_to_workspace(next_idx, true, Some(direction))?; self.update_focused_workspace(self.mouse_follows_focus, true)?;