Unverified Commit 4c1d887e authored by Renzo Olivares's avatar Renzo Olivares Committed by GitHub

Set selection on tap down for desktop platforms and tap up for mobile (#105505)

Co-authored-by: 's avatarRenzo Olivares <roliv@google.com>
parent 2c13db3b
......@@ -1454,6 +1454,9 @@ class TextSelectionGestureDetectorBuilder {
/// * [TextSelectionGestureDetector.onTapDown], which triggers this callback.
@protected
void onTapDown(TapDownDetails details) {
if (!delegate.selectionEnabled) {
return;
}
renderEditable.handleTapDown(details);
// The selection overlay should only be shown when the user is interacting
// through a touch screen (via either a finger or a stylus). A mouse shouldn't
......@@ -1465,13 +1468,21 @@ class TextSelectionGestureDetectorBuilder {
|| kind == PointerDeviceKind.stylus;
// Handle shift + click selection if needed.
if (_isShiftPressed && renderEditable.selection?.baseOffset != null) {
_isShiftTapping = true;
final bool isShiftPressedValid = _isShiftPressed && renderEditable.selection?.baseOffset != null;
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.iOS:
// On mobile platforms the selection is set on tap up.
if (_isShiftTapping) {
_isShiftTapping = false;
}
break;
case TargetPlatform.macOS:
// On these platforms, a shift-tapped unfocused field expands from 0,
// not from the previous selection.
// On macOS, a shift-tapped unfocused field expands from 0, not from the
// previous selection.
if (isShiftPressedValid) {
_isShiftTapping = true;
final TextSelection? fromSelection = renderEditable.hasFocus
? null
: const TextSelection.collapsed(offset: 0);
......@@ -1480,14 +1491,23 @@ class TextSelectionGestureDetectorBuilder {
SelectionChangedCause.tap,
fromSelection,
);
return;
}
// On macOS, a tap/click places the selection in a precise position.
// This differs from iOS/iPadOS, where if the gesture is done by a touch
// then the selection moves to the closest word edge, instead of a
// precise position.
renderEditable.selectPosition(cause: SelectionChangedCause.tap);
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
if (isShiftPressedValid) {
_isShiftTapping = true;
_extendSelection(details.globalPosition, SelectionChangedCause.tap);
break;
return;
}
renderEditable.selectPosition(cause: SelectionChangedCause.tap);
break;
}
}
......@@ -1547,15 +1567,42 @@ class TextSelectionGestureDetectorBuilder {
/// this callback.
@protected
void onSingleTapUp(TapUpDetails details) {
if (delegate.selectionEnabled) {
// Handle shift + click selection if needed.
final bool isShiftPressedValid = _isShiftPressed && renderEditable.selection?.baseOffset != null;
switch (defaultTargetPlatform) {
case TargetPlatform.linux:
case TargetPlatform.macOS:
case TargetPlatform.windows:
// On desktop platforms the selection is set on tap down.
if (_isShiftTapping) {
_isShiftTapping = false;
}
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
if (isShiftPressedValid) {
_isShiftTapping = true;
_extendSelection(details.globalPosition, SelectionChangedCause.tap);
return;
}
if (delegate.selectionEnabled) {
switch (defaultTargetPlatform) {
renderEditable.selectPosition(cause: SelectionChangedCause.tap);
break;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
if (isShiftPressedValid) {
// On iOS, a shift-tapped unfocused field expands from 0, not from
// the previous selection.
_isShiftTapping = true;
final TextSelection? fromSelection = renderEditable.hasFocus
? null
: const TextSelection.collapsed(offset: 0);
_expandSelection(
details.globalPosition,
SelectionChangedCause.tap,
fromSelection,
);
return;
}
switch (details.kind) {
case PointerDeviceKind.mouse:
case PointerDeviceKind.trackpad:
......@@ -1566,18 +1613,11 @@ class TextSelectionGestureDetectorBuilder {
break;
case PointerDeviceKind.touch:
case PointerDeviceKind.unknown:
// On macOS/iOS/iPadOS a touch tap places the cursor at the edge
// of the word.
// On iOS/iPadOS a touch tap places the cursor at the edge of the word.
renderEditable.selectWordEdge(cause: SelectionChangedCause.tap);
break;
}
break;
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
renderEditable.selectPosition(cause: SelectionChangedCause.tap);
break;
}
}
}
......
......@@ -475,8 +475,6 @@ void main() {
final TestGesture down1 = await tester.startGesture(tester.getCenter(find.byType(TextField).first), kind: PointerDeviceKind.mouse);
await tester.pump();
await tester.pumpAndSettle();
await down1.up();
await down1.removePointer();
expect(focusNodeA.hasFocus, true);
......
......@@ -557,9 +557,9 @@ void main() {
switch (defaultTargetPlatform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
expect(renderEditable.selectWordEdgeCalled, isTrue);
break;
case TargetPlatform.macOS:
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
......
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