Unverified Commit c706abf0 authored by YeungKC's avatar YeungKC Committed by GitHub

Fix error cursor position for left and right arrow event after text selection (#68402)

parent 03db9bf9
...@@ -676,14 +676,24 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin { ...@@ -676,14 +676,24 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
} }
} else { } else {
if (rightArrow && newSelection.extentOffset < _plainText.length) { if (rightArrow && newSelection.extentOffset < _plainText.length) {
final int nextExtent = nextCharacter(newSelection.extentOffset, _plainText); int nextExtent;
if (!shift && !wordModifier && !lineModifier && newSelection.start != newSelection.end) {
nextExtent = newSelection.end;
} else {
nextExtent = nextCharacter(newSelection.extentOffset, _plainText);
}
final int distance = nextExtent - newSelection.extentOffset; final int distance = nextExtent - newSelection.extentOffset;
newSelection = newSelection.copyWith(extentOffset: nextExtent); newSelection = newSelection.copyWith(extentOffset: nextExtent);
if (shift) { if (shift) {
_cursorResetLocation += distance; _cursorResetLocation += distance;
} }
} else if (leftArrow && newSelection.extentOffset > 0) { } else if (leftArrow && newSelection.extentOffset > 0) {
final int previousExtent = previousCharacter(newSelection.extentOffset, _plainText); int previousExtent;
if (!shift && !wordModifier && !lineModifier && newSelection.start != newSelection.end) {
previousExtent = newSelection.start;
} else {
previousExtent = previousCharacter(newSelection.extentOffset, _plainText);
}
final int distance = newSelection.extentOffset - previousExtent; final int distance = newSelection.extentOffset - previousExtent;
newSelection = newSelection.copyWith(extentOffset: previousExtent); newSelection = newSelection.copyWith(extentOffset: previousExtent);
if (shift) { if (shift) {
......
...@@ -4331,7 +4331,7 @@ void main() { ...@@ -4331,7 +4331,7 @@ void main() {
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlRight); await tester.sendKeyUpEvent(LogicalKeyboardKey.controlRight);
await tester.pumpAndSettle(); await tester.pumpAndSettle();
const String expected = 'a big a bighouse\njumped over a mouse'; const String expected = 'a biga big house\njumped over a mouse';
expect(find.text(expected), findsOneWidget, reason: 'Because text contains ${controller.text}'); expect(find.text(expected), findsOneWidget, reason: 'Because text contains ${controller.text}');
}); });
......
...@@ -935,6 +935,68 @@ void main() { ...@@ -935,6 +935,68 @@ void main() {
expect(delegate.textEditingValue.text, ''); expect(delegate.textEditingValue.text, '');
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/61021 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/61021
test('arrow keys with selection text', () async {
final TextSelectionDelegate delegate = FakeEditableTextState();
final ViewportOffset viewportOffset = ViewportOffset.zero();
late TextSelection currentSelection;
final RenderEditable editable = RenderEditable(
backgroundCursorColor: Colors.grey,
selectionColor: Colors.black,
textDirection: TextDirection.ltr,
cursorColor: Colors.red,
offset: viewportOffset,
textSelectionDelegate: delegate,
onSelectionChanged: (TextSelection selection, RenderEditable renderObject, SelectionChangedCause cause) {
currentSelection = selection;
},
startHandleLayerLink: LayerLink(),
endHandleLayerLink: LayerLink(),
text: const TextSpan(
text: '012345', // Thumbs up
style: TextStyle(height: 1.0, fontSize: 10.0, fontFamily: 'Ahem'),
),
selection: const TextSelection.collapsed(
offset: 0,
),
);
layout(editable);
editable.hasFocus = true;
editable.selection = const TextSelection(baseOffset: 2, extentOffset: 4);
pumpFrame();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowRight);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 4);
editable.selection = const TextSelection(baseOffset: 4, extentOffset: 2);
pumpFrame();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowRight);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 4);
editable.selection = const TextSelection(baseOffset: 2, extentOffset: 4);
pumpFrame();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 2);
editable.selection = const TextSelection(baseOffset: 4, extentOffset: 2);
pumpFrame();
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 2);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/58068
test('getEndpointsForSelection handles empty characters', () { test('getEndpointsForSelection handles empty characters', () {
final TextSelectionDelegate delegate = FakeEditableTextState(); final TextSelectionDelegate delegate = FakeEditableTextState();
final RenderEditable editable = RenderEditable( final RenderEditable editable = RenderEditable(
......
...@@ -3989,7 +3989,6 @@ void main() { ...@@ -3989,7 +3989,6 @@ void main() {
reason: 'on $platform', reason: 'on $platform',
); );
// Move forward one character to reset the selection.
await sendKeys( await sendKeys(
tester, tester,
<LogicalKeyboardKey>[ <LogicalKeyboardKey>[
...@@ -4002,8 +4001,8 @@ void main() { ...@@ -4002,8 +4001,8 @@ void main() {
selection, selection,
equals( equals(
const TextSelection( const TextSelection(
baseOffset: 21, baseOffset: 20,
extentOffset: 21, extentOffset: 20,
affinity: TextAffinity.downstream, affinity: TextAffinity.downstream,
), ),
), ),
...@@ -4024,8 +4023,8 @@ void main() { ...@@ -4024,8 +4023,8 @@ void main() {
selection, selection,
equals( equals(
const TextSelection( const TextSelection(
baseOffset: 21, baseOffset: 20,
extentOffset: 40, extentOffset: 39,
affinity: TextAffinity.downstream, affinity: TextAffinity.downstream,
), ),
), ),
...@@ -4049,7 +4048,7 @@ void main() { ...@@ -4049,7 +4048,7 @@ void main() {
selection, selection,
equals( equals(
const TextSelection( const TextSelection(
baseOffset: 21, baseOffset: 20,
extentOffset: testText.length, extentOffset: testText.length,
affinity: TextAffinity.downstream, affinity: TextAffinity.downstream,
), ),
...@@ -4071,8 +4070,8 @@ void main() { ...@@ -4071,8 +4070,8 @@ void main() {
selection, selection,
equals( equals(
const TextSelection( const TextSelection(
baseOffset: 21, baseOffset: 20,
extentOffset: 58, extentOffset: 57,
affinity: TextAffinity.downstream, affinity: TextAffinity.downstream,
), ),
), ),
...@@ -4094,7 +4093,7 @@ void main() { ...@@ -4094,7 +4093,7 @@ void main() {
selection, selection,
equals( equals(
const TextSelection( const TextSelection(
baseOffset: 21, baseOffset: 20,
extentOffset: 72, extentOffset: 72,
affinity: TextAffinity.downstream, affinity: TextAffinity.downstream,
), ),
...@@ -4117,7 +4116,7 @@ void main() { ...@@ -4117,7 +4116,7 @@ void main() {
selection, selection,
equals( equals(
const TextSelection( const TextSelection(
baseOffset: 21, baseOffset: 20,
extentOffset: 55, extentOffset: 55,
affinity: TextAffinity.downstream, affinity: TextAffinity.downstream,
), ),
......
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