flyout: a11y: Allow users to control flyout menus with keyboard [chromium/src : main]

0 views
Skip to first unread message

Masa Fujita (Gerrit)

unread,
Sep 24, 2025, 8:56:23 AM (yesterday) Sep 24
to chromium...@chromium.org, peilinwa...@google.com, chromium-a...@chromium.org, hanxi...@chromium.org, extension...@chromium.org

Masa Fujita has uploaded the change for review

Commit message

flyout: a11y: Allow users to control flyout menus with keyboard

This CL adds the ability for the user to use the keyboard to control the
flyout menus.

When the user selects an item with arrow keys and decides to proceed,
the `View`'s click listeneris called. We capture this and run the flyout
logic when necessary.

This CL also makes it so that `ListMenuItemAdapter` sets up the view to
use both the delegate and the click listener upon click.
Bug: 447103380
Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca

Change diff


Change information

Files:
  • M ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java
  • M ui/android/java/src/org/chromium/ui/listmenu/ListMenuUtils.java
Change size: S
Delta: 2 files changed, 33 insertions(+), 13 deletions(-)
Open in Gerrit

Related details

Attention set is empty
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: newchange
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca
Gerrit-Change-Number: 6978443
Gerrit-PatchSet: 1
Gerrit-Owner: Masa Fujita <mas...@google.com>
satisfied_requirement
unsatisfied_requirement
open
diffy

Masa Fujita (Gerrit)

unread,
Sep 24, 2025, 8:57:13 AM (yesterday) Sep 24
to Jenna Himawan, chromium...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, hanxi...@chromium.org, peilinwa...@google.com
Attention needed from Jenna Himawan

Masa Fujita added 1 comment

Patchset-level comments
File-level comment, Patchset 1 (Latest):
Masa Fujita . resolved

PTAL!

Open in Gerrit

Related details

Attention is currently required from:
  • Jenna Himawan
Submit Requirements:
  • requirement satisfiedCode-Coverage
  • requirement is not satisfiedCode-Owners
  • requirement is not satisfiedCode-Review
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: comment
Gerrit-Project: chromium/src
Gerrit-Branch: main
Gerrit-Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca
Gerrit-Change-Number: 6978443
Gerrit-PatchSet: 1
Gerrit-Owner: Masa Fujita <mas...@google.com>
Gerrit-Reviewer: Jenna Himawan <jhim...@google.com>
Gerrit-Attention: Jenna Himawan <jhim...@google.com>
Gerrit-Comment-Date: Wed, 24 Sep 2025 12:57:01 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
satisfied_requirement
unsatisfied_requirement
open
diffy

Masa Fujita (Gerrit)

unread,
Sep 24, 2025, 9:06:08 AM (yesterday) Sep 24
to Jenna Himawan, chromium...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, hanxi...@chromium.org, peilinwa...@google.com
Attention needed from Jenna Himawan

Masa Fujita voted and added 1 comment

Votes added by Masa Fujita

Commit-Queue+1

1 comment

File ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java
Line 94, Patchset 2 (Latest): boolean handled = false;
if (hasClickListener(item)) {
// The item had a click listener in the model, but none was bound by the
// ViewBinder, and there is no click delegate to use. In this case, call
// the model click listener directly.
item.model.get(CLICK_LISTENER).onClick(view);
handled = true;
}
if (mDelegate != null) {
// Delegate, if possible.
mDelegate.onItemSelected(item.model);
handled = true;
}
if (handled) {
return;
}
// As a fallback, use ListView's performItemClick.
long id = getItemId(position);
((ListView) parent).performItemClick(v, position, id);
Masa Fujita . unresolved

@jhim...@google.com This is the part I'm unsure about - do you think it sometimes makes sense to run both the delegate and the click listener?

Open in Gerrit

Related details

Attention is currently required from:
  • Jenna Himawan
Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca
    Gerrit-Change-Number: 6978443
    Gerrit-PatchSet: 2
    Gerrit-Owner: Masa Fujita <mas...@google.com>
    Gerrit-Reviewer: Jenna Himawan <jhim...@google.com>
    Gerrit-Reviewer: Masa Fujita <mas...@google.com>
    Gerrit-Attention: Jenna Himawan <jhim...@google.com>
    Gerrit-Comment-Date: Wed, 24 Sep 2025 13:05:55 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Jenna Himawan (Gerrit)

    unread,
    Sep 24, 2025, 2:18:48 PM (yesterday) Sep 24
    to Masa Fujita, Chromium LUCI CQ, chromium...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, hanxi...@chromium.org, peilinwa...@google.com
    Attention needed from Masa Fujita

    Jenna Himawan added 6 comments

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuFlyoutController.java
    Line 143, Patchset 2 (Latest): * @param item The ListItem that is the target of the hover event.
    Jenna Himawan . unresolved

    Replace hover -> "focused" in the Javadoc

    Line 158, Patchset 2 (Latest): updateHighlightPath(highlightPath);
    Jenna Himawan . unresolved

    I'm a bit confused on why we're calling this here. Can you provide better documentation about what the method does?

    I read the code a bit more. My understanding is that the `List<ListItem> highlightPath` is updated, but updateHighlightPath is not called right away. We update the highlight path, then pass the updated highlight path to another method, and expect the other method to updateHighlightPath using the parameter.

    Could we not just updateHighlightPath right away?

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java
    Line 48, Patchset 2 (Latest): * will be ran.
    Jenna Himawan . unresolved

    nit: "both will run" (or "both will be run")

    (if we keep this change)

    Line 94, Patchset 2 (Latest): boolean handled = false;
    if (hasClickListener(item)) {
    // The item had a click listener in the model, but none was bound by the
    // ViewBinder, and there is no click delegate to use. In this case, call
    // the model click listener directly.
    item.model.get(CLICK_LISTENER).onClick(view);
    handled = true;
    }
    if (mDelegate != null) {
    // Delegate, if possible.
    mDelegate.onItemSelected(item.model);
    handled = true;
    }
    if (handled) {
    return;
    }
    // As a fallback, use ListView's performItemClick.
    long id = getItemId(position);
    ((ListView) parent).performItemClick(v, position, id);
    Masa Fujita . unresolved

    @jhim...@google.com This is the part I'm unsure about - do you think it sometimes makes sense to run both the delegate and the click listener?

    Jenna Himawan

    We haven't had a scenario so far where this is true. Do you need it for your changes?

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuUtils.java
    Line 264, Patchset 2 (Latest): flyoutController.handleEnterEvent(
    Jenna Himawan . unresolved

    It seems that the "handleEnterEvent" is activated on click. This makes sense, but you should probably rename the method so that its name is compatible with any user input that should trigger the flyout right away (including click, right arrow, space, and enter)

    Line 264, Patchset 2 (Latest): flyoutController.handleEnterEvent(
    Jenna Himawan . unresolved

    You can handle this in a follow-up, but pressing the keyboard right arrow should also enter the flyout.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Masa Fujita
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca
    Gerrit-Change-Number: 6978443
    Gerrit-PatchSet: 2
    Gerrit-Owner: Masa Fujita <mas...@google.com>
    Gerrit-Reviewer: Jenna Himawan <jhim...@google.com>
    Gerrit-Reviewer: Masa Fujita <mas...@google.com>
    Gerrit-Attention: Masa Fujita <mas...@google.com>
    Gerrit-Comment-Date: Wed, 24 Sep 2025 18:18:38 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Masa Fujita <mas...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Masa Fujita (Gerrit)

    unread,
    7:57 AM (10 hours ago) 7:57 AM
    to Chromium LUCI CQ, Jenna Himawan, chromium...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, hanxi...@chromium.org, peilinwa...@google.com
    Attention needed from Jenna Himawan

    Masa Fujita voted and added 6 comments

    Votes added by Masa Fujita

    Commit-Queue+1

    6 comments

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuFlyoutController.java
    Line 143, Patchset 2: * @param item The ListItem that is the target of the hover event.
    Jenna Himawan . resolved

    Replace hover -> "focused" in the Javadoc

    Masa Fujita

    Done

    Line 158, Patchset 2: updateHighlightPath(highlightPath);
    Jenna Himawan . unresolved

    I'm a bit confused on why we're calling this here. Can you provide better documentation about what the method does?

    I read the code a bit more. My understanding is that the `List<ListItem> highlightPath` is updated, but updateHighlightPath is not called right away. We update the highlight path, then pass the updated highlight path to another method, and expect the other method to updateHighlightPath using the parameter.

    Could we not just updateHighlightPath right away?

    Masa Fujita

    Actually `updateHighlightPath()` is a method that immediately changes the UI state (the variable `List<ListItem> highlightPath` is created during recursion and is just passed around without updates). I renamed it and added doc to clarify a bit more. Does it make sense?

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java
    Line 48, Patchset 2: * will be ran.
    Jenna Himawan . resolved

    nit: "both will run" (or "both will be run")

    (if we keep this change)

    Masa Fujita

    oops, thanks!

    Line 94, Patchset 2: boolean handled = false;

    if (hasClickListener(item)) {
    // The item had a click listener in the model, but none was bound by the
    // ViewBinder, and there is no click delegate to use. In this case, call
    // the model click listener directly.
    item.model.get(CLICK_LISTENER).onClick(view);
    handled = true;
    }
    if (mDelegate != null) {
    // Delegate, if possible.
    mDelegate.onItemSelected(item.model);
    handled = true;
    }
    if (handled) {
    return;
    }
    // As a fallback, use ListView's performItemClick.
    long id = getItemId(position);
    ((ListView) parent).performItemClick(v, position, id);
    Masa Fujita . unresolved

    @jhim...@google.com This is the part I'm unsure about - do you think it sometimes makes sense to run both the delegate and the click listener?

    Jenna Himawan

    We haven't had a scenario so far where this is true. Do you need it for your changes?

    Masa Fujita

    The reason why we need this is because:

    • BasicListMenu always sets a delegate but
    • ListMenuUtils sets a CLICK_LISTENER for submenus

    and we need both of them to be called, unless we change either's implementation.

    I considered having the delegate call the listener but the delegate doesn't have access to the `View`.

    I wasn't sure if you were comfortable with calling both though.

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuUtils.java
    Line 264, Patchset 2: flyoutController.handleEnterEvent(
    Jenna Himawan . resolved

    You can handle this in a follow-up, but pressing the keyboard right arrow should also enter the flyout.

    Masa Fujita

    I'm planning on doing this in another CL.

    Line 264, Patchset 2: flyoutController.handleEnterEvent(
    Jenna Himawan . resolved

    It seems that the "handleEnterEvent" is activated on click. This makes sense, but you should probably rename the method so that its name is compatible with any user input that should trigger the flyout right away (including click, right arrow, space, and enter)

    Masa Fujita

    Done

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Jenna Himawan
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca
    Gerrit-Change-Number: 6978443
    Gerrit-PatchSet: 4
    Gerrit-Owner: Masa Fujita <mas...@google.com>
    Gerrit-Reviewer: Jenna Himawan <jhim...@google.com>
    Gerrit-Reviewer: Masa Fujita <mas...@google.com>
    Gerrit-Attention: Jenna Himawan <jhim...@google.com>
    Gerrit-Comment-Date: Thu, 25 Sep 2025 11:57:37 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: Masa Fujita <mas...@google.com>
    Comment-In-Reply-To: Jenna Himawan <jhim...@google.com>
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Masa Fujita (Gerrit)

    unread,
    8:00 AM (10 hours ago) 8:00 AM
    to Chromium LUCI CQ, Jenna Himawan, chromium...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, hanxi...@chromium.org, peilinwa...@google.com
    Attention needed from Jenna Himawan

    Masa Fujita voted Commit-Queue+1

    Commit-Queue+1
    Open in Gerrit

    Related details

    Attention is currently required from:
    • Jenna Himawan
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca
    Gerrit-Change-Number: 6978443
    Gerrit-PatchSet: 5
    Gerrit-Owner: Masa Fujita <mas...@google.com>
    Gerrit-Reviewer: Jenna Himawan <jhim...@google.com>
    Gerrit-Reviewer: Masa Fujita <mas...@google.com>
    Gerrit-Attention: Jenna Himawan <jhim...@google.com>
    Gerrit-Comment-Date: Thu, 25 Sep 2025 12:00:31 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Masa Fujita (Gerrit)

    unread,
    12:05 PM (6 hours ago) 12:05 PM
    to Chromium LUCI CQ, Jenna Himawan, chromium...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, hanxi...@chromium.org, peilinwa...@google.com
    Attention needed from Jenna Himawan

    Masa Fujita voted and added 2 comments

    Votes added by Masa Fujita

    Commit-Queue+1

    2 comments

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuUtils.java
    Line 249, Patchset 6: org.chromium.ui.listmenu.ListMenuItemProperties.KEY_LISTENER,
    Masa Fujita . unresolved

    qq: can `ListMenuSubmenuHeaderItemProperties.KEY_LISTENER` be replaced with `ListMenuItemProperties.KEY_LISTENER`?

    Line 264, Patchset 2: flyoutController.handleEnterEvent(
    Jenna Himawan . resolved

    You can handle this in a follow-up, but pressing the keyboard right arrow should also enter the flyout.

    Masa Fujita

    I'm planning on doing this in another CL.

    Masa Fujita

    On a second thought, I decided to do that here too.

    Open in Gerrit

    Related details

    Attention is currently required from:
    • Jenna Himawan
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca
    Gerrit-Change-Number: 6978443
    Gerrit-PatchSet: 8
    Gerrit-Owner: Masa Fujita <mas...@google.com>
    Gerrit-Reviewer: Jenna Himawan <jhim...@google.com>
    Gerrit-Reviewer: Masa Fujita <mas...@google.com>
    Gerrit-Attention: Jenna Himawan <jhim...@google.com>
    Gerrit-Comment-Date: Thu, 25 Sep 2025 16:04:56 +0000
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy

    Jenna Himawan (Gerrit)

    unread,
    1:58 PM (4 hours ago) 1:58 PM
    to Masa Fujita, Chromium LUCI CQ, chromium...@chromium.org, chromium-a...@chromium.org, extension...@chromium.org, hanxi...@chromium.org, peilinwa...@google.com
    Attention needed from Masa Fujita

    Jenna Himawan added 2 comments

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuFlyoutController.java
    Line 158, Patchset 2: updateHighlightPath(highlightPath);
    Jenna Himawan . unresolved

    I'm a bit confused on why we're calling this here. Can you provide better documentation about what the method does?

    I read the code a bit more. My understanding is that the `List<ListItem> highlightPath` is updated, but updateHighlightPath is not called right away. We update the highlight path, then pass the updated highlight path to another method, and expect the other method to updateHighlightPath using the parameter.

    Could we not just updateHighlightPath right away?

    Masa Fujita

    Actually `updateHighlightPath()` is a method that immediately changes the UI state (the variable `List<ListItem> highlightPath` is created during recursion and is just passed around without updates). I renamed it and added doc to clarify a bit more. Does it make sense?

    Jenna Himawan

    I think this helps make it clearer. It seems a bit asymmetric, though...

    When we enter the flyout, we update List<ListItem> highlightPath outside the enterFlyout method, then the first thing the enterFlyout method does is update the highlights using the highlightPath that it is passed.

    When we exit the flyout, we call updateHighlights with highlightPath.subList(...).

    Would it make sense to have the enterFlyout method add `item` to the end of the list and then call updateHighlights?

    You can do this in a separate CL; sorry for bothering you!

    File ui/android/java/src/org/chromium/ui/listmenu/ListMenuItemAdapter.java
    Attention is currently required from:
    • Masa Fujita
    Submit Requirements:
    • requirement satisfiedCode-Coverage
    • requirement is not satisfiedCode-Owners
    • requirement is not satisfiedCode-Review
    • requirement is not satisfiedNo-Unresolved-Comments
    Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
    Gerrit-MessageType: comment
    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I4560508cdfe63fab553e44478bb48d3ed528caca
    Gerrit-Change-Number: 6978443
    Gerrit-PatchSet: 9
    Gerrit-Owner: Masa Fujita <mas...@google.com>
    Gerrit-Reviewer: Jenna Himawan <jhim...@google.com>
    Gerrit-Reviewer: Masa Fujita <mas...@google.com>
    Gerrit-Attention: Masa Fujita <mas...@google.com>
    Gerrit-Comment-Date: Thu, 25 Sep 2025 17:58:48 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    satisfied_requirement
    unsatisfied_requirement
    open
    diffy
    Reply all
    Reply to author
    Forward
    0 new messages