From 3e069a433b2b423d952407b3964d868c0c7cc4fe Mon Sep 17 00:00:00 2001 From: Sergey Solodukhin Date: Mon, 12 Oct 2020 21:52:04 +0300 Subject: [PATCH] =?UTF-8?q?fix=20issue=20#55400=20PopupMenuButton=20positi?= =?UTF-8?q?ons=20menu=20incorrectly=20with=20nest=E2=80=A6=20(#65832)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flutter/lib/src/material/popup_menu.dart | 2 +- .../test/material/popup_menu_test.dart | 83 +++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/material/popup_menu.dart b/packages/flutter/lib/src/material/popup_menu.dart index a80e12d468..47263dd727 100644 --- a/packages/flutter/lib/src/material/popup_menu.dart +++ b/packages/flutter/lib/src/material/popup_menu.dart @@ -1077,7 +1077,7 @@ class PopupMenuButtonState extends State> { void showButtonMenu() { final PopupMenuThemeData popupMenuTheme = PopupMenuTheme.of(context); final RenderBox button = context.findRenderObject()! as RenderBox; - final RenderBox overlay = Overlay.of(context)!.context.findRenderObject()! as RenderBox; + final RenderBox overlay = Navigator.of(context)!.overlay!.context.findRenderObject()! as RenderBox; final RelativeRect position = RelativeRect.fromRect( Rect.fromPoints( button.localToGlobal(widget.offset, ancestor: overlay), diff --git a/packages/flutter/test/material/popup_menu_test.dart b/packages/flutter/test/material/popup_menu_test.dart index da308fe096..5347310c84 100644 --- a/packages/flutter/test/material/popup_menu_test.dart +++ b/packages/flutter/test/material/popup_menu_test.dart @@ -634,6 +634,89 @@ void main() { await testPositioningDownThenUp(tester, TextDirection.rtl, Alignment.bottomCenter, TextDirection.rtl, const Rect.fromLTWH(450.0, 500.0, 0.0, 0.0)); }); + testWidgets('PopupMenu positioning inside nested Overlay', (WidgetTester tester) async { + final Key buttonKey = UniqueKey(); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + appBar: AppBar(title: const Text('Example')), + body: Padding( + padding: const EdgeInsets.all(8.0), + child: Overlay( + initialEntries: [ + OverlayEntry( + builder: (_) => Center( + child: PopupMenuButton( + key: buttonKey, + itemBuilder: (_) => >[ + const PopupMenuItem(value: 1, child: Text('Item 1')), + const PopupMenuItem(value: 2, child: Text('Item 2')), + ], + child: const Text('Show Menu'), + ), + ), + ), + ], + ), + ), + ), + ), + ); + + final Finder buttonFinder = find.byKey(buttonKey); + final Finder popupFinder = find.bySemanticsLabel('Popup menu'); + await tester.tap(buttonFinder); + await tester.pumpAndSettle(); + + final Offset buttonTopLeft = tester.getTopLeft(buttonFinder); + expect(tester.getTopLeft(popupFinder), buttonTopLeft); + }); + + testWidgets('PopupMenu positioning inside nested Navigator', (WidgetTester tester) async { + final Key buttonKey = UniqueKey(); + + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + appBar: AppBar(title: const Text('Example')), + body: Padding( + padding: const EdgeInsets.all(8.0), + child: Navigator( + onGenerateRoute: (RouteSettings settings) { + return MaterialPageRoute( + builder: (BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Center( + child: PopupMenuButton( + key: buttonKey, + itemBuilder: (_) => >[ + const PopupMenuItem(value: 1, child: Text('Item 1')), + const PopupMenuItem(value: 2, child: Text('Item 2')), + ], + child: const Text('Show Menu'), + ), + ), + ); + }, + ); + }, + ), + ), + ), + ), + ); + + final Finder buttonFinder = find.byKey(buttonKey); + final Finder popupFinder = find.bySemanticsLabel('Popup menu'); + await tester.tap(buttonFinder); + await tester.pumpAndSettle(); + + final Offset buttonTopLeft = tester.getTopLeft(buttonFinder); + expect(tester.getTopLeft(popupFinder), buttonTopLeft); + }); + testWidgets('PopupMenu removes MediaQuery padding', (WidgetTester tester) async { late BuildContext popupContext;