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)
|
if (onTapUp != null)
|
||||||
invokeCallback<void>('onTapUp', () {
|
invokeCallback<void>('onTapUp', () {
|
||||||
onTapUp!(pointer, TapUpDetails(
|
onTapUp!(pointer, TapUpDetails(
|
||||||
|
kind: getKindForPointer(pointer),
|
||||||
localPosition: position.local,
|
localPosition: position.local,
|
||||||
globalPosition: position.global,
|
globalPosition: position.global,
|
||||||
));
|
));
|
||||||
|
@ -59,6 +59,7 @@ typedef GestureTapDownCallback = void Function(TapDownDetails details);
|
|||||||
class TapUpDetails {
|
class TapUpDetails {
|
||||||
/// The [globalPosition] argument must not be null.
|
/// The [globalPosition] argument must not be null.
|
||||||
TapUpDetails({
|
TapUpDetails({
|
||||||
|
required this.kind,
|
||||||
this.globalPosition = Offset.zero,
|
this.globalPosition = Offset.zero,
|
||||||
Offset? localPosition,
|
Offset? localPosition,
|
||||||
}) : assert(globalPosition != null),
|
}) : assert(globalPosition != null),
|
||||||
@ -69,6 +70,9 @@ class TapUpDetails {
|
|||||||
|
|
||||||
/// The local position at which the pointer contacted the screen.
|
/// The local position at which the pointer contacted the screen.
|
||||||
final Offset localPosition;
|
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
|
/// Signature for when a pointer that will trigger a tap has stopped contacting
|
||||||
@ -512,6 +516,7 @@ class TapGestureRecognizer extends BaseTapGestureRecognizer {
|
|||||||
@override
|
@override
|
||||||
void handleTapUp({ required PointerDownEvent down, required PointerUpEvent up}) {
|
void handleTapUp({ required PointerDownEvent down, required PointerUpEvent up}) {
|
||||||
final TapUpDetails details = TapUpDetails(
|
final TapUpDetails details = TapUpDetails(
|
||||||
|
kind: up.kind,
|
||||||
globalPosition: up.position,
|
globalPosition: up.position,
|
||||||
localPosition: up.localPosition,
|
localPosition: up.localPosition,
|
||||||
);
|
);
|
||||||
|
@ -93,7 +93,20 @@ class _TextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDete
|
|||||||
switch (Theme.of(_state.context).platform) {
|
switch (Theme.of(_state.context).platform) {
|
||||||
case TargetPlatform.iOS:
|
case TargetPlatform.iOS:
|
||||||
case TargetPlatform.macOS:
|
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;
|
break;
|
||||||
case TargetPlatform.android:
|
case TargetPlatform.android:
|
||||||
case TargetPlatform.fuchsia:
|
case TargetPlatform.fuchsia:
|
||||||
|
@ -1260,7 +1260,7 @@ class _DefaultSemanticsGestureDelegate extends SemanticsGestureDelegate {
|
|||||||
if (tap.onTapDown != null)
|
if (tap.onTapDown != null)
|
||||||
tap.onTapDown(TapDownDetails());
|
tap.onTapDown(TapDownDetails());
|
||||||
if (tap.onTapUp != null)
|
if (tap.onTapUp != null)
|
||||||
tap.onTapUp(TapUpDetails());
|
tap.onTapUp(TapUpDetails(kind: PointerDeviceKind.unknown));
|
||||||
if (tap.onTap != null)
|
if (tap.onTap != null)
|
||||||
tap.onTap();
|
tap.onTap();
|
||||||
};
|
};
|
||||||
|
@ -109,6 +109,35 @@ void main() {
|
|||||||
tap.dispose();
|
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) {
|
testGesture('No duplicate tap events', (GestureTester tester) {
|
||||||
final TapGestureRecognizer tap = TapGestureRecognizer();
|
final TapGestureRecognizer tap = TapGestureRecognizer();
|
||||||
|
|
||||||
|
@ -6110,6 +6110,41 @@ void main() {
|
|||||||
expect(find.byType(CupertinoButton), findsNothing);
|
expect(find.byType(CupertinoButton), findsNothing);
|
||||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
}, 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 {
|
testWidgets('tap moves cursor to the position tapped', (WidgetTester tester) async {
|
||||||
final TextEditingController controller = TextEditingController(
|
final TextEditingController controller = TextEditingController(
|
||||||
text: 'Atwater Peel Sherbrooke Bonaventure',
|
text: 'Atwater Peel Sherbrooke Bonaventure',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user