From 1a31e396dbd99c426c6da56576b9a4c44c08bc8b Mon Sep 17 00:00:00 2001 From: Srivats Venkataraman <42980667+srivats22@users.noreply.github.com> Date: Wed, 13 Nov 2024 18:34:08 -0500 Subject: [PATCH] #154792 - CupertinoActionSheetAction cursor doesn't change to clickable on desktop (#158470) This PR is for issue #154792 The Video recording shows the before and after The first button with the text "Go" uses the default cursor The second button with the text "With Cursor" uses a custom cursor that has been passed in the parameters https://github.com/user-attachments/assets/e82ecd42-42b1-42c9-aa30-a6f3daddb436 Here is the code for the second button ```dart CupertinoButton( onPressed: () { showCupertinoModalPopup( context: context, builder: (BuildContext context) { return CupertinoActionSheet( title: const Text('The title'), message: const Text('Message'), actions: [ CupertinoActionSheetAction( cursor: SystemMouseCursors.forbidden, child: const Text('One'), onPressed: () {}, ), ], ); }, ); }, child: const Text('With Cursor'), ), ``` Fixes https://github.com/flutter/flutter/issues/154792 --- .../flutter/lib/src/cupertino/dialog.dart | 9 ++++- .../test/cupertino/action_sheet_test.dart | 38 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/flutter/lib/src/cupertino/dialog.dart b/packages/flutter/lib/src/cupertino/dialog.dart index 38151897c9..c264683d08 100644 --- a/packages/flutter/lib/src/cupertino/dialog.dart +++ b/packages/flutter/lib/src/cupertino/dialog.dart @@ -1215,6 +1215,7 @@ class CupertinoActionSheetAction extends StatefulWidget { required this.onPressed, this.isDefaultAction = false, this.isDestructiveAction = false, + this.mouseCursor, required this.child, }); @@ -1234,6 +1235,12 @@ class CupertinoActionSheetAction extends StatefulWidget { /// Destructive buttons have red text. final bool isDestructiveAction; + /// The cursor that will be shown when hovering over the button. + /// + /// If null, defaults to [SystemMouseCursors.click] on web and + /// [MouseCursor.defer] on other platforms. + final MouseCursor? mouseCursor; + /// The widget below this widget in the tree. /// /// Typically a [Text] widget. @@ -1312,7 +1319,7 @@ class _CupertinoActionSheetActionState extends State + fontSize * _kActionSheetButtonVerticalPaddingFactor; return MouseRegion( - cursor: kIsWeb ? SystemMouseCursors.click : MouseCursor.defer, + cursor: widget.mouseCursor ?? (kIsWeb ? SystemMouseCursors.click : MouseCursor.defer), child: MetaData( metaData: this, behavior: HitTestBehavior.opaque, diff --git a/packages/flutter/test/cupertino/action_sheet_test.dart b/packages/flutter/test/cupertino/action_sheet_test.dart index e8c4daf212..0e0186cfc9 100644 --- a/packages/flutter/test/cupertino/action_sheet_test.dart +++ b/packages/flutter/test/cupertino/action_sheet_test.dart @@ -1956,6 +1956,44 @@ void main() { ); }); + testWidgets('CupertinoActionSheet action cursor behavior', (WidgetTester tester) async { + const SystemMouseCursor customCursor = SystemMouseCursors.grab; + + await tester.pumpWidget( + createAppWithButtonThatLaunchesActionSheet( + CupertinoActionSheet( + title: const Text('The title'), + message: const Text('Message'), + actions: [ + CupertinoActionSheetAction( + mouseCursor: customCursor, + onPressed: () { }, + child: const Text('One'), + ), + ], + ), + ), + ); + await tester.tap(find.text('Go')); + await tester.pump(); + + final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1); + await gesture.addPointer(location: const Offset(10, 10)); + await tester.pumpAndSettle(); + expect( + RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), + SystemMouseCursors.basic, + ); + + final Offset actionSheetAction = tester.getCenter(find.text('One')); + await gesture.moveTo(actionSheetAction); + await tester.pumpAndSettle(); + expect( + RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), + customCursor, + ); + }); + testWidgets('Action sheets emits haptic vibration on sliding into a button', (WidgetTester tester) async { int vibrationCount = 0;