mirror of
https://github.com/flutter/flutter
synced 2024-09-19 08:11:56 +00:00
Shift tap on an unfocused field (#97543)
This commit is contained in:
parent
ea6025ca49
commit
33a16f44aa
|
@ -951,17 +951,20 @@ class TextSelectionGestureDetectorBuilder {
|
|||
// Either base or extent will be moved to the last tapped position, whichever
|
||||
// is closest. The selection will never shrink or pivot, only grow.
|
||||
//
|
||||
// If fromSelection is given, will expand from that selection instead of the
|
||||
// current selection in renderEditable.
|
||||
//
|
||||
// See also:
|
||||
//
|
||||
// * [_extendSelection], which is similar but pivots the selection around
|
||||
// the base.
|
||||
void _expandSelection(Offset offset, SelectionChangedCause cause) {
|
||||
void _expandSelection(Offset offset, SelectionChangedCause cause, [TextSelection? fromSelection]) {
|
||||
assert(cause != null);
|
||||
assert(offset != null);
|
||||
assert(renderEditable.selection?.baseOffset != null);
|
||||
|
||||
final TextPosition tappedPosition = renderEditable.getPositionForPoint(offset);
|
||||
final TextSelection selection = renderEditable.selection!;
|
||||
final TextSelection selection = fromSelection ?? renderEditable.selection!;
|
||||
final bool baseIsCloser =
|
||||
(tappedPosition.offset - selection.baseOffset).abs()
|
||||
< (tappedPosition.offset - selection.extentOffset).abs();
|
||||
|
@ -1069,7 +1072,16 @@ class TextSelectionGestureDetectorBuilder {
|
|||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
_expandSelection(details.globalPosition, SelectionChangedCause.tap);
|
||||
// On these platforms, a shift-tapped unfocused field expands from 0,
|
||||
// not from the previous selection.
|
||||
final TextSelection? fromSelection = renderEditable.hasFocus
|
||||
? null
|
||||
: const TextSelection.collapsed(offset: 0);
|
||||
_expandSelection(
|
||||
details.globalPosition,
|
||||
SelectionChangedCause.tap,
|
||||
fromSelection,
|
||||
);
|
||||
break;
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
|
|
|
@ -5053,6 +5053,62 @@ void main() {
|
|||
expect(controller.selection.extentOffset, 4);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows }));
|
||||
|
||||
testWidgets('shift tapping an unfocused field', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
final FocusNode focusNode = FocusNode();
|
||||
await tester.pumpWidget(
|
||||
CupertinoApp(
|
||||
home: Center(
|
||||
child: CupertinoTextField(
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(focusNode.hasFocus, isFalse);
|
||||
|
||||
// Put the cursor at the end of the field.
|
||||
await tester.tapAt(textOffsetToPosition(tester, controller.text.length));
|
||||
await tester.pump(kDoubleTapTimeout);
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasFocus, isTrue);
|
||||
expect(controller.selection.baseOffset, 35);
|
||||
expect(controller.selection.extentOffset, 35);
|
||||
|
||||
// Unfocus the field, but the selection remains.
|
||||
focusNode.unfocus();
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasFocus, isFalse);
|
||||
expect(controller.selection.baseOffset, 35);
|
||||
expect(controller.selection.extentOffset, 35);
|
||||
|
||||
// Shift tap in the middle of the field.
|
||||
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
|
||||
await tester.tapAt(textOffsetToPosition(tester, 20));
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasFocus, isTrue);
|
||||
switch (defaultTargetPlatform) {
|
||||
// Apple platforms start the selection from 0.
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
expect(controller.selection.baseOffset, 0);
|
||||
break;
|
||||
|
||||
// Other platforms start from the previous selection.
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
case TargetPlatform.linux:
|
||||
case TargetPlatform.windows:
|
||||
expect(controller.selection.baseOffset, 35);
|
||||
break;
|
||||
}
|
||||
expect(controller.selection.extentOffset, 20);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('can shift + tap + drag to select with a keyboard (Apple platforms)', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
|
|
|
@ -10560,6 +10560,63 @@ void main() {
|
|||
expect(controller.selection.extentOffset, 4);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.fuchsia, TargetPlatform.linux, TargetPlatform.windows }));
|
||||
|
||||
testWidgets('shift tapping an unfocused field', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
final FocusNode focusNode = FocusNode();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
expect(focusNode.hasFocus, isFalse);
|
||||
|
||||
// Put the cursor at the end of the field.
|
||||
await tester.tapAt(textOffsetToPosition(tester, controller.text.length));
|
||||
await tester.pump(kDoubleTapTimeout);
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasFocus, isTrue);
|
||||
expect(controller.selection.baseOffset, 35);
|
||||
expect(controller.selection.extentOffset, 35);
|
||||
|
||||
// Unfocus the field, but the selection remains.
|
||||
focusNode.unfocus();
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasFocus, isFalse);
|
||||
expect(controller.selection.baseOffset, 35);
|
||||
expect(controller.selection.extentOffset, 35);
|
||||
|
||||
// Shift tap in the middle of the field.
|
||||
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
|
||||
await tester.tapAt(textOffsetToPosition(tester, 20));
|
||||
await tester.pumpAndSettle();
|
||||
expect(focusNode.hasFocus, isTrue);
|
||||
switch (defaultTargetPlatform) {
|
||||
// Apple platforms start the selection from 0.
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
expect(controller.selection.baseOffset, 0);
|
||||
break;
|
||||
|
||||
// Other platforms start from the previous selection.
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
case TargetPlatform.linux:
|
||||
case TargetPlatform.windows:
|
||||
expect(controller.selection.baseOffset, 35);
|
||||
break;
|
||||
}
|
||||
expect(controller.selection.extentOffset, 20);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('can shift + tap + drag to select with a keyboard (Apple platforms)', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
|
|
Loading…
Reference in a new issue