Return keyboard focus to terminal when pane context menu closes - #20652
Open
Mango Yen (mangokingTW) wants to merge 1 commit into
Open
Return keyboard focus to terminal when pane context menu closes#20652Mango Yen (mangokingTW) wants to merge 1 commit into
Mango Yen (mangokingTW) wants to merge 1 commit into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
When dismissing the pane context menu (or submenus) with Esc, XAML leaves keyboard focus on the now-hidden AppBarButton or MoreButton. Subsequent Enter invokes the hidden item instead of reaching the shell. Fix: - TermControl: Restore focus on context menu Closed if the focused element belongs to the closing flyout; respect active search box. - TerminalPage: Hand focus back to parent button when a sub-flyout closes. - Utils: Add bounded VisualTree helper IsElementInCommandBarFlyout to verify flyout membership and prevent cross-pane focus stealing. Closes microsoft#20593
Mango Yen (mangokingTW)
force-pushed
the
pr/official-context-menu-focus-fix
branch
from
September 9, 2026 02:48
6f7a935 to
a8d7e68
Compare
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 of the Pull Request
When the pane context menu (opened via Menu/Apps key, Shift+F10, or Right-Click when
rightClickContextMenuis enabled) is dismissed with Esc, keyboard focus currently remains trapped on the now-hidden menu item (AppBarButtonor overflowMoreButton). Pressing Enter afterwards invokes the hidden command (e.g. reopening a flyout or splitting a pane) instead of sending input to the active shell.This PR ensures keyboard focus is properly restored to the terminal (or active Find search box) when the context menu is dismissed.
References and Relevant Issues
Detailed Description of the Pull Request
Root Cause
CommandBarFlyoutmoves focus to its menu buttons or overflow toggle (MoreButton). When dismissed via Esc, XAML closes the flyout but does not restore focus to the underlying control, leaving focus trapped on the invisible element.Proposed Changes
TermControl.cpp):Closed, checks if the currently focused element belongs to the closing menu (PrimaryCommands,SecondaryCommands, child flyouts, or internalMoreButton)._searchBox) is open, restores focus to its textbox; otherwise restores focus to the terminal viaFocus(FocusState::Programmatic).CommandBarancestor to prevent cross-pane focus stealing in multi-pane layouts.TerminalPage.cpp):handBackFocusOnClose, hands focus back to the parent button that opened the submenu usingFocusState::Keyboard(falling back toFocusState::Programmatic).TermControl.Utils.h):IsElementInCommandBarFlyoutintoWinRTUtils/inc/Utils.hto eliminate logic duplication acrossTermControlandTerminalPage.Generative AI Disclosure
This pull request was developed with the assistance of Google Antigravity (Gemini Flash 3.8) for code exploration, edge-case analysis, and drafting this PR description. Problem investigation, focus contract definitions, manual testing, and final code verification were reviewed and directed by me.
Validation Steps Performed
Visual Demonstration
Both recordings capture the exact same top-level dismissal test (
test_esc_from_the_top_level_hands_focus_back_to_the_terminal): navigating toSplit pane, dismissing with Esc, then pressing Enter.reproduction-20593-x64.mp4From Run 34097704495 (
verification-recording-windows-latest)• 39.5s - 41.5s: Menu opens, nav down to
Split pane• 41.5s - 42.5s:
Split paneentry highlighted• 42.6s: Esc pressed; menu disappears
• 46.5s: Enter pressed
• 46.9s: Submenu reopens in mid-air at (0, 0)
reproduction-20593-x64.mp4From Run 34170503162 (
verification-recording-windows-latest)• 27.0s - 29.2s: Menu opens, nav down to
Split pane• 29.2s - 30.6s:
Split paneentry highlighted• 30.7s: Esc pressed; menu disappears, focus returned to terminal
• 32.0s: Enter pressed
• 33.2s: Enter sends newline to shell prompt
Automated UI Testing & Key Edge Cases
Verification was conducted with an automated UI test harness running under wintegrate across Windows 11 x64 and ARM64 environments. wintegrate provides native Windows UI Automation drivers, process discovery, keyboard/mouse input injection, and automated screen recordings during CI and VM test runs.
The complete test suite (19 edge-case tests) and continuous screen recordings are maintained in companion PR #1 (fix/context-menu-focus-after-esc):
windows-latestx64 &windows-11-armarm64)verification-recording-windows-latest.zip(x64)verification-recording-windows-11-arm.zip(arm64)verification-recording-windows-latest.zip• Apps / Menu key (default trigger)
• Shift+F10 (WCAG keybinding)
• Mouse Right-Click (with
rightClickContextMenu: true)L396L856L886FocusStaysTrappedOnMenu)Focus remained trapped on invisible
AppBarButton; pressing Enter re-opened the menuFocus immediately returned to terminal; Enter sends newline to shell
• Split pane submenu
L345AssertionError)1st Esc closed submenu but focus failed to return to parent button; 2nd Esc failed to return to terminal
1st Esc returned focus to parent button; 2nd Esc returned focus to terminal
MoreButton(...) EscL665AssertionError)Focus trapped on invisible
MoreButton; terminal cannot receive inputSingle-pass ancestor traversal matched CommandBar; focus restored to terminal
• Context menu Esc with Find open
L606AssertionError)Focus remained trapped on invisible menu item instead of returning to search box TextBox
Detects active
_searchBoxand accurately restores focus to search box TextBox• Dismissing menu in split layout
L511L767FocusStolenCrossPane)Dismissing Pane B menu left focus trapped on hidden item, terminal never received focus
Bounded tree search ensures each pane only handles its own menu without cross-pane interference
• Rapid Esc + Enter
• Rapid typing after Esc
L950L971AssertionError)Rapid keystrokes swallowed or triggered hidden actions; typed characters lost
Focus returned synchronously; subsequent keys and characters 100% delivered to shell
• Clicking outside open submenu
L726Verifies behavior when owner button is detached from Visual Tree during dismissal
handBackFocusOnClosesafely falls back without crash; focus returns cleanlyPR Checklist