Skip to content

How to share focus with popovers and other sub-tasks #106923

Description

@matthew-carroll

There's a conflict in text-based focus behavior in Flutter and I'm wondering if there's an intended approach to this problem.

Typically, when entering text into something like a form field, the moment focus moves away from the field, the selection is gone. For example, you'll see a caret and type text into a "name" field. Then, focus moves to an "email" field. At this point, there is no caret or selection in the "name" field any longer, and there is a caret in the "email" field. However, this focus behavior is not universal.

When composing text, there are a number of occasions in which some kind of popover might appear. For example, a popover to select text styles, enter a URL for a link, or select a compound character. In these situations, the popover includes focusable elements, and the user should be able to move focus around those elements. But that focus change should not impact the selection within the text field. Additionally, the moment the popover disappears, focus should return to the text field with the selection unchanged.

Does Flutter have an approach for handling these different situations?

Visual examples:

  • Editing the link URL in a selection toolbar (this example use SuperEditor but without keyboard as the input source, not IME)
    Screenshot 2022-06-28 at 23 46 13

  • Right-click on selected to show the context menu
    Screenshot 2022-06-28 at 23 49 08

  • Press and hold character key that can be written with different accents depending on the language (e.g. Portuguese)
    Screenshot 2022-06-28 at 23 50 53

Activity

  1. matthew-carroll commented on Jul 1, 2022

    @matthew-carroll
    ContributorAuthor
  2. added
    in triagePresently being triaged by the triage team
    on Jul 1, 2022
  3. exaby73 commented on Jul 1, 2022

    @exaby73
    Member

    Hello @matthew-carroll. Thank you for filing this issue. Can you include the output of flutter doctor -v as well as a minimal, reproducible example along with reproduction steps?

  4. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jul 1, 2022
  5. matthew-carroll commented on Jul 1, 2022

    @matthew-carroll
    ContributorAuthor

    The Flutter version doesn't matter for this. It's a question about the approach. All necessary information is in the ticket. I'd like to hear the perspective from someone working on text input, e.g., @justinmc, @gspencergoog, @LongCatIsLooong

  6. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Jul 1, 2022
  7. justinmc commented on Jul 1, 2022

    @justinmc
    Contributor

    Is this related to this problem with FocusTrap? #86972

    Taps outside of an input will always steal focus from that input because of FocusTrap.

  8. matthew-carroll commented on Jul 2, 2022

    @matthew-carroll
    ContributorAuthor

    That issue may or may not be related. But the root question here is how a Flutter developer should know when losing focus means "your input isn't active anymore" vs situations that mean "your input is still active, but something else has focus temporarily". You can see those examples in the original post.

  9. LongCatIsLooong commented on Jul 2, 2022

    @LongCatIsLooong
    Contributor

    the moment focus moves away from the field, the selection is gone

    TextField is considered focused as long as a descendant in its focus tree is focused, even if the TextField is not the primary focus, because it mostly relies on hasFocus to determine if it's receiving input.

    When composing text, there are a number of occasions in which some kind of popover might appear.

    If elements in the popover are themselves focusable and have to use dedicated FocusNodes, then in theory as long as these FocusNodes are descendants of the FocusNode you gave to the TextField, TextField should still consider itself as focused and appear as focused. This may require the popover implementation to find the focus node that belongs to the text field, if the popover is implemented as a separate OverlayEntry, since you can't rely on the widget tree hierarchy to automatically do that for you.

  10. matthew-carroll commented on Jul 2, 2022

    @matthew-carroll
    ContributorAuthor

    It sounds like you're saying that FocusNode hierarchy might be different from Widget hierarchy. Am I understanding you correctly?

    If so, don't Focus widgets automatically reparent FocusNodes such that a FocusNode in an overlay can't be a descendent of a FocusNode in the regular tree?

    Furthermore, what's the story around platform interop? You'll see in the original post that there are multiple situations where the popover is a system UI, e.g., a context menu or a compound character selection.

  11. LongCatIsLooong commented on Jul 2, 2022

    @LongCatIsLooong
    Contributor

    That's right. I think the Focus widget uses Focus.of to build the focus tree. So if you want the text field to stay focused when something in the popover gains focus, right now you'll probably have to manage the FocusNode subtree yourself.

    Furthermore, what's the story around platform interop? You'll see in the original post that there are multiple situations where the popover is a system UI, e.g., a context menu or a compound character selection.

    As far as the text input plugin goes I think the flutter framework handles focus separately from the platform's focus system. For key input if the system decides to hand a key event to the FlutterView then the embedder sends the key event to the framework.

  12. matthew-carroll commented on Jul 2, 2022

    @matthew-carroll
    ContributorAuthor

    Can we get an official Flutter team example of each situation, so that everyone is clear on the intended approach? E.g., a case where focus moves to an in-app popover and back, and a case where focus moves to an OS popover and back?

    I'm also wondering if Flutter should offer a generalized capability to achieve this FocusNode hierarchy. We can handle a custom hierarchy when the same developer is developing the document editor and the popovers. But consider that super_editor is developing the document editor and app developers are creating any number of popovers. How do we deal with open-ended possibilities for this use-case?

  13. matthew-carroll commented on Jul 4, 2022

    @matthew-carroll
    ContributorAuthor

    I'll add another detail to this issue. I started to implement custom management of a FocusNode's parent. However, my custom parenting wasn't being respected. The parent-child relationship kept getting changed by something else.

    I discovered that TextField passes its FocusNode to EditableText, which then includes a Focus widget within itself. Therefore, it looks like TextField is forcing reparenting based on the widget tree, preventing me from solving this problem. Is there an intended workaround for this situation?

  14. added
    a: text inputEntering text in a text field or keyboard related problems
    c: new featureNothing broken; request for a new capability
    on Jul 4, 2022
  15. 29 remaining items

  16. flutter-triage-bot commented on Sep 12, 2023

    @flutter-triage-bot

    This issue is missing a priority label. Please set a priority label when adding the triaged-framework label.

  17. added
    P3Issues that are less important to the Flutter project
    on Sep 12, 2023
  18. added
    packageflutter/packages repository. See also p: labels.
    and removed
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Aug 17, 2026
  19. added
    team-designOwned by Design Languages team
    triaged-designTriaged by Design Languages team
    and removed on Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: text inputEntering text in a text field or keyboard related problemsc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterf: focusFocus traversal, gaining or losing focusp: material_uimaterial_ui package in flutter/packagespackageflutter/packages repository. See also p: labels.team-designOwned by Design Languages teamtriaged-designTriaged by Design Languages team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions