Skip to content

fix(wm): refocus selection on destroy when foreground goes null#1727

Open
MattKotsenas wants to merge 1 commit into
LGUG2Z:masterfrom
MattKotsenas:fix/refocus-on-destroy
Open

fix(wm): refocus selection on destroy when foreground goes null#1727
MattKotsenas wants to merge 1 commit into
LGUG2Z:masterfrom
MattKotsenas:fix/refocus-on-destroy

Conversation

@MattKotsenas

@MattKotsenas MattKotsenas commented Jul 14, 2026

Copy link
Copy Markdown

Problem

Closing the focused (foreground) tiled window sometimes does not move focus to a surviving neighbor. komorebi removes the window and re-tiles, but no managed window regains focus. Borders render unfocused on every window and keystrokes do nothing until the user refocuses by hand.

Root cause

The removal handlers (Destroy/Unmanage, Minimize, Hide) call update_focused_workspace(false, false), which re-tiles but leaves focus to the OS. komorebi reconciles its selection in the FocusChange handler once Windows promotes a successor. From looking at git blame, this appears intended to prevent focus fights.

When the focused window is destroyed, Windows does not always promote a successor. When it promotes nothing, the foreground becomes null, no FocusChange arrives, and the selection never regains OS focus.

Fix

Keep the reactive no-force-focus default and add a narrow fallback in the Destroy/Unmanage handler: when the OS foreground is null after removal, follow and trigger focus so update_focused_workspace restores komorebi's own selection (maximized/monocle/tiling). A non-null foreground is still left to FocusChange, so the OS is not fought and the should_skip_focus_change desync should not occur.

Added a small predicate (should_refocus_after_destroy) with unit tests, mirroring the existing should_skip_focus_change.

Notes

I haven't been able to reproduce the behavior in the Minimize or Hide paths, so I haven't touched them. It's probably safe to extend the fix there too, so happy to include those paths as well if desired.

Reactive events pass trigger_focus=false so komorebi follows the OS
foreground and reconciles via the FocusChange handler once Windows
promotes a successor window. When the destroyed window was the
foreground and Windows promotes nothing, the foreground becomes null,
no FocusChange arrives, and komorebi's selection never regains OS focus,
leaving every border unfocused until the user refocuses by hand.

Add a narrow fallback in the Destroy/Unmanage handler: when the OS
foreground is null after removal, focus the current selection. Any
non-null foreground is left to FocusChange, so the OS is not fought and
the should_skip_focus_change desync cannot occur.
@MattKotsenas MattKotsenas reopened this Jul 14, 2026
@MattKotsenas MattKotsenas marked this pull request as ready for review July 14, 2026 04:46
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