mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix disabled DropdownMenu doesn't defer the mouse cursor (#145686)
fixes [DropdownMenu cursor in disabled state](https://github.com/flutter/flutter/issues/144611) This was added in https://github.com/flutter/flutter/pull/121353 ### Code sample <details> <summary>expand to view the code sample</summary> ```dart import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( body: Center( child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ const Spacer(), const Text('enabled: true,\nrequestFocusOnTap: true,'), const SizedBox(height: 16), DropdownMenu<String>( enabled: true, initialSelection: 'First', requestFocusOnTap: true, width: 200, dropdownMenuEntries: ['First', 'Second', 'Third'] .map((e) => DropdownMenuEntry(value: e, label: e)) .toList(), ), const Text('Expected: text cursor'), const Spacer(), const Text('enabled: true,\nrequestFocusOnTap: false,'), const SizedBox(height: 16), DropdownMenu<String>( enabled: true, initialSelection: 'First', requestFocusOnTap: false, width: 200, dropdownMenuEntries: ['First', 'Second', 'Third'] .map((e) => DropdownMenuEntry(value: e, label: e)) .toList(), // label: const Text('requestFocusOnTap: false'), ), const Text('Expected: clickable cursor'), const Spacer(), const Text('enabled: false,\nrequestFocusOnTap: true,'), const SizedBox(height: 16), DropdownMenu<String>( enabled: false, initialSelection: 'First', requestFocusOnTap: true, width: 200, dropdownMenuEntries: ['First', 'Second', 'Third'] .map((e) => DropdownMenuEntry(value: e, label: e)) .toList(), ), const Text('Expected: deferred cursor'), const Spacer(), const Text('enabled: false,\nrequestFocusOnTap: false,'), const SizedBox(height: 16), DropdownMenu<String>( enabled: false, initialSelection: 'First', requestFocusOnTap: false, width: 200, dropdownMenuEntries: ['First', 'Second', 'Third'] .map((e) => DropdownMenuEntry(value: e, label: e)) .toList(), ), const Text('Expected: deferred cursor'), const Spacer(), ], ), ), ), ); } } ``` </details> ### Preview 
This commit is contained in:
parent
8d31c58333
commit
d2c8552944
@ -699,7 +699,10 @@ class _DropdownMenuState<T> extends State<DropdownMenu<T>> {
|
||||
?? theme.inputDecorationTheme
|
||||
?? defaults.inputDecorationTheme!;
|
||||
|
||||
final MouseCursor effectiveMouseCursor = canRequestFocus() ? SystemMouseCursors.text : SystemMouseCursors.click;
|
||||
final MouseCursor? effectiveMouseCursor = switch (widget.enabled) {
|
||||
true => canRequestFocus() ? SystemMouseCursors.text : SystemMouseCursors.click,
|
||||
false => null,
|
||||
};
|
||||
|
||||
Widget menuAnchor = MenuAnchor(
|
||||
style: effectiveMenuStyle,
|
||||
|
||||
@ -1342,6 +1342,68 @@ void main() {
|
||||
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
|
||||
});
|
||||
|
||||
testWidgets('If enabled is false, the mouse cursor should be deferred when hovered', (WidgetTester tester) async {
|
||||
Widget buildDropdownMenu({ bool enabled = true, bool? requestFocusOnTap }) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
DropdownMenu<TestMenu>(
|
||||
enabled: enabled,
|
||||
requestFocusOnTap: requestFocusOnTap,
|
||||
dropdownMenuEntries: menuChildren,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Check mouse cursor dropdown menu is disabled and requestFocusOnTap is true.
|
||||
await tester.pumpWidget(buildDropdownMenu(enabled: false, requestFocusOnTap: true));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
Finder textFieldFinder = find.byType(TextField);
|
||||
TextField textField = tester.widget<TextField>(textFieldFinder);
|
||||
expect(textField.canRequestFocus, true);
|
||||
|
||||
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
|
||||
await gesture.moveTo(tester.getCenter(textFieldFinder));
|
||||
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
|
||||
|
||||
// Remove the pointer.
|
||||
await gesture.removePointer();
|
||||
|
||||
// Check mouse cursor dropdown menu is disabled and requestFocusOnTap is false.
|
||||
await tester.pumpWidget(buildDropdownMenu(enabled: false, requestFocusOnTap: false));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
textFieldFinder = find.byType(TextField);
|
||||
textField = tester.widget<TextField>(textFieldFinder);
|
||||
expect(textField.canRequestFocus, false);
|
||||
|
||||
// Add a new pointer.
|
||||
await gesture.addPointer();
|
||||
await gesture.moveTo(tester.getCenter(textFieldFinder));
|
||||
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.basic);
|
||||
|
||||
// Remove the pointer.
|
||||
await gesture.removePointer();
|
||||
|
||||
// Check enabled dropdown menu updates the mouse cursor when hovered.
|
||||
await tester.pumpWidget(buildDropdownMenu(requestFocusOnTap: true));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
textFieldFinder = find.byType(TextField);
|
||||
textField = tester.widget<TextField>(textFieldFinder);
|
||||
expect(textField.canRequestFocus, true);
|
||||
|
||||
// Add a new pointer.
|
||||
await gesture.addPointer();
|
||||
await gesture.moveTo(tester.getCenter(textFieldFinder));
|
||||
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);
|
||||
});
|
||||
|
||||
testWidgets('The menu has the same width as the input field in ListView', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/123631
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user