fix(wm): move ops on floating workspaces

83f222fe84
* fix(wm): correctly define moves across monitors

Moves within the same workspace were being considered as moves across
monitors when the workspace was floating (not tiled).

This commit fixes this by changing the way we first define if a move was
across monitor or not.

We now search for the moved window on all workspaces and check if its
monitor index is different from the target monitor index (the monitor
where the move ended).

a02694348e
* fix(wm): ignore moves/resizes on floating workspaces

This commit makes sure that moves or resizes within a floating workspace
(i.e. not tiled) will be ignored, unless the move is across monitors.
We don't care about the positions or sizes of windows within a floating
workspace!

4bf24f81e0
* fix(wm): avoid workspace load on cross monitor moves

This commit replaces the `window_manager.focus_workspace` call with a
`monitor.focus_workspace` which doesn't load the workspace. There is no
need to load the workspace when moving windows across monitors since
those workspaces will already be loaded, we simply need to update them.
Loading the workspace would cause some issues as well, like when moving
a window to a floating workspace which already contained a window that
matched some `floating_windows` rules was always putting the
"floating_window" on top of the window we just moved with a bunch of
focus flickering. This is fixed with this commit.

cb53f463ae
* fix(wm): avoid workspace load on command move across monitor

If the move happens between the already focused workspaces of two
monitors we shouldn't load the workspace, since it is already loaded and
it will cause changes on focused windows, which might result on the
window we just moved not being focused.
This commit is contained in:
alex-ds13
2024-11-28 22:58:29 +00:00
committed by LGUG2Z
parent b22ec90438
commit e6ddccc5f6
2 changed files with 36 additions and 7 deletions

View File

@@ -485,8 +485,21 @@ impl WindowManager {
// place across a monitor boundary to an empty workspace
.unwrap_or(&Rect::default());
// This will be true if we have moved to an empty workspace on another monitor
let mut moved_across_monitors = old_position == Rect::default();
// This will be true if we have moved to another monitor
let mut moved_across_monitors = false;
for (i, monitors) in self.monitors().iter().enumerate() {
for workspace in monitors.workspaces() {
if workspace.contains_window(window.hwnd) && i != target_monitor_idx {
moved_across_monitors = true;
break;
}
}
if moved_across_monitors {
break;
}
}
if let Some((origin_monitor_idx, origin_workspace_idx, _)) = pending {
// If we didn't move to another monitor with an empty workspace, it is
// still possible that we moved to another monitor with a populated workspace
@@ -517,7 +530,9 @@ impl WindowManager {
}
let workspace = self.focused_workspace_mut()?;
if workspace.contains_managed_window(window.hwnd) || moved_across_monitors {
if (*workspace.tile() && workspace.contains_managed_window(window.hwnd))
|| moved_across_monitors
{
let resize = Rect {
left: new_position.left - old_position.left,
top: new_position.top - old_position.top,
@@ -570,11 +585,19 @@ impl WindowManager {
// so that we don't have ghost tiles until we force an interaction on
// the origin monitor's focused workspace
self.focus_monitor(origin_monitor_idx)?;
self.focus_workspace(origin_workspace_idx)?;
let origin_monitor = self
.monitors_mut()
.get_mut(origin_monitor_idx)
.ok_or_else(|| anyhow!("there is no monitor at this idx"))?;
origin_monitor.focus_workspace(origin_workspace_idx)?;
self.update_focused_workspace(false, false)?;
self.focus_monitor(target_monitor_idx)?;
self.focus_workspace(target_workspace_idx)?;
let target_monitor = self
.monitors_mut()
.get_mut(target_monitor_idx)
.ok_or_else(|| anyhow!("there is no monitor at this idx"))?;
target_monitor.focus_workspace(target_workspace_idx)?;
self.update_focused_workspace(false, false)?;
// Make sure to give focus to the moved window again

View File

@@ -1437,8 +1437,12 @@ impl WindowManager {
.get_mut(monitor_idx)
.ok_or_else(|| anyhow!("there is no monitor"))?;
let mut should_load_workspace = false;
if let Some(workspace_idx) = workspace_idx {
target_monitor.focus_workspace(workspace_idx)?;
if workspace_idx != target_monitor.focused_workspace_idx() {
target_monitor.focus_workspace(workspace_idx)?;
should_load_workspace = true;
}
}
let target_workspace = target_monitor
.focused_workspace_mut()
@@ -1469,7 +1473,9 @@ impl WindowManager {
bail!("failed to find a window to move");
}
target_monitor.load_focused_workspace(mouse_follows_focus)?;
if should_load_workspace {
target_monitor.load_focused_workspace(mouse_follows_focus)?;
}
target_monitor.update_focused_workspace(offset)?;
// this second one is for DPI changes when the target is another monitor