From f6747dfa100b578c2425c2b684aade95260b444a Mon Sep 17 00:00:00 2001 From: Justin Hutchins <44933935+jushutch@users.noreply.github.com> Date: Fri, 14 May 2021 13:39:13 -0400 Subject: [PATCH] Change cursor when hovering on DropdownButton (#80567) --- .../flutter/lib/src/material/dropdown.dart | 19 ++++-- .../flutter/test/material/dropdown_test.dart | 59 +++++++++++++++++++ 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/packages/flutter/lib/src/material/dropdown.dart b/packages/flutter/lib/src/material/dropdown.dart index af799084231..4fb769dcdc0 100644 --- a/packages/flutter/lib/src/material/dropdown.dart +++ b/packages/flutter/lib/src/material/dropdown.dart @@ -19,6 +19,7 @@ import 'ink_well.dart'; import 'input_decorator.dart'; import 'material.dart'; import 'material_localizations.dart'; +import 'material_state.dart'; import 'scrollbar.dart'; import 'shadows.dart'; import 'theme.dart'; @@ -1501,6 +1502,13 @@ class _DropdownButtonState extends State> with WidgetsBindi ); } + final MouseCursor effectiveMouseCursor = MaterialStateProperty.resolveAs( + MaterialStateMouseCursor.clickable, + { + if (!_enabled) MaterialState.disabled, + }, + ); + return Semantics( button: true, child: Actions( @@ -1509,10 +1517,13 @@ class _DropdownButtonState extends State> with WidgetsBindi canRequestFocus: _enabled, focusNode: focusNode, autofocus: widget.autofocus, - child: GestureDetector( - onTap: _enabled ? _handleTap : null, - behavior: HitTestBehavior.opaque, - child: result, + child: MouseRegion( + cursor: effectiveMouseCursor, + child: GestureDetector( + onTap: _enabled ? _handleTap : null, + behavior: HitTestBehavior.opaque, + child: result, + ), ), ), ), diff --git a/packages/flutter/test/material/dropdown_test.dart b/packages/flutter/test/material/dropdown_test.dart index 22e1b788c27..2f0668a0535 100644 --- a/packages/flutter/test/material/dropdown_test.dart +++ b/packages/flutter/test/material/dropdown_test.dart @@ -5,6 +5,7 @@ import 'dart:math' as math; import 'dart:ui' show window; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; @@ -3390,4 +3391,62 @@ void main() { expect(feedback.hapticCount, 0); }); }); + + testWidgets('DropdownButton changes mouse cursor when hovered', (WidgetTester tester) async { + const Key key = Key('testDropdownButton'); + await tester.pumpWidget( + MaterialApp( + home: Material( + child: DropdownButton( + key: key, + onChanged: (String? newValue) {}, + items: ['One', 'Two', 'Three', 'Four'] + .map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList() + ), + ), + ), + ); + + final Finder dropdownButtonFinder = find.byKey(key); + final Offset onDropdownButton = tester.getCenter(dropdownButtonFinder); + final Offset offDropdownButton = tester.getBottomRight(dropdownButtonFinder) + const Offset(1, 1); + final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1); + + await gesture.addPointer(location: onDropdownButton); + addTearDown(gesture.removePointer); + + await tester.pump(); + + expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click); + await gesture.moveTo(offDropdownButton); + expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); + + // Test that mouse cursor doesn't change when button is disabled + await tester.pumpWidget( + MaterialApp( + home: Material( + child: DropdownButton( + key: key, + items: ['One', 'Two', 'Three', 'Four'] + .map>((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList() + ), + ), + ), + ); + + await gesture.moveTo(onDropdownButton); + expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); + await gesture.moveTo(offDropdownButton); + expect(RendererBinding.instance!.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic); + }); }