SelectionArea on iOS should toggle the context menu when tapping on the previous selection (#132851)
https://github.com/flutter/flutter/assets/948037/210fdee4-d922-422b-a257-4ee586a3814f Related: https://github.com/flutter/flutter/issues/129583
This commit is contained in:
parent
d5a162b788
commit
2ecb8866a2
@ -341,7 +341,20 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
|
||||
_gestureRecognizers[TapGestureRecognizer] = GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
|
||||
() => TapGestureRecognizer(debugOwner: this),
|
||||
(TapGestureRecognizer instance) {
|
||||
instance.onTap = _clearSelection;
|
||||
instance.onTapUp = (TapUpDetails details) {
|
||||
if (defaultTargetPlatform == TargetPlatform.iOS && _positionIsOnActiveSelection(globalPosition: details.globalPosition)) {
|
||||
// On iOS when the tap occurs on the previous selection, instead of
|
||||
// moving the selection, the context menu will be toggled.
|
||||
final bool toolbarIsVisible = _selectionOverlay?.toolbarIsVisible ?? false;
|
||||
if (toolbarIsVisible) {
|
||||
hideToolbar(false);
|
||||
} else {
|
||||
_showToolbar(location: details.globalPosition);
|
||||
}
|
||||
} else {
|
||||
_clearSelection();
|
||||
}
|
||||
};
|
||||
instance.onSecondaryTapDown = _handleRightClickDown;
|
||||
},
|
||||
);
|
||||
|
@ -886,6 +886,78 @@ void main() {
|
||||
await gesture.up();
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'single tap on the previous selection toggles the toolbar on iOS',
|
||||
(WidgetTester tester) async {
|
||||
Set<ContextMenuButtonType> buttonTypes = <ContextMenuButtonType>{};
|
||||
final UniqueKey toolbarKey = UniqueKey();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: SelectableRegion(
|
||||
focusNode: FocusNode(),
|
||||
selectionControls: materialTextSelectionHandleControls,
|
||||
contextMenuBuilder: (
|
||||
BuildContext context,
|
||||
SelectableRegionState selectableRegionState,
|
||||
) {
|
||||
buttonTypes = selectableRegionState.contextMenuButtonItems
|
||||
.map((ContextMenuButtonItem buttonItem) => buttonItem.type)
|
||||
.toSet();
|
||||
return SizedBox.shrink(key: toolbarKey);
|
||||
},
|
||||
child: const Column(
|
||||
children: <Widget>[
|
||||
Text('How are you?'),
|
||||
Text('Good, and you?'),
|
||||
Text('Fine, thank you.'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(buttonTypes.isEmpty, true);
|
||||
expect(find.byKey(toolbarKey), findsNothing);
|
||||
|
||||
final RenderParagraph paragraph = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('How are you?'), matching: find.byType(RichText)));
|
||||
final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph, 2));
|
||||
addTearDown(gesture.removePointer);
|
||||
await tester.pump(const Duration(milliseconds: 500));
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 3));
|
||||
expect(buttonTypes, contains(ContextMenuButtonType.copy));
|
||||
expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
|
||||
expect(find.byKey(toolbarKey), findsOneWidget);
|
||||
|
||||
await gesture.down(textOffsetToPosition(paragraph, 2));
|
||||
await tester.pump();
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 3));
|
||||
expect(buttonTypes, contains(ContextMenuButtonType.copy));
|
||||
expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
|
||||
expect(find.byKey(toolbarKey), findsNothing);
|
||||
|
||||
await gesture.down(textOffsetToPosition(paragraph, 2));
|
||||
await tester.pump();
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
expect(paragraph.selections[0], const TextSelection(baseOffset: 0, extentOffset: 3));
|
||||
expect(buttonTypes, contains(ContextMenuButtonType.copy));
|
||||
expect(buttonTypes, contains(ContextMenuButtonType.selectAll));
|
||||
expect(find.byKey(toolbarKey), findsOneWidget);
|
||||
|
||||
// Clear selection.
|
||||
await tester.tapAt(textOffsetToPosition(paragraph, 9));
|
||||
await tester.pump();
|
||||
expect(paragraph.selections.isEmpty, true);
|
||||
expect(find.byKey(toolbarKey), findsNothing);
|
||||
},
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.iOS),
|
||||
skip: kIsWeb, // [intended] Web uses its native context menu.
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'right-click mouse can select word at position on Apple platforms',
|
||||
(WidgetTester tester) async {
|
||||
|
Loading…
x
Reference in New Issue
Block a user