Skip to content

Conversation

@dkwingsmt
Copy link
Contributor

@dkwingsmt dkwingsmt commented Sep 26, 2024

This PR adjusts the implementation of handling navigational shortcuts (i.e. arrow keys) on MenuAnchor and DropdownMenu.

Motivation

The direct outcome of this PR is to allow keyboard to enter submenus on Web: When the focus is on a MenuAnchor while the menu is open, pressing arrow keys should move the focus to the menu item.

It is caused by the fact that MenuAnchor does not wrap itself with a Shortcuts, and therefore key events when the focus is on a MenuAnchor has been working only because the event falls back to the Shortcuts widget defined by WidgetsApp, whose default value happens to satisfy MenuAnchor's needs - except on Web where arrow keys are defined to scroll instead of traverse.

Instead of defining this problem as "just a patch for Web", I think it's better to define it as a problem of all platforms: MenuAnchor's shortcuts should be independent of WidgetsApp.shortcuts. Because even if WidgetsApp.shortcuts is redefined as something else, people should probably still expect arrow keys to work on MenuAnchor.

Therefore this PR makes MenuAnchor produce a Shortcuts by itself.

Dropdown menu

The fix above breaks DropdownMenu. DropdownMenu uses MenuAnchor, while defining its own shortcuts because, when filter is enabled:

  • The left and right arrow keys need to move the text carets instead
  • The up and down arrow keys need to "fake" directional navigation - the focus needs to stay on the text field, while some menu item is highlighted as if it is focused.

Before the PR, DropdownMenu defines these shortcuts out of MenuAnchor. In order for the DropdownMenu's shortcuts to take priority, these shortcuts are moved to between MenuAnchor and the Textfield.

A test is added to verify that the left/right keys move text carets.

Below are psuedo-widget-trees after the PR:

MenuAnchor
 |- Shortcuts(arrows->DirectionalFocusIntent)
    |- MenuAnchor.child
    |- menu

DropdownMenu
 |- Actions(DirectionalFocusIntent->_dropdownMenuNavigation)
    |- MenuAnchor
        |- Shortcuts(arrows->DirectionalFocusIntent)
            |- Shortcuts(leftright->ExtendSelectionByCharacterIntent, updown->_dropdownMenuArrowIntent)
            |  |- TextField
            |     |- EditableText
            |        |- Actions(DirectionalFocusIntent->DirectionalFocusAction.forTextField)
            |- menu

Known issues

After this PR, traversing the menu still have quite a few problems, which are left for other PRs.

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Sep 26, 2024
@dkwingsmt dkwingsmt marked this pull request as ready for review September 26, 2024 07:02
@dkwingsmt
Copy link
Contributor Author

cc @davidhicks980

Copy link
Contributor

@gspencergoog gspencergoog left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

32384589-a60f0e74-c078-11e7-9bc1-e5b5287aea9d

Copy link
Contributor

@bleroux bleroux left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the test failures, the problem is that DropdownMenu reuses MenuAnchor and defines its own Shortcuts which are superceeded by the Shortcuts added by this PR.

return Shortcuts(
shortcuts: _kMenuTraversalShortcuts,
child: Actions(
actions: <Type, Action<Intent>>{
_ArrowUpIntent: CallbackAction<_ArrowUpIntent>(
onInvoke: handleUpKeyInvoke,
),
_ArrowDownIntent: CallbackAction<_ArrowDownIntent>(
onInvoke: handleDownKeyInvoke,
),
},
child: menuAnchor,
),
);

child: child,
// This `Shortcuts` is needed so that shortcuts work when the focus is on
// MenuAnchor (specifically, the root menu, since submenus have their own
// `Shortcuts`.)
Copy link
Contributor

@bleroux bleroux Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// `Shortcuts`.)
// `Shortcuts`).

In french it would be that way, not sure if it is the same in english. 😅

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Period outside the parenthesis is correct in English too 👍

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch by @bleroux on the Dropdown thing. I'm not sure if it's helpful here but things like Action.overridable also exist.

child: child,
// This `Shortcuts` is needed so that shortcuts work when the focus is on
// MenuAnchor (specifically, the root menu, since submenus have their own
// `Shortcuts`.)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Period outside the parenthesis is correct in English too 👍

@dkwingsmt
Copy link
Contributor Author

Yeah I was unsure how to fix the drop down menu, both to make it functional and semantically correct. Thank you for letting me know overridable. I'll take a look soon.

@github-actions github-actions bot added the a: text input Entering text in a text field or keyboard related problems label Oct 1, 2024
@github-actions github-actions bot removed the a: text input Entering text in a text field or keyboard related problems label Oct 1, 2024
@dkwingsmt dkwingsmt changed the title [MenuAnchor] Allow keyboard to enter submenu on Web Adjust navigational shortcut handling of MenuAnchor and DropdownMenu Oct 1, 2024
@dkwingsmt dkwingsmt changed the title Adjust navigational shortcut handling of MenuAnchor and DropdownMenu Allow arrow keys to navigate MenuAnchor independently of global shortcut definition Oct 1, 2024
@dkwingsmt dkwingsmt added the autosubmit Merge PR when tree becomes green via auto submit App label Oct 3, 2024
@auto-submit auto-submit bot merged commit 59e5743 into flutter:master Oct 3, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 4, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 5, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 5, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 6, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 6, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Oct 8, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Oct 8, 2024
Manual roll requested by [email protected]

flutter/flutter@ec2e12b...0917e9d

2024-10-05 [email protected] Roll Flutter Engine from 2068577e510b to 01de9dcf6bbf (1 revision) (flutter/flutter#156274)
2024-10-05 [email protected] Roll Flutter Engine from 6d6bc39fe8b1 to 2068577e510b (1 revision) (flutter/flutter#156267)
2024-10-05 [email protected] Roll Flutter Engine from 92b5b318190b to 6d6bc39fe8b1 (4 revisions) (flutter/flutter#156266)
2024-10-05 [email protected] Roll Flutter Engine from fd6082ab6693 to 92b5b318190b (1 revision) (flutter/flutter#156261)
2024-10-05 [email protected] Roll Flutter Engine from bc5f9fc80b06 to fd6082ab6693 (4 revisions) (flutter/flutter#156258)
2024-10-04 [email protected] Roll Flutter Engine from eece6c3ec63a to bc5f9fc80b06 (2 revisions) (flutter/flutter#156252)
2024-10-04 [email protected] Roll pub packages (flutter/flutter#156254)
2024-10-04 [email protected] Roll Flutter Engine from 9fa363bdde20 to eece6c3ec63a (1 revision) (flutter/flutter#156250)
2024-10-04 [email protected] Roll Flutter Engine from d38f5e560a98 to 9fa363bdde20 (1 revision) (flutter/flutter#156249)
2024-10-04 [email protected] remove bringup from Windows tool_integration_tests_* (flutter/flutter#156179)
2024-10-04 [email protected] Roll Flutter Engine from 205484009711 to d38f5e560a98 (4 revisions) (flutter/flutter#156239)
2024-10-04 [email protected] Normalize `ThemeData.cardTheme` (flutter/flutter#153254)
2024-10-04 [email protected] Roll Packages from 429650f to 05bf1d4 (5 revisions) (flutter/flutter#156225)
2024-10-04 [email protected] Roll Flutter Engine from e0109f0fd5b2 to 205484009711 (1 revision) (flutter/flutter#156216)
2024-10-04 [email protected] Roll pub packages (flutter/flutter#156215)
2024-10-04 [email protected] Roll Flutter Engine from c2a9fb051bd0 to e0109f0fd5b2 (1 revision) (flutter/flutter#156213)
2024-10-04 [email protected] Roll Flutter Engine from 66d397dff87a to c2a9fb051bd0 (5 revisions) (flutter/flutter#156206)
2024-10-04 [email protected] Roll Flutter Engine from 20369c5d2b93 to 66d397dff87a (5 revisions) (flutter/flutter#156188)
2024-10-03 [email protected] Roll Flutter Engine from de1762dbc5cc to 20369c5d2b93 (7 revisions) (flutter/flutter#156174)
2024-10-03 [email protected] Refactor devfs_web_ddc_modules_test.dart (flutter/flutter#155609)
2024-10-03 [email protected] Allow arrow keys to navigate `MenuAnchor` independently of global shortcut definition (flutter/flutter#155728)
2024-10-03 [email protected] Inherited Theme: zero rebuilds (flutter/flutter#155699)
2024-10-03 [email protected] Roll Flutter Engine from 247bc68c578e to de1762dbc5cc (4 revisions) (flutter/flutter#156160)
2024-10-03 [email protected] Roll pub packages (flutter/flutter#156159)
2024-10-03 [email protected] pattern-matching refactor (flutter/flutter#154753)
2024-10-03 [email protected] Add autocorrect and enableSuggestions to SearchDelegate (flutter/flutter#154932)
2024-10-03 [email protected] Roll Packages from 7c97c88 to 429650f (6 revisions) (flutter/flutter#156155)
2024-10-03 [email protected] Move some tools test ownership to Ben (flutter/flutter#156123)
2024-10-03 [email protected] further shard the Windows tool_integration_tests* targets (flutter/flutter#156121)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC [email protected],[email protected] on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 11, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants