Skip to content

Commit 6ffcc9e

Browse files
authored
Hide the context menu on tap down (#126295)
Desktop text selection toolbar no longer flashes before closing.
1 parent 15a7e07 commit 6ffcc9e

File tree

3 files changed

+97
-3
lines changed

3 files changed

+97
-3
lines changed

packages/flutter/lib/src/widgets/text_selection.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,10 +2108,13 @@ class TextSelectionGestureDetectorBuilder {
21082108
switch (defaultTargetPlatform) {
21092109
case TargetPlatform.android:
21102110
case TargetPlatform.fuchsia:
2111+
// On mobile platforms the selection is set on tap up.
2112+
editableText.hideToolbar(false);
21112113
case TargetPlatform.iOS:
21122114
// On mobile platforms the selection is set on tap up.
21132115
break;
21142116
case TargetPlatform.macOS:
2117+
editableText.hideToolbar();
21152118
// On macOS, a shift-tapped unfocused field expands from 0, not from the
21162119
// previous selection.
21172120
if (isShiftPressedValid) {
@@ -2132,6 +2135,7 @@ class TextSelectionGestureDetectorBuilder {
21322135
renderEditable.selectPosition(cause: SelectionChangedCause.tap);
21332136
case TargetPlatform.linux:
21342137
case TargetPlatform.windows:
2138+
editableText.hideToolbar();
21352139
if (isShiftPressedValid) {
21362140
_extendSelection(details.globalPosition, SelectionChangedCause.tap);
21372141
return;
@@ -2206,18 +2210,16 @@ class TextSelectionGestureDetectorBuilder {
22062210
case TargetPlatform.linux:
22072211
case TargetPlatform.macOS:
22082212
case TargetPlatform.windows:
2209-
editableText.hideToolbar();
2213+
break;
22102214
// On desktop platforms the selection is set on tap down.
22112215
case TargetPlatform.android:
2212-
editableText.hideToolbar();
22132216
if (isShiftPressedValid) {
22142217
_extendSelection(details.globalPosition, SelectionChangedCause.tap);
22152218
return;
22162219
}
22172220
renderEditable.selectPosition(cause: SelectionChangedCause.tap);
22182221
editableText.showSpellCheckSuggestionsToolbar();
22192222
case TargetPlatform.fuchsia:
2220-
editableText.hideToolbar();
22212223
if (isShiftPressedValid) {
22222224
_extendSelection(details.globalPosition, SelectionChangedCause.tap);
22232225
return;

packages/flutter/test/cupertino/text_field_test.dart

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9513,4 +9513,49 @@ void main() {
95139513
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }),
95149514
skip: kIsWeb, // [intended]
95159515
);
9516+
9517+
testWidgets('text selection toolbar is hidden on tap down', (WidgetTester tester) async {
9518+
final TextEditingController controller = TextEditingController(
9519+
text: 'blah1 blah2',
9520+
);
9521+
await tester.pumpWidget(
9522+
CupertinoApp(
9523+
home: Center(
9524+
child: CupertinoTextField(
9525+
controller: controller,
9526+
),
9527+
),
9528+
),
9529+
);
9530+
9531+
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
9532+
9533+
TestGesture gesture = await tester.startGesture(
9534+
textOffsetToPosition(tester, 8),
9535+
kind: PointerDeviceKind.mouse,
9536+
buttons: kSecondaryMouseButton,
9537+
);
9538+
await tester.pump();
9539+
await gesture.up();
9540+
await tester.pumpAndSettle();
9541+
9542+
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsOneWidget);
9543+
9544+
gesture = await tester.startGesture(
9545+
textOffsetToPosition(tester, 2),
9546+
kind: PointerDeviceKind.mouse,
9547+
);
9548+
await tester.pump();
9549+
9550+
// After the gesture is down but not up, the toolbar is already gone.
9551+
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
9552+
9553+
await gesture.up();
9554+
await tester.pumpAndSettle();
9555+
9556+
expect(find.byType(CupertinoAdaptiveTextSelectionToolbar), findsNothing);
9557+
},
9558+
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
9559+
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }),
9560+
);
95169561
}

packages/flutter/test/material/text_field_test.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16315,6 +16315,53 @@ void main() {
1631516315
expectedConfiguration.spellCheckSuggestionsToolbarBuilder,
1631616316
);
1631716317
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.iOS }));
16318+
16319+
testWidgets('text selection toolbar is hidden on tap down', (WidgetTester tester) async {
16320+
final TextEditingController controller = TextEditingController(
16321+
text: 'blah1 blah2',
16322+
);
16323+
await tester.pumpWidget(
16324+
MaterialApp(
16325+
home: Scaffold(
16326+
body: Center(
16327+
child: TextField(
16328+
controller: controller,
16329+
),
16330+
),
16331+
),
16332+
),
16333+
);
16334+
16335+
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
16336+
16337+
TestGesture gesture = await tester.startGesture(
16338+
textOffsetToPosition(tester, 8),
16339+
kind: PointerDeviceKind.mouse,
16340+
buttons: kSecondaryMouseButton,
16341+
);
16342+
await tester.pump();
16343+
await gesture.up();
16344+
await tester.pumpAndSettle();
16345+
16346+
expect(find.byType(AdaptiveTextSelectionToolbar), findsOneWidget);
16347+
16348+
gesture = await tester.startGesture(
16349+
textOffsetToPosition(tester, 2),
16350+
kind: PointerDeviceKind.mouse,
16351+
);
16352+
await tester.pump();
16353+
16354+
// After the gesture is down but not up, the toolbar is already gone.
16355+
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
16356+
16357+
await gesture.up();
16358+
await tester.pumpAndSettle();
16359+
16360+
expect(find.byType(AdaptiveTextSelectionToolbar), findsNothing);
16361+
},
16362+
skip: isContextMenuProvidedByPlatform, // [intended] only applies to platforms where we supply the context menu.
16363+
variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }),
16364+
);
1631816365
}
1631916366

1632016367
/// A Simple widget for testing the obscure text.

0 commit comments

Comments
 (0)