Summary
Fixes #16114 by refreshing floating-workspace exclusions when personal window rules register after saved workspace modes. This implements the change notification suggested in the issue.
The first matching window now stays outside the floating mode's ownership, just like subsequent matching windows. Ending floating mode leaves these windows floating.
Why the first window is affected
The shipped hyprland.lua loads saved workspace modes through default.hypr.toggles before its personal-configuration section. A saved floating mode builds its opening rules from the float patterns currently recorded in o.floating_apps.
A later o.window(..., { float = true }) records a new pattern, but the generated exclusions previously stayed unchanged. The first matching window therefore received the mode's size and opening tag. claim_opened() claimed that window and refreshed the rules, making subsequent matching windows behave correctly. The incorrect ownership also caused the first window to become tiled when floating mode ended.
Fix logic
- Track whether
o.window()records a float pattern or a class/title-to-tag relationship. - After registering the window rule, notify
o.floating_apps_changedwhen that registry changed. - Set that hook to
sync_open_rules()in the workspace-mode module, so exclusions are current before the first matching window opens. Notifying for both float rules and tagging rules handles either registration order. - Clear the previous hook when helpers reload, avoiding calls into the preceding configuration's workspace-mode state.
Unrelated window rules do not trigger a refresh. The fix uses the existing rule-generation path and adds no polling or configuration migration.
Regression coverage
The added regression fails against unchanged production code with a late class float rule did not refresh the first-window exclusion, then passes with this patch.
Five new regression groups cover late class/title rules, either half of a late tag relationship, both tag-related rules registered late in either order, multiple floating workspaces and disabled modes, and avoiding unrelated refreshes or stale callbacks after helpers reload.
Focused validation completed on the submitted sources:
| Suite | Passing checks |
|---|---|
| Floating workspaces | 45 |
| Workspace layout | 15 |
| Workspace-mode migration | 2 |
| Total | 62 |
OMARCHY_PATH="$PWD" bash test/shell.d/hyprland-floating-workspaces-test.sh
OMARCHY_PATH="$PWD" bash test/shell.d/hyprland-workspace-layout-test.sh
OMARCHY_PATH="$PWD" bash test/shell.d/workspace-layout-mode-migration-test.sh
luac -p default/hypr/helpers.lua
luac -p default/hypr/workspace-modes.lua
bash -n test/shell.d/hyprland-floating-workspaces-test.sh
git diff --checkNative before/after result
Reproduced using the real Omarchy modules in a sandboxed, nested Hyprland 0.56.2 compositor accelerated by a Radeon 8060S on a Ryzen AI Max+ PRO 395. The configuration restores a floating workspace before registering the personal rule. Two matching foot terminals request 100×8 cells, resolving to 600×120 pixels in this fixture; an ordinary terminal checks that workspace mode still manages normal windows.
| Observation | Unchanged upstream | With this patch |
|---|---|---|
| First class-matching terminal | 436×578, incorrectly mode-owned | 600×120, unclaimed |
| Second class-matching terminal | 600×120, unclaimed | 600×120, unclaimed |
| First matching terminal when floating mode ends | Incorrectly tiled | Remains floating at 600×120 |
| Ordinary control terminal | Mode-owned, then tiled on mode exit | Mode-owned, then tiled on mode exit |
All 16 native comparison assertions passed, including title-rule ownership, mode exit, and completion without configuration errors. Before/after screenshots were also inspected.
Validation scope
The title-only case also stops being claimed and remains floating on mode exit. In this minimal nested configuration, however, its first terminal negotiates 682×850 even with the personal rule registered early on unchanged upstream. The patched late-rule case matches that unaffected early-rule control. This patch corrects stale exclusions and mode ownership; it does not establish a general fix for initial title-based size negotiation.
The comparison uses current upstream modules in an isolated configuration, rather than a full installed Omarchy 4.5 session. Confirmation in the reporter's complete configuration would be useful.
[Medium impact] The PR appears safe to merge; no actionable issues were found.
Summary
Updates floating-workspace exclusions as personal window rules are registered, before the first matching window opens.
No actionable issues were found. Review checks were based on source inspection and a clean
git diff --check; no runtime or visual verification was performed.Diagram
Reviews (1) · Last reviewed commit: "Refresh floating workspace exclusions fo..." · Reviewed by Greptile