Skip to content

PopupMenuButton should expose useRootNavigator argument #95425

Closed

Description

@nailgilaziev

While creating multi panel UI for wide screens sometimes you need to use several navigators. Root navigator and two nested navigators for each panel.

Currently PopupMenuButton as child of one of the nested navigators will use closest navigator to show popup menu items. This creates behavior different from what is expected. You can have multiple open popup menus when using multi panel UI!

I think people most often expect to see only one open popup on the screen at the same time. They expect that tapping outside of the presented popup menu will close it. This is how it works now at the case if you have one panel UI, but not in the case when utilizing multi panel UI with nested navigators.

Steps to Reproduce

  1. Execute flutter run on the code sample
  2. Tap on 3 dot icon button in the left AppBar
  3. Tap on 3 dot icon button in the right AppBar

Expected results:

Step2. Left popup appears
Step3. Left popup disappears

Actual results:

Step2. Left popup appears
Step3. Right popup appears, but left not disappears

My observations:

This happens because PopupMenuButton unconditionally uses closest Navigator from context.
I think that as default it should use root Navigator, but you can opt-in to use closest if needed.
internally PopupMenuButton uses showButtonMenu method that uses showMenu that has bool useRootNavigator = false argument. But currently this argument not used and it resolves to false.

Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    debugShowCheckedModeBanner: false,
    home: TwoPanelsHome(),
  ));
}

class TwoPanelsHome extends StatelessWidget {
  const TwoPanelsHome({Key? key}) : super(key: key);

  bool hanleOnPopPage(Route<dynamic> route, dynamic result) {
    return route.didPop(result);
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Expanded(
          child: Navigator(
            onPopPage: hanleOnPopPage,
            pages: [
              TestScaffold('left/master1'),
              TestScaffold('left/master2'),
            ].map((e) => MaterialPage<void>(child: e)).toList(),
          ),
        ),
        Expanded(
          child: Navigator(
            onPopPage: hanleOnPopPage,
            pages: [
              TestScaffold('right/details1'),
              TestScaffold('right/details2')
            ].map((e) => MaterialPage<void>(child: e)).toList(),
          ),
        ),
      ],
    );
  }
}

class TestScaffold extends StatelessWidget {
  const TestScaffold(this.name, {Key? key}) : super(key: key);

  final String name;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(name),
        actions: [
          PopupMenuButton<String>(
              onSelected: (s) {
                print(s);
              },
              itemBuilder: (context) => [
                    PopupMenuItem<String>(
                      child: Text('one'),
                      value: 'one',
                    ),
                    PopupMenuItem<String>(
                      child: Text('two'),
                      value: 'two',
                    ),
                  ]),
        ],
      ),
      body: Center(child: Text('$name\npress more menu button')),
    );
  }
}
Logs
[✓] Flutter (Channel stable, 2.8.0, on macOS 12.0.1 21A559 darwin-x64, locale en-RU)
    • Flutter version 2.8.0 at /Users/ng/Tools/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision cf44000065 (8 days ago), 2021-12-08 14:06:50 -0800
    • Engine revision 40a99c5951
    • Dart version 2.15.0
Screen.Recording.2021-12-16.at.23.16.12.mov

Activity

  1. nailgilaziev commented on Dec 16, 2021

    @nailgilaziev
    Author

    if the community or team agrees with my idea, to opt-in to useRootNavigator then it seems to me that I can make a pull request for this issue. At least I will try.

    will look like this:

    const PopupMenuButton({
        Key? key,
        ...
        this.useRootNavigator = true,
        });
  2. added
    in triagePresently being triaged by the triage team
    p: material_uimaterial_ui package in flutter/packages
    frameworkflutter/packages/flutter repository. See also f: labels.
    c: proposalA detailed proposal for a change to Flutter
    c: new featureNothing broken; request for a new capability
    and removed
    in triagePresently being triaged by the triage team
    on Dec 17, 2021
  3. added
    P3Issues that are less important to the Flutter project
    on Sep 23, 2022
  4. flutter-triage-bot commented on Jul 8, 2023

    @flutter-triage-bot

    This issue is assigned but has had no recent status updates. Please consider unassigning this issue if it is not going to be addressed in the near future. This allows people to have a clearer picture of what work is actually planned. Thanks!

  5. removed their assignment
    on Jul 21, 2023
  6. added a commit that references this issue on Nov 10, 2023
    983b2f6
  7. github-actions commented on Nov 24, 2023

    @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.

  8. locked as resolved and limited conversation to collaborators on Nov 24, 2023
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 projectc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterframeworkflutter/packages/flutter repository. See also f: labels.p: material_uimaterial_ui package in flutter/packagesteam-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