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<Container> 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.
This commit is contained in:
LGUG2Z
2024-09-22 11:47:07 -07:00
parent 3720ce42d0
commit c3f135703e

View File

@@ -1259,6 +1259,7 @@ impl WindowManager {
let mut cross_monitor_monocle = false; let mut cross_monitor_monocle = false;
// this is for when we are scrolling across workspaces like PaperWM
if new_idx.is_none() if new_idx.is_none()
&& matches!( && matches!(
self.cross_boundary_behaviour, self.cross_boundary_behaviour,
@@ -1289,6 +1290,22 @@ impl WindowManager {
self.focus_workspace(next_idx)?; 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(()); return Ok(());
} }
@@ -1300,17 +1317,30 @@ impl WindowManager {
.ok_or_else(|| anyhow!("there is no container or monitor in this direction"))?; .ok_or_else(|| anyhow!("there is no container or monitor in this direction"))?;
self.focus_monitor(monitor_idx)?; 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(monocle) = focused_workspace.monocle_container() {
if let Some(window) = monocle.focused_window() { 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( WindowsApi::center_cursor_in_rect(&WindowsApi::window_rect(
window.hwnd(), window.hwnd(),
)?)?; )?)?;
cross_monitor_monocle = true; 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 origin_monitor_idx = self.focused_monitor_idx();
let target_container_idx = workspace.new_idx_for_direction(direction); 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() if target_container_idx.is_none()
&& matches!( && matches!(
self.cross_boundary_behaviour, self.cross_boundary_behaviour,
@@ -1376,6 +1407,8 @@ impl WindowManager {
_ => workspace_idx, _ => 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.move_container_to_workspace(next_idx, true, Some(direction))?;
self.update_focused_workspace(self.mouse_follows_focus, true)?; self.update_focused_workspace(self.mouse_follows_focus, true)?;