Unverified Commit e0ea39fe authored by acumen's avatar acumen Committed by GitHub

Reland "Fix bug with clicking `Copy` or `Select All` within contextMenu" (#122973)

Reland "Fix bug with clicking `Copy` or `Select All` within contextMenu"
parent e6e99e2d
......@@ -319,6 +319,12 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
/// {@macro flutter.rendering.RenderEditable.lastSecondaryTapDownPosition}
Offset? lastSecondaryTapDownPosition;
/// The [SelectionOverlay] that is currently visible on the screen.
///
/// Can be null if there is no visible [SelectionOverlay].
@visibleForTesting
SelectionOverlay? get selectionOverlay => _selectionOverlay;
@override
void initState() {
super.initState();
......@@ -988,11 +994,37 @@ class SelectableRegionState extends State<SelectableRegion> with TextSelectionDe
selectionGeometry: _selectionDelegate.value,
onCopy: () {
_copy();
hideToolbar();
// In Android copy should clear the selection.
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
_clearSelection();
break;
case TargetPlatform.iOS:
hideToolbar(false);
break;
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
hideToolbar();
break;
}
},
onSelectAll: () {
selectAll();
hideToolbar();
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.iOS:
case TargetPlatform.fuchsia:
selectAll(SelectionChangedCause.toolbar);
break;
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
selectAll();
hideToolbar();
break;
}
},
);
}
......
......@@ -926,6 +926,7 @@ void main() {
),
),
);
final RenderParagraph paragraph2 = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('Good, and you?'), matching: find.byType(RichText)));
final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph2, 7)); // at the 'a'
addTearDown(gesture.removePointer);
......@@ -1708,6 +1709,115 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.android }),
);
testWidgets('the selection behavior when clicking `Copy` item in mobile platforms', (WidgetTester tester) async {
List<ContextMenuButtonItem> buttonItems = <ContextMenuButtonItem>[];
await tester.pumpWidget(
MaterialApp(
home: SelectableRegion(
focusNode: FocusNode(),
selectionControls: materialTextSelectionHandleControls,
contextMenuBuilder: (
BuildContext context,
SelectableRegionState selectableRegionState,
) {
buttonItems = selectableRegionState.contextMenuButtonItems;
return const SizedBox.shrink();
},
child: const Text('How are you?'),
),
),
);
final RenderParagraph paragraph1 = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('How are you?'), matching: find.byType(RichText)));
await tester.longPressAt(textOffsetToPosition(paragraph1, 6)); // at the 'r'
await tester.pump(kLongPressTimeout);
// `are` is selected.
expect(paragraph1.selections[0], const TextSelection(baseOffset: 4, extentOffset: 7));
expect(buttonItems.length, 2);
expect(buttonItems[0].type, ContextMenuButtonType.copy);
// Press `Copy` item
buttonItems[0].onPressed.call();
final SelectableRegionState regionState = tester.state<SelectableRegionState>(find.byType(SelectableRegion));
// In Android copy should clear the selection.
switch(defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
expect(regionState.selectionOverlay, isNull);
expect(regionState.selectionOverlay?.startHandleLayerLink, isNull);
expect(regionState.selectionOverlay?.endHandleLayerLink, isNull);
break;
case TargetPlatform.iOS:
expect(regionState.selectionOverlay, isNotNull);
expect(regionState.selectionOverlay?.startHandleLayerLink, isNotNull);
expect(regionState.selectionOverlay?.endHandleLayerLink, isNotNull);
break;
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
expect(regionState.selectionOverlay, isNotNull);
break;
}
},
skip: kIsWeb, // [intended]
);
testWidgets('the handles do not disappear when clicking `Select all` item in mobile platforms', (WidgetTester tester) async {
List<ContextMenuButtonItem> buttonItems = <ContextMenuButtonItem>[];
await tester.pumpWidget(
MaterialApp(
home: SelectableRegion(
focusNode: FocusNode(),
selectionControls: materialTextSelectionHandleControls,
contextMenuBuilder: (
BuildContext context,
SelectableRegionState selectableRegionState,
) {
buttonItems = selectableRegionState.contextMenuButtonItems;
return const SizedBox.shrink();
},
child: const Text('How are you?'),
),
),
);
final RenderParagraph paragraph1 = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('How are you?'), matching: find.byType(RichText)));
await tester.longPressAt(textOffsetToPosition(paragraph1, 6)); // at the 'r'
await tester.pump(kLongPressTimeout);
// `are` is selected.
expect(paragraph1.selections[0], const TextSelection(baseOffset: 4, extentOffset: 7));
expect(buttonItems.length, 2);
expect(buttonItems[1].type, ContextMenuButtonType.selectAll);
// Press `Select All` item
buttonItems[1].onPressed.call();
final SelectableRegionState regionState = tester.state<SelectableRegionState>(find.byType(SelectableRegion));
switch(defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.iOS:
case TargetPlatform.fuchsia:
expect(regionState.selectionOverlay, isNotNull);
expect(regionState.selectionOverlay?.startHandleLayerLink, isNotNull);
expect(regionState.selectionOverlay?.endHandleLayerLink, isNotNull);
break;
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
// Test doesn't run these platforms.
break;
}
},
skip: kIsWeb, // [intended]
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.android, TargetPlatform.fuchsia }),
);
testWidgets('builds the correct button items', (WidgetTester tester) async {
Set<ContextMenuButtonType> buttonTypes = <ContextMenuButtonType>{};
await tester.pumpWidget(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment