Unverified Commit 715fcaac authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Can't drag the cursor with the mouse (#103002)

parent 8afaf7b5
...@@ -1208,12 +1208,28 @@ class _SelectionHandleOverlayState extends State<_SelectionHandleOverlay> with S ...@@ -1208,12 +1208,28 @@ class _SelectionHandleOverlayState extends State<_SelectionHandleOverlay> with S
alignment: Alignment.topLeft, alignment: Alignment.topLeft,
width: interactiveRect.width, width: interactiveRect.width,
height: interactiveRect.height, height: interactiveRect.height,
child: GestureDetector( child: RawGestureDetector(
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
dragStartBehavior: widget.dragStartBehavior, gestures: <Type, GestureRecognizerFactory>{
onPanStart: widget.onSelectionHandleDragStart, PanGestureRecognizer: GestureRecognizerFactoryWithHandlers<PanGestureRecognizer>(
onPanUpdate: widget.onSelectionHandleDragUpdate, () => PanGestureRecognizer(
onPanEnd: widget.onSelectionHandleDragEnd, debugOwner: this,
// Mouse events select the text and do not drag the cursor.
supportedDevices: <PointerDeviceKind>{
PointerDeviceKind.touch,
PointerDeviceKind.stylus,
PointerDeviceKind.unknown,
},
),
(PanGestureRecognizer instance) {
instance
..dragStartBehavior = widget.dragStartBehavior
..onStart = widget.onSelectionHandleDragStart
..onUpdate = widget.onSelectionHandleDragUpdate
..onEnd = widget.onSelectionHandleDragEnd;
},
),
},
child: Padding( child: Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(
left: padding.left, left: padding.left,
......
...@@ -10,6 +10,7 @@ import 'package:flutter/services.dart'; ...@@ -10,6 +10,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'clipboard_utils.dart'; import 'clipboard_utils.dart';
import 'editable_text_utils.dart';
void main() { void main() {
late int tapCount; late int tapCount;
...@@ -628,7 +629,7 @@ void main() { ...@@ -628,7 +629,7 @@ void main() {
}); });
testWidgets('Mouse drag does not show handles nor toolbar', (WidgetTester tester) async { testWidgets('Mouse drag does not show handles nor toolbar', (WidgetTester tester) async {
// Regressing test for https://github.com/flutter/flutter/issues/69001 // Regression test for https://github.com/flutter/flutter/issues/69001
await tester.pumpWidget( await tester.pumpWidget(
const MaterialApp( const MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -652,6 +653,231 @@ void main() { ...@@ -652,6 +653,231 @@ void main() {
expect(editableText.selectionOverlay!.toolbarIsVisible, isFalse); expect(editableText.selectionOverlay!.toolbarIsVisible, isFalse);
}); });
testWidgets('Mouse drag selects and cannot drag cursor', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/102928
final TextEditingController controller = TextEditingController(
text: 'I love flutter!',
);
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
final FakeTextSelectionGestureDetectorBuilderDelegate delegate = FakeTextSelectionGestureDetectorBuilderDelegate(
editableTextKey: editableTextKey,
forcePressEnabled: false,
selectionEnabled: true,
);
final TextSelectionGestureDetectorBuilder provider =
TextSelectionGestureDetectorBuilder(delegate: delegate);
await tester.pumpWidget(
MaterialApp(
home: provider.buildGestureDetector(
behavior: HitTestBehavior.translucent,
child: EditableText(
key: editableTextKey,
controller: controller,
focusNode: FocusNode(),
backgroundCursorColor: Colors.white,
cursorColor: Colors.white,
style: const TextStyle(),
selectionControls: materialTextSelectionControls,
),
),
),
);
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, -1);
final Offset position = textOffsetToPosition(tester, 4);
await tester.tapAt(position);
await tester.pump();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 4);
final TestGesture gesture = await tester.startGesture(position, kind: PointerDeviceKind.mouse);
addTearDown(gesture.removePointer);
await tester.pump();
await gesture.moveTo(textOffsetToPosition(tester, 7));
await tester.pump();
await gesture.moveTo(textOffsetToPosition(tester, 10));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(controller.selection.isCollapsed, isFalse);
expect(controller.selection.baseOffset, 4);
expect(controller.selection.extentOffset, 10);
});
testWidgets('Touch drag moves the cursor', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/102928
final TextEditingController controller = TextEditingController(
text: 'I love flutter!',
);
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
final FakeTextSelectionGestureDetectorBuilderDelegate delegate = FakeTextSelectionGestureDetectorBuilderDelegate(
editableTextKey: editableTextKey,
forcePressEnabled: false,
selectionEnabled: true,
);
final TextSelectionGestureDetectorBuilder provider =
TextSelectionGestureDetectorBuilder(delegate: delegate);
await tester.pumpWidget(
MaterialApp(
home: provider.buildGestureDetector(
behavior: HitTestBehavior.translucent,
child: EditableText(
key: editableTextKey,
controller: controller,
focusNode: FocusNode(),
backgroundCursorColor: Colors.white,
cursorColor: Colors.white,
style: const TextStyle(),
selectionControls: materialTextSelectionControls,
),
),
),
);
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, -1);
final Offset position = textOffsetToPosition(tester, 4);
await tester.tapAt(position);
await tester.pump();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 4);
final TestGesture gesture = await tester.startGesture(position);
addTearDown(gesture.removePointer);
await tester.pump();
await gesture.moveTo(textOffsetToPosition(tester, 7));
await tester.pump();
await gesture.moveTo(textOffsetToPosition(tester, 10));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 10);
});
testWidgets('Stylus drag moves the cursor', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/102928
final TextEditingController controller = TextEditingController(
text: 'I love flutter!',
);
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
final FakeTextSelectionGestureDetectorBuilderDelegate delegate = FakeTextSelectionGestureDetectorBuilderDelegate(
editableTextKey: editableTextKey,
forcePressEnabled: false,
selectionEnabled: true,
);
final TextSelectionGestureDetectorBuilder provider =
TextSelectionGestureDetectorBuilder(delegate: delegate);
await tester.pumpWidget(
MaterialApp(
home: provider.buildGestureDetector(
behavior: HitTestBehavior.translucent,
child: EditableText(
key: editableTextKey,
controller: controller,
focusNode: FocusNode(),
backgroundCursorColor: Colors.white,
cursorColor: Colors.white,
style: const TextStyle(),
selectionControls: materialTextSelectionControls,
),
),
),
);
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, -1);
final Offset position = textOffsetToPosition(tester, 4);
await tester.tapAt(position);
await tester.pump();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 4);
final TestGesture gesture = await tester.startGesture(position, kind: PointerDeviceKind.stylus);
addTearDown(gesture.removePointer);
await tester.pump();
await gesture.moveTo(textOffsetToPosition(tester, 7));
await tester.pump();
await gesture.moveTo(textOffsetToPosition(tester, 10));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 10);
});
testWidgets('Drag of unknown type moves the cursor', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/102928
final TextEditingController controller = TextEditingController(
text: 'I love flutter!',
);
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
final FakeTextSelectionGestureDetectorBuilderDelegate delegate = FakeTextSelectionGestureDetectorBuilderDelegate(
editableTextKey: editableTextKey,
forcePressEnabled: false,
selectionEnabled: true,
);
final TextSelectionGestureDetectorBuilder provider =
TextSelectionGestureDetectorBuilder(delegate: delegate);
await tester.pumpWidget(
MaterialApp(
home: provider.buildGestureDetector(
behavior: HitTestBehavior.translucent,
child: EditableText(
key: editableTextKey,
controller: controller,
focusNode: FocusNode(),
backgroundCursorColor: Colors.white,
cursorColor: Colors.white,
style: const TextStyle(),
selectionControls: materialTextSelectionControls,
),
),
),
);
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, -1);
final Offset position = textOffsetToPosition(tester, 4);
await tester.tapAt(position);
await tester.pump();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 4);
final TestGesture gesture = await tester.startGesture(position, kind: PointerDeviceKind.unknown);
addTearDown(gesture.removePointer);
await tester.pump();
await gesture.moveTo(textOffsetToPosition(tester, 7));
await tester.pump();
await gesture.moveTo(textOffsetToPosition(tester, 10));
await tester.pump();
await gesture.up();
await tester.pumpAndSettle();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 10);
});
testWidgets('test TextSelectionGestureDetectorBuilder drag with RenderEditable viewport offset change', (WidgetTester tester) async { testWidgets('test TextSelectionGestureDetectorBuilder drag with RenderEditable viewport offset change', (WidgetTester tester) async {
await pumpTextSelectionGestureDetectorBuilder(tester); await pumpTextSelectionGestureDetectorBuilder(tester);
final FakeRenderEditable renderEditable = tester.renderObject(find.byType(FakeEditable)); final FakeRenderEditable renderEditable = tester.renderObject(find.byType(FakeEditable));
...@@ -767,7 +993,7 @@ void main() { ...@@ -767,7 +993,7 @@ void main() {
of: find.byType(CompositedTransformFollower), of: find.byType(CompositedTransformFollower),
matching: find.descendant( matching: find.descendant(
of: find.byType(FadeTransition), of: find.byType(FadeTransition),
matching: find.byType(GestureDetector), matching: find.byType(RawGestureDetector),
), ),
); );
......
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