Unverified Commit 566ac3ce authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Trackpad mode crash fix (#30475)

Fixes a crash that happened when attempting to select text in trackpad mode on iOS.
parent 4a2832b0
...@@ -914,6 +914,10 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien ...@@ -914,6 +914,10 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
void updateFloatingCursor(RawFloatingCursorPoint point) { void updateFloatingCursor(RawFloatingCursorPoint point) {
switch(point.state){ switch(point.state){
case FloatingCursorDragState.Start: case FloatingCursorDragState.Start:
if (_floatingCursorResetController.isAnimating) {
_floatingCursorResetController.stop();
_onFloatingCursorResetTick();
}
final TextPosition currentTextPosition = TextPosition(offset: renderEditable.selection.baseOffset); final TextPosition currentTextPosition = TextPosition(offset: renderEditable.selection.baseOffset);
_startCaretRect = renderEditable.getLocalRectForCaret(currentTextPosition); _startCaretRect = renderEditable.getLocalRectForCaret(currentTextPosition);
renderEditable.setFloatingCursor(point.state, _startCaretRect.center - _floatingCursorOffset, currentTextPosition); renderEditable.setFloatingCursor(point.state, _startCaretRect.center - _floatingCursorOffset, currentTextPosition);
......
...@@ -476,6 +476,72 @@ void main() { ...@@ -476,6 +476,72 @@ void main() {
expect(controller.selection.baseOffset, 10); expect(controller.selection.baseOffset, 10);
}); });
// Regression test for https://github.com/flutter/flutter/pull/30475.
testWidgets('Trying to select with the floating cursor does not crash', (WidgetTester tester) async {
const String text = 'hello world this is fun and cool and awesome!';
controller.text = text;
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(devicePixelRatio: 1),
child: Directionality(
textDirection: TextDirection.ltr,
child: FocusScope(
node: focusScopeNode,
autofocus: true,
child: EditableText(
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
),
),
),
),
);
await tester.tap(find.byType(EditableText));
final RenderEditable renderEditable = findRenderEditable(tester);
renderEditable.selection = const TextSelection(baseOffset: 29, extentOffset: 29);
expect(controller.selection.baseOffset, 29);
final EditableTextState editableTextState = tester.firstState(find.byType(EditableText));
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start));
expect(controller.selection.baseOffset, 29);
// Sets the origin.
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update,
offset: const Offset(20, 20)));
expect(controller.selection.baseOffset, 29);
// Moves the cursor right a few characters.
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update,
offset: const Offset(-250, 20)));
// But we have not yet set the offset because the user is not done placing the cursor.
expect(controller.selection.baseOffset, 29);
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.End));
// Immediately start a new floating cursor, in the same way as happens when
// the user tries to select text in trackpad mode.
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Start));
await tester.pumpAndSettle();
// Set and move the second cursor like a selection. Previously, the second
// Update here caused a crash.
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update,
offset: const Offset(20, 20)));
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.Update,
offset: const Offset(-250, 20)));
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.End));
await tester.pumpAndSettle();
});
testWidgets('autofocus sets cursor to the end of text', (WidgetTester tester) async { testWidgets('autofocus sets cursor to the end of text', (WidgetTester tester) async {
const String text = 'hello world'; const String text = 'hello world';
final FocusScopeNode focusScopeNode = FocusScopeNode(); final FocusScopeNode focusScopeNode = FocusScopeNode();
......
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