Skip to content

Should implement a context menu widget #31955

Closed

Description

@gspencergoog

With the ability to right-click, we need to be able to allow developers to implement custom context menus. On desktop platforms, these may need to be platform-specific context menus (so that they can render outside of the window), on web they will need to integrate with the context menu APIs there, and on Android they will need to be rendered by Flutter (one can right click on ChromeOS in an Android app, for instance. iOS doesn't support mouse, so it's not needed there). As a first pass on desktop platforms, it may initially be acceptable if the menu is rendered by Flutter (and hence doesn't render outside of the window), but long term probably not, so the API should definitely take that into account (and not take Widgets for the items, but rather some form of data object).

Before this, #31946 will probably need to be implemented, in order to provide the actions that the menu will invoke.

See also #30976 and #31412

Activity

  1. gspencergoog commented on Jul 16, 2019

    @gspencergoog
    ContributorAuthor

    Actually, Flutter might be able to render the context menu itself on Windows, macOS, and Linux, since we can probably do this once we have multi-window support described in #30701, and still render outside of the window. This would allow a lot of flexibility in the visual presentation of the context menu (including looking just like the platform native context menu).

  2. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Jul 26, 2019
  3. added this to the milestone on Aug 13, 2019
  4. dancojocaru2000 commented on Mar 26, 2020

    @dancojocaru2000

    Since iPad OS 13.4 now has mouse support, such a context menu widget should be considered for iOS as well.

  5. added
    P2Important issues not at the top of the work list
    on May 29, 2020
  6. removed this from the milestone on Aug 17, 2020
  7. esDotDev commented on Dec 9, 2020

    @esDotDev

    fwiw, with a bit of logic to offset the context-menu depending on which quadrant off the app you are in, it becomes almost impossible to have the context menu be cut-off. If you take a look at VSCode it works like this. Spotify also does a variation of this.

    I was able to code this up in about 90 lines, just using a Stack at the top of the tree and a custom Notification:

    Usage is something like:

     MaterialApp(
          home: ContextOverlay( child: ... )
    );
    ...
    ContextMenuRegion(
      menuBuilder: (_) => MyMenu(),
      child: SomeContent(),
    )
    

    Certainly there are use cases for going outside the window (for very small apps, or very huge menus), but I think 98% of needs can be served with something simple like this, and the simple offset logic is actually very robust/elegant.

    Hopefully the primary use case doesn't become overly complicated in order to serve the edge case of falling outside the window chrome. Many very popular desktop apps, like Slack, Steam, Spotify, VSCode etc all use totally custom context menus, and they often look nicer for it, so it would be nice to be able to render as a widget if possible imo, otherwise it seems like styling it to match our apps could be quite hard/inflexible.

  8. justinmc commented on Dec 14, 2020

    @justinmc
    Contributor

    I played around with creating a Flutter-rendered context menu on Mac and getting it to work with text editing:

    desktop_tsm

    The messy POC code is on my desktop-context-menu branch, but I'm holding off on moving forward with it due to a few blockers:

    • It needs to share code with the Android and iOS text selection menus. These need to be refactored a bit to support this. The Android menu's refactor is about to be merged in Material Text Selection Toolbar improvements #69428, and iOS should follow suit. This will also allow custom menu items, which will be really important since desktop context menus often have dozens of options.
    • It's too hard to implement distinct text editing behaviors in the current code (e.g. what happens on double tap/click, when the menu should show, etc.). Just handling some distinct behaviors in Android and iOS now is resulting in a steady stream of bugs and regressions. This needs to be refactored to support multiple platforms, which I am working on proposing in this design doc.
    • TextButton needs to support custom alignment so that we can make the buttons align left like on native Mac.

    I didn't see @esDotDev's comment above about menu positioning when I started this, but that looks like a great way to do positioning.

    Tl;dr: The approach of rendering a desktop context menu with Flutter looks totally doable, but we will struggle with bugs and limited features if we don't complete some refactoring first.

  9. justinmc commented on Jan 20, 2021

    @justinmc
    Contributor

    A Mac context menu was implemented in #73882 and a generic Material one will be implemented for Mac and Linux in #74286. I'll close this issue when it's merged.

    However, these menus are super basic and have major limitations for now. For example, for now, the only buttons available are the default cut/copy/paste/selectall from mobile, and there is no way for developers to extend these menus. I'm tracking these next steps in #74255.

    Light Dark
    Mac Screen Shot 2021-01-15 at 10 37 00 AM Screen Shot 2021-01-15 at 10 36 45 AM
    Windows/Linux Screen Shot 2021-01-20 at 9 59 16 AM Screen Shot 2021-01-20 at 9 59 35 AM
  10. aBuder commented on Aug 1, 2021

    @aBuder

    fwiw, with a bit of logic to offset the context-menu depending on which quadrant off the app you are in, it becomes almost impossible to have the context menu be cut-off. If you take a look at VSCode it works like this. Spotify also does a variation of this.

    I was able to code this up in about 90 lines, just using a Stack at the top of the tree and a custom Notification:

    Usage is something like:

    
     MaterialApp(
    
          home: ContextOverlay( child: ... )
    
    );
    
    ...
    
    ContextMenuRegion(
    
      menuBuilder: (_) => MyMenu(),
    
      child: SomeContent(),
    
    )
    
    

    Certainly there are use cases for going outside the window (for very small apps, or very huge menus), but I think 98% of needs can be served with something simple like this, and the simple offset logic is actually very robust/elegant.

    Hopefully the primary use case doesn't become overly complicated in order to serve the edge case of falling outside the window chrome. Many very popular desktop apps, like Slack, Steam, Spotify, VSCode etc all use totally custom context menus, and they often look nicer for it, so it would be nice to be able to render as a widget if possible imo, otherwise it seems like styling it to match our apps could be quite hard/inflexible.

    Can you share the code

  11. github-actions commented on Aug 15, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  12. locked as resolved and limited conversation to collaborators on Aug 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

P2Important issues not at the top of the work lista: desktopRunning on desktopc: new featureNothing broken; request for a new capabilitycustomer: web10frameworkflutter/packages/flutter repository. See also f: labels.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions