Repository navigation
focus_trap: End the Tab search at the first repeated stop - #3642
Merged
Merged
Conversation
advance_focus stopped only when focus came back to the first stop it reached. A tab order that cycles without passing that stop, such as a stop whose previous stop is itself, made Tab or Shift-Tab out of a trap loop forever. The search now ends at any repeated stop and focuses the trap's container, as it already did for a trap without reachable stops. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
boboshan
marked this pull request as ready for review
October 22, 2026 12:48
huacnlee
enabled auto-merge (squash)
October 24, 2026 03:56
huacnlee
approved these changes
Oct 24, 2026
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.
Description
In an active focus trap,
advance_focus(Tab and Shift-Tab) walks the window's tab order until focus is inside the trap, and stops early only when focus comes back to the first stop it reached. If GPUI's tab order cycles without passing that stop, it never comes back. We hit this with Shift-Tab from a modal in an application whose tab order held a stop thatfocus_prevreturned as its own previous stop: the walk stayed on that stop, and the window hung on the key press. We have not isolated what makes GPUI's order do that; a handle tracked twice in one frame does not do it on its own.The search now records the stops it visits and, at the first repeat, focuses the trap's container, the fallback it already uses for a trap with no reachable stops. A full cycle behaves as before.
No public API changes.
How to Test
focus_trap_search_ends_at_a_short_cycle_on_its_containerdrivesadvance_focuswith a scriptedadvance(first, second, second) that panics when it runs out, so the previous loop fails in about 0.06s instead of hanging.cargo clippy -p gpui-base --locked -- --deny warnings,cargo test -p gpui-base --features test-support --lib root,cargo fmt --checkandtypos.Checklist
cargo runfor story tests related to the changes.🤖 Generated with Claude Code