CupertinoContextMenu child respects available screen width (#175300)

Missed this in [Correct position for an open
CupertinoContextMenu](https://github.com/flutter/flutter/pull/170943)

Fixes [CupertinoContextMenu wrong
position](https://github.com/flutter/flutter/issues/175225)
This commit is contained in:
Victor Sanni 2025-09-17 13:38:13 -07:00 committed by GitHub
parent f2c2d6422e
commit 48d2277199
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 95 additions and 1 deletions

View File

@ -1463,10 +1463,17 @@ class _ContextMenuAlignedChildrenDelegate extends MultiChildLayoutDelegate {
final double availableHeightForChild =
screenBounds.height - _ContextMenuRouteStaticState._kPadding;
final double availableWidth = screenBounds.width - _ContextMenuRouteStaticState._kPadding * 2;
final double availableWidthForChild = switch (orientation) {
Orientation.portrait => availableWidth,
Orientation.landscape => availableWidth - _ContextMenuSheetState._kMenuWidth,
};
assert(availableWidthForChild >= 0.0);
assert(availableHeightForChild >= 0.0);
final Size childSize = layoutChild(
_ContextMenuChild.child,
constraints.copyWith(maxHeight: availableHeightForChild),
constraints.copyWith(maxHeight: availableHeightForChild, maxWidth: availableWidthForChild),
);
// In portrait orientation, the child is atop the menu, while in landscape

View File

@ -1453,4 +1453,91 @@ void main() {
);
});
});
testWidgets('CupertinoContextMenu respects available screen width - Portrait', (
WidgetTester tester,
) async {
const Size portraitScreenSize = Size(300.0, 350.0);
await binding.setSurfaceSize(portraitScreenSize);
addTearDown(() => binding.setSurfaceSize(null));
final Widget child = getChild();
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(size: portraitScreenSize),
child: CupertinoApp(
home: Center(
child: CupertinoContextMenu(
actions: <Widget>[
CupertinoContextMenuAction(child: const Text('Test'), onPressed: () {}),
],
child: child,
),
),
),
),
);
expect(find.byWidget(child), findsOneWidget);
final Rect childRect = tester.getRect(find.byWidget(child));
// Start a press on the child.
final TestGesture gesture = await tester.startGesture(childRect.center);
await tester.pump();
await tester.pump(const Duration(milliseconds: 500));
await gesture.up();
await tester.pumpAndSettle();
expect(tester.takeException(), null);
// Verify the child width is constrained correctly.
expect(findStatic(), findsOneWidget);
final Size fittedBoxSize = tester.getSize(findFittedBox());
// availableWidth = 300.0 (screen width) - 2 * 20.0 (padding) = 260.0
expect(fittedBoxSize.width, 260.0);
});
testWidgets('CupertinoContextMenu respects available screen width - Landscape', (
WidgetTester tester,
) async {
const Size landscapeScreenSize = Size(350.0, 300.0);
await binding.setSurfaceSize(landscapeScreenSize);
addTearDown(() => binding.setSurfaceSize(null));
final Widget child = getChild(width: 500);
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(size: landscapeScreenSize),
child: CupertinoApp(
home: Center(
child: CupertinoContextMenu(
actions: <Widget>[
CupertinoContextMenuAction(child: const Text('Test'), onPressed: () {}),
],
child: child,
),
),
),
),
);
expect(find.byWidget(child), findsOneWidget);
final Rect childRect = tester.getRect(find.byWidget(child));
// Start a press on the child.
final TestGesture gesture = await tester.startGesture(childRect.center);
await tester.pump();
await tester.pump(const Duration(milliseconds: 500));
await gesture.up();
await tester.pumpAndSettle();
expect(tester.takeException(), null);
// Verify the child width is constrained correctly.
expect(findStatic(), findsOneWidget);
final Size fittedBoxSize = tester.getSize(findFittedBox());
// availableWidth = 350.0 (screen width) - 2 * 20.0 (padding) = 310.0
// availableWidthForChild = 310.0 - 250.0 (menu width) = 60.0
expect(fittedBoxSize.width, 60.0);
});
}