Skip to content

Commit

Permalink
fix(wm): move ops on floating workspaces
Browse files Browse the repository at this point in the history
83f222f
* 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).

a026943
* 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!

4bf24f8
* 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.

cb53f46
* 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.
  • Loading branch information
alex-ds13 authored and LGUG2Z committed Nov 28, 2024
1 parent b22ec90 commit ed96b54
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 8 deletions.
35 changes: 30 additions & 5 deletions komorebi/src/process_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -669,6 +692,7 @@ impl WindowManager {
}
WindowManagerEvent::MouseCapture(..)
| WindowManagerEvent::Cloak(..)
| WindowManagerEvent::LocationChange(..)
| WindowManagerEvent::TitleUpdate(..) => {}
};

Expand Down Expand Up @@ -714,6 +738,7 @@ impl WindowManager {
if !matches!(
event,
WindowManagerEvent::Show(WinEvent::ObjectNameChange, _)
| WindowManagerEvent::LocationChange(_, _)
) {
tracing::info!("processed: {}", event.window().to_string());
} else {
Expand Down
10 changes: 8 additions & 2 deletions komorebi/src/window_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down
10 changes: 9 additions & 1 deletion komorebi/src/window_manager_event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub enum WindowManagerEvent {
Unmanage(Window),
Raise(Window),
TitleUpdate(WinEvent, Window),
LocationChange(WinEvent, Window),
}

impl Display for WindowManagerEvent {
Expand Down Expand Up @@ -78,6 +79,9 @@ impl Display for WindowManagerEvent {
Self::TitleUpdate(winevent, window) => {
write!(f, "TitleUpdate (WinEvent: {winevent}, Window: {window})")
}
Self::LocationChange(winevent, window) => {
write!(f, "LocationChange (WinEvent: {winevent}, Window: {window})")
}
}
}
}
Expand All @@ -98,7 +102,8 @@ impl WindowManagerEvent {
| Self::Raise(window)
| Self::Manage(window)
| Self::Unmanage(window)
| Self::TitleUpdate(_, window) => window,
| Self::TitleUpdate(_, window)
| Self::LocationChange(_, window) => window,
}
}

Expand All @@ -122,6 +127,7 @@ impl WindowManagerEvent {
WindowManagerEvent::Unmanage(_) => "Unmanage",
WindowManagerEvent::Raise(_) => "Raise",
WindowManagerEvent::TitleUpdate(_, _) => "TitleUpdate",
WindowManagerEvent::LocationChange(_, _) => "LocationChange",
}
}

Expand All @@ -137,6 +143,7 @@ impl WindowManagerEvent {
| WindowManagerEvent::MoveResizeStart(event, _)
| WindowManagerEvent::MoveResizeEnd(event, _)
| WindowManagerEvent::MouseCapture(event, _)
| WindowManagerEvent::LocationChange(event, _)
| WindowManagerEvent::TitleUpdate(event, _) => Some(event.to_string()),
WindowManagerEvent::Manage(_)
| WindowManagerEvent::Unmanage(_)
Expand Down Expand Up @@ -202,6 +209,7 @@ impl WindowManagerEvent {
Option::from(Self::TitleUpdate(winevent, window))
}
}
WinEvent::ObjectLocationChange => Option::from(Self::LocationChange(winevent, window)),
_ => None,
}
}
Expand Down

0 comments on commit ed96b54

Please sign in to comment.