Don't move to word edge when tapping with a mouse (#60177)
This commit is contained in:
parent
6338181428
commit
d13b56a0cd
@ -478,6 +478,7 @@ class MultiTapGestureRecognizer extends GestureRecognizer {
|
||||
if (onTapUp != null)
|
||||
invokeCallback<void>('onTapUp', () {
|
||||
onTapUp!(pointer, TapUpDetails(
|
||||
kind: getKindForPointer(pointer),
|
||||
localPosition: position.local,
|
||||
globalPosition: position.global,
|
||||
));
|
||||
|
@ -59,6 +59,7 @@ typedef GestureTapDownCallback = void Function(TapDownDetails details);
|
||||
class TapUpDetails {
|
||||
/// The [globalPosition] argument must not be null.
|
||||
TapUpDetails({
|
||||
required this.kind,
|
||||
this.globalPosition = Offset.zero,
|
||||
Offset? localPosition,
|
||||
}) : assert(globalPosition != null),
|
||||
@ -69,6 +70,9 @@ class TapUpDetails {
|
||||
|
||||
/// The local position at which the pointer contacted the screen.
|
||||
final Offset localPosition;
|
||||
|
||||
/// The kind of the device that initiated the event.
|
||||
final PointerDeviceKind kind;
|
||||
}
|
||||
|
||||
/// Signature for when a pointer that will trigger a tap has stopped contacting
|
||||
@ -512,6 +516,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
||||
@override
|
||||
void handleTapUp({ required PointerDownEvent down, required PointerUpEvent up}) {
|
||||
final TapUpDetails details = TapUpDetails(
|
||||
kind: up.kind,
|
||||
globalPosition: up.position,
|
||||
localPosition: up.localPosition,
|
||||
);
|
||||
|
@ -93,7 +93,20 @@ class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDete
|
||||
switch (Theme.of(_state.context).platform) {
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
renderEditable.selectWordEdge(cause: SelectionChangedCause.tap);
|
||||
switch (details.kind) {
|
||||
case PointerDeviceKind.mouse:
|
||||
case PointerDeviceKind.stylus:
|
||||
case PointerDeviceKind.invertedStylus:
|
||||
// Precise devices should place the cursor at a precise position.
|
||||
renderEditable.selectPosition(cause: SelectionChangedCause.tap);
|
||||
break;
|
||||
case PointerDeviceKind.touch:
|
||||
case PointerDeviceKind.unknown:
|
||||
// On macOS/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:
|
||||
|
@ -1260,7 +1260,7 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate {
|
||||
if (tap.onTapDown != null)
|
||||
tap.onTapDown(TapDownDetails());
|
||||
if (tap.onTapUp != null)
|
||||
tap.onTapUp(TapUpDetails());
|
||||
tap.onTapUp(TapUpDetails(kind: PointerDeviceKind.unknown));
|
||||
if (tap.onTap != null)
|
||||
tap.onTap();
|
||||
};
|
||||
|
@ -109,6 +109,35 @@ void main() {
|
||||
tap.dispose();
|
||||
});
|
||||
|
||||
testGesture('Details contain the correct device kind', (GestureTester tester) {
|
||||
final TapGestureRecognizer tap = TapGestureRecognizer();
|
||||
|
||||
TapDownDetails lastDownDetails;
|
||||
TapUpDetails lastUpDetails;
|
||||
|
||||
tap.onTapDown = (TapDownDetails details) {
|
||||
lastDownDetails = details;
|
||||
};
|
||||
tap.onTapUp = (TapUpDetails details) {
|
||||
lastUpDetails = details;
|
||||
};
|
||||
|
||||
const PointerDownEvent mouseDown =
|
||||
PointerDownEvent(pointer: 1, kind: PointerDeviceKind.mouse);
|
||||
const PointerUpEvent mouseUp =
|
||||
PointerUpEvent(pointer: 1, kind: PointerDeviceKind.mouse);
|
||||
|
||||
tap.addPointer(mouseDown);
|
||||
tester.closeArena(1);
|
||||
tester.route(mouseDown);
|
||||
expect(lastDownDetails.kind, PointerDeviceKind.mouse);
|
||||
|
||||
tester.route(mouseUp);
|
||||
expect(lastUpDetails.kind, PointerDeviceKind.mouse);
|
||||
|
||||
tap.dispose();
|
||||
});
|
||||
|
||||
testGesture('No duplicate tap events', (GestureTester tester) {
|
||||
final TapGestureRecognizer tap = TapGestureRecognizer();
|
||||
|
||||
|
@ -6110,6 +6110,41 @@ void main() {
|
||||
expect(find.byType(CupertinoButton), findsNothing);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets(
|
||||
'tap with a mouse does not move cursor to the edge of the word',
|
||||
(WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: TextField(
|
||||
controller: controller,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final Offset textfieldStart = tester.getTopLeft(find.byType(TextField));
|
||||
|
||||
final TestGesture gesture = await tester.startGesture(
|
||||
textfieldStart + const Offset(50.0, 9.0),
|
||||
pointer: 1,
|
||||
kind: PointerDeviceKind.mouse,
|
||||
);
|
||||
addTearDown(gesture.removePointer);
|
||||
await gesture.up();
|
||||
|
||||
// Cursor at tap position, not at word edge.
|
||||
expect(
|
||||
controller.selection,
|
||||
const TextSelection.collapsed(offset: 3, affinity: TextAffinity.downstream),
|
||||
);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('tap moves cursor to the position tapped', (WidgetTester tester) async {
|
||||
final TextEditingController controller = TextEditingController(
|
||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||
|
Loading…
x
Reference in New Issue
Block a user