Skip to content

fix(movetoworkspace): follow floating window to destination monitor#305

Open
sim590 wants to merge 3 commits into
outfoxxed:masterfrom
sim590:fix/movetoworkspace-floating-focus
Open

fix(movetoworkspace): follow floating window to destination monitor#305
sim590 wants to merge 3 commits into
outfoxxed:masterfrom
sim590:fix/movetoworkspace-floating-focus

Conversation

@sim590

@sim590 sim590 commented May 4, 2026

Copy link
Copy Markdown

Problem

When a focused floating window is moved to another workspace with follow=true (e.g. via hy3:movetoworkspace <ws>,follow), keyboard focus and active monitor do not reliably follow the window.

Two bugs combine to cause this:

1. Wrong follow path when a tiled window exists on the origin workspace

getWorkspaceFocusedNode(origin) returns the hy3 node of a tiled window on the origin workspace even though the focused window is floating (and has no hy3 node). The if (node != nullptr) branch in the follow block then calls node->focus() on that tiled window, stealing both keyboard focus and active monitor from the floating window we just moved.

2. Monitor focus not explicitly updated

fullWindowFocus and monitor->changeWorkspace do not call rawMonitorFocus directly. Monitor focus only updates as a side-effect of cursor warping via simulateMouseMovement, which is skipped when misc:mouse_move_focuses_monitor = 0 or the cursor is already within the window bounds.

Fix

  • Introduce moved_floating to track whether the dispatched action moved a floating window. When true, skip the node->focus() path in the follow block even if node != nullptr.
  • Call fullWindowFocus on the floating window to set keyboard focus with a keybind reason (hard focus), regardless of input:follow_mouse.
  • Call rawMonitorFocus with the destination monitor explicitly so the active monitor is always correct, regardless of cursor position or misc:mouse_move_focuses_monitor.

Reproduction

# hyprland.conf — bind mod+o to split-changemonitor
bind = $mod, o, split-changemonitor, +1
  1. Open a floating terminal on monitor 1 and a tiled window on monitor 2
  2. Focus the floating terminal
  3. Press mod+o repeatedly — before this fix, focus would jump to the tiled window after the first move

sim590 added 3 commits May 27, 2026 14:39
When a floating window is moved to another workspace with follow=true,
node is nullptr so the original node->focus() call was skipped (guard
added in previous fix). As a result, fullWindowFocus was never called
and the active monitor remained the origin monitor.

Call fullWindowFocus directly on the focused floating window so that
the active monitor is updated correctly after the move.
…ng window

fullWindowFocus does not call rawMonitorFocus directly. The monitor
focus was only updated as a side effect of cursor warping via
simulateMouseMovement, which is skipped when input:follow_mouse is 0
or when the cursor is already within the window's new bounds.

Call rawMonitorFocus with the destination monitor explicitly after
fullWindowFocus and warpCursorToBox so that the active monitor is
reliably updated on every move, regardless of cursor position or
follow_mouse setting.
…s floating

When follow=true and a floating window was moved, getWorkspaceFocusedNode
may return a non-null hy3 node from the origin workspace (a tiled window).
The if (node != nullptr) branch then focused that tiled window instead of
the floating window we just moved, losing both keyboard and monitor focus.

Track whether the move was for a floating window and skip the node focus
path in that case, always falling through to the floating window follow
logic instead.
@sim590
sim590 force-pushed the fix/movetoworkspace-floating-focus branch from 5b1f0d2 to 3a7de57 Compare May 27, 2026 18:39
@sim590
sim590 changed the base branch from 0.54 to master May 27, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant