Skip to content

Commit

Permalink
Hide SelectableRegion text selection toolbar when orientation chang…
Browse files Browse the repository at this point in the history
…es (#104841)
  • Loading branch information
markusaksli-nc authored May 27, 2022
1 parent 053144b commit 62eebb4
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 1 deletion.
32 changes: 31 additions & 1 deletion packages/flutter/lib/src/widgets/selectable_region.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import 'focus_manager.dart';
import 'focus_scope.dart';
import 'framework.dart';
import 'gesture_detector.dart';
import 'media_query.dart';
import 'overlay.dart';
import 'selection_container.dart';
import 'text_editing_intents.dart';
Expand Down Expand Up @@ -212,6 +213,8 @@ class _SelectableRegionState extends State<SelectableRegion> with TextSelectionD
bool get _hasSelectionOverlayGeometry => _selectionDelegate.value.startSelectionPoint != null
|| _selectionDelegate.value.endSelectionPoint != null;

Orientation? _lastOrientation;

@override
void initState() {
super.initState();
Expand All @@ -228,6 +231,33 @@ class _SelectableRegionState extends State<SelectableRegion> with TextSelectionD
);
}

@override
void didChangeDependencies() {
super.didChangeDependencies();

switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.iOS:
break;
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
return;
}

// Hide the text selection toolbar on mobile when orientation changes.
final Orientation orientation = MediaQuery.of(context).orientation;
if (_lastOrientation == null) {
_lastOrientation = orientation;
return;
}
if (orientation != _lastOrientation) {
_lastOrientation = orientation;
hideToolbar(defaultTargetPlatform == TargetPlatform.android);
}
}

@override
void didUpdateWidget(SelectableRegion oldWidget) {
super.didUpdateWidget(oldWidget);
Expand Down Expand Up @@ -703,7 +733,7 @@ class _SelectableRegionState extends State<SelectableRegion> with TextSelectionD
void hideToolbar([bool hideHandles = true]) {
_selectionOverlay?.hideToolbar();
if (hideHandles) {
_selectionOverlay?.hideToolbar();
_selectionOverlay?.hideHandles();
}
}

Expand Down
40 changes: 40 additions & 0 deletions packages/flutter/test/widgets/selectable_region_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,46 @@ void main() {
expect(clipboardData['text'], 'thank');
}, skip: kIsWeb); // [intended] Web uses its native context menu.
});

testWidgets('toolbar is hidden on mobile when orientation changes', (WidgetTester tester) async {
await tester.pumpWidget(
MaterialApp(
home: SelectableRegion(
focusNode: FocusNode(),
selectionControls: materialTextSelectionControls,
child: const Text('How are you?'),
),
),
);
addTearDown(tester.binding.window.clearPhysicalSizeTestValue);

final RenderParagraph paragraph1 = tester.renderObject<RenderParagraph>(find.descendant(of: find.text('How are you?'), matching: find.byType(RichText)));
final TestGesture gesture = await tester.startGesture(textOffsetToPosition(paragraph1, 6)); // at the 'r'
addTearDown(gesture.removePointer);
await tester.pump(const Duration(milliseconds: 500));
// `are` is selected.
expect(paragraph1.selections[0], const TextSelection(baseOffset: 4, extentOffset: 7));
await tester.pumpAndSettle();
// Text selection toolbar has appeared.
expect(find.text('Copy'), findsOneWidget);

// Hide the toolbar by changing orientation.
tester.binding.window.physicalSizeTestValue = const Size(1800.0, 2400.0);
await tester.pumpAndSettle();
expect(find.text('Copy'), findsNothing);

// Handles should be hidden as well on Android
expect(
find.descendant(
of: find.byType(CompositedTransformFollower),
matching: find.byType(Padding),
),
defaultTargetPlatform == TargetPlatform.android ? findsNothing : findsNWidgets(2),
);
},
skip: kIsWeb, // [intended] Web uses its native context menu.
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.android }),
);
}

class SelectionSpy extends LeafRenderObjectWidget {
Expand Down

0 comments on commit 62eebb4

Please sign in to comment.