From f0bc4dd58066f4b155082990e558ae9c27b29263 Mon Sep 17 00:00:00 2001 From: abdullahtas0 Date: Fri, 14 Aug 2026 00:37:36 +0300 Subject: [PATCH 1/2] Fix MenuAnchor scrollbar safe area padding --- packages/material_ui/lib/src/menu_anchor.dart | 33 ++++++++----- ...ange_2026_08_14_menu_anchor_scrollbar.yaml | 3 ++ .../material_ui/test/menu_anchor_test.dart | 48 +++++++++++++++++++ 3 files changed, 73 insertions(+), 11 deletions(-) create mode 100644 packages/material_ui/pending_changelogs/change_2026_08_14_menu_anchor_scrollbar.yaml diff --git a/packages/material_ui/lib/src/menu_anchor.dart b/packages/material_ui/lib/src/menu_anchor.dart index 14fa9e6b15e1..9027074acf9a 100644 --- a/packages/material_ui/lib/src/menu_anchor.dart +++ b/packages/material_ui/lib/src/menu_anchor.dart @@ -3697,6 +3697,7 @@ class _MenuPanelState extends State<_MenuPanel> { final EdgeInsetsGeometry padding = resolve((MenuStyle? style) => style?.padding) ?? EdgeInsets.zero; final Offset densityAdjustment = visualDensity.baseSizeAdjustment; + final MediaQueryData mediaQuery = MediaQuery.of(context); // Per the Material Design team: don't allow the VisualDensity // adjustment to reduce the width of the left/right padding. If we // did, VisualDensity.compact, the default for desktop/web, would @@ -3757,17 +3758,27 @@ class _MenuPanelState extends State<_MenuPanel> { ).copyWith(scrollbars: false, overscroll: false, physics: const ClampingScrollPhysics()), child: PrimaryScrollController( controller: scrollController, - child: Scrollbar( - thumbVisibility: displayScrollbar, - child: SingleChildScrollView( - controller: scrollController, - scrollDirection: widget.orientation, - child: Flex( - crossAxisAlignment: CrossAxisAlignment.start, - textDirection: Directionality.of(context), - direction: widget.orientation, - mainAxisSize: MainAxisSize.min, - children: children, + child: MediaQuery.removePadding( + context: context, + removeLeft: true, + removeTop: true, + removeRight: true, + removeBottom: true, + child: Scrollbar( + thumbVisibility: displayScrollbar, + child: MediaQuery( + data: mediaQuery, + child: SingleChildScrollView( + controller: scrollController, + scrollDirection: widget.orientation, + child: Flex( + crossAxisAlignment: CrossAxisAlignment.start, + textDirection: Directionality.of(context), + direction: widget.orientation, + mainAxisSize: MainAxisSize.min, + children: children, + ), + ), ), ), ), diff --git a/packages/material_ui/pending_changelogs/change_2026_08_14_menu_anchor_scrollbar.yaml b/packages/material_ui/pending_changelogs/change_2026_08_14_menu_anchor_scrollbar.yaml new file mode 100644 index 000000000000..9edf4d555bc3 --- /dev/null +++ b/packages/material_ui/pending_changelogs/change_2026_08_14_menu_anchor_scrollbar.yaml @@ -0,0 +1,3 @@ +changelog: | + - Fixes `MenuAnchor` scrollbars inheriting system safe-area padding. +version: patch diff --git a/packages/material_ui/test/menu_anchor_test.dart b/packages/material_ui/test/menu_anchor_test.dart index f54165756b32..6d989d5d6839 100644 --- a/packages/material_ui/test/menu_anchor_test.dart +++ b/packages/material_ui/test/menu_anchor_test.dart @@ -566,6 +566,54 @@ void main() { expect(find.byType(Scrollbar).last, paints..rrect(color: const Color(0xff00ff00))); }, variant: TargetPlatformVariant.desktop()); + // Regression test for https://github.com/flutter/flutter/issues/188155. + testWidgets('Menu scrollbar does not inherit MediaQuery padding', (WidgetTester tester) async { + addTearDown(tester.view.reset); + tester.view.devicePixelRatio = 1.0; + tester.view.padding = const FakeViewPadding(bottom: 24.0); + EdgeInsets? menuItemPadding; + + await tester.pumpWidget( + MaterialApp( + home: Material( + child: MenuAnchor( + controller: controller, + style: const MenuStyle( + maximumSize: WidgetStatePropertyAll(Size.fromHeight(100.0)), + ), + menuChildren: [ + Builder( + builder: (BuildContext context) { + menuItemPadding = MediaQuery.paddingOf(context); + return MenuItemButton(onPressed: () {}, child: const Text('Item 0')); + }, + ), + for (int i = 1; i < 4; i++) MenuItemButton(onPressed: () {}, child: Text('Item $i')), + ], + builder: (BuildContext context, MenuController controller, Widget? child) { + return TextButton(onPressed: controller.open, child: const Text('Open menu')); + }, + ), + ), + ), + ); + + await tester.tap(find.text('Open menu')); + await tester.pumpAndSettle(); + + final CustomPaint scrollbarPaint = tester.widget( + find.descendant( + of: find.byType(Scrollbar), + matching: find.byWidgetPredicate( + (Widget widget) => widget is CustomPaint && widget.foregroundPainter is ScrollbarPainter, + ), + ), + ); + final scrollbarPainter = scrollbarPaint.foregroundPainter! as ScrollbarPainter; + expect(scrollbarPainter.padding, EdgeInsets.zero); + expect(menuItemPadding, const EdgeInsets.only(bottom: 24.0)); + }); + testWidgets('Focus is returned to previous focus before invoking onPressed', ( WidgetTester tester, ) async { From 3db34ecd0629a650451ad167fba7971885f9a953 Mon Sep 17 00:00:00 2001 From: abdullahtas0 Date: Fri, 14 Aug 2026 00:52:35 +0300 Subject: [PATCH 2/2] Reuse MenuAnchor MediaQuery data --- packages/material_ui/lib/src/menu_anchor.dart | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/material_ui/lib/src/menu_anchor.dart b/packages/material_ui/lib/src/menu_anchor.dart index 9027074acf9a..68a0c129e451 100644 --- a/packages/material_ui/lib/src/menu_anchor.dart +++ b/packages/material_ui/lib/src/menu_anchor.dart @@ -3758,12 +3758,13 @@ class _MenuPanelState extends State<_MenuPanel> { ).copyWith(scrollbars: false, overscroll: false, physics: const ClampingScrollPhysics()), child: PrimaryScrollController( controller: scrollController, - child: MediaQuery.removePadding( - context: context, - removeLeft: true, - removeTop: true, - removeRight: true, - removeBottom: true, + child: MediaQuery( + data: mediaQuery.removePadding( + removeLeft: true, + removeTop: true, + removeRight: true, + removeBottom: true, + ), child: Scrollbar( thumbVisibility: displayScrollbar, child: MediaQuery(