fix(engine): mitigate focus corruption from boundary raise races#355
Open
qeude wants to merge 1 commit intoacsandmann:mainfrom
Open
fix(engine): mitigate focus corruption from boundary raise races#355qeude wants to merge 1 commit intoacsandmann:mainfrom
qeude wants to merge 1 commit intoacsandmann:mainfrom
Conversation
When MoveFocus hits a boundary in a scrolling layout, the engine was falling back and returning ALL visible tiled windows as raise_windows. Holding down the focus key floods RaiseManager with sequences, each raising N windows. The queue backs up, so OS focus confirmations (WindowFocused) arrive out of order and can interfere with the engine's current focus state. - Boundary fallback: only focus the selected window, don't raise every visible tiled window. This stops the raise queue from exploding when a focus key is held at the edge. - WindowFocused guard: ignore the event if the window is not present in the active workspace/layout. Stale/delayed focus confirmations for windows that have left the layout are dropped instead of corrupting focused_window. This mitigates the focus corruption described in acsandmann#285. Further work may be needed to fully eliminate races between delayed OS confirmations and subsequent focus commands.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR mitigates a bug where keyboard focus can become stuck or behave erratically when repeatedly moving focus at layout boundaries (e.g., holding down the focus-left key in a scrolling layout).
Contributing factor: When a directional focus command hits a boundary, the engine previously fell back by queuing a raise request for every visible tiled window. Rapidly sending focus commands floods the
RaiseManagerqueue, causing focus confirmations from the OS to arrive out of order. These delayedWindowFocusedevents can then interfere with the engine's current focus state.Changes
move_focus_internal): When there is no adjacent focus target, only keep focus on the current selection. Previously the engine returned all visible windows asraise_windows, causing an unbounded queue backlog when the focus key is held at the edge. Now returnsraise_windows: vec![].WindowFocused): Before accepting aWindowFocusedevent, verify the reported window is still present in the active workspace/layout. Stale/delayed focus confirmations for windows that have left the layout are now dropped instead of corruptingfocused_window.Scope
This mitigates the focus corruption described in #285. Further work may be needed to fully eliminate races between delayed OS confirmations and subsequent focus commands (e.g., tracking a focus generation number to ignore confirmations older than the last explicit
MoveFocus).Files changed
src/layout_engine/engine.rs(+12 / −6)