Unverified Commit fb3dba74 authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Correct text selection pivot points (#71756)

parent a42aa048
......@@ -678,6 +678,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
newSelection = newSelection.copyWith(extentOffset: textSelection.extentOffset);
}
} else {
// The directional arrows move the TextSelection.extentOffset, while the
// base remains fixed.
if (rightArrow && newSelection.extentOffset < _plainText.length) {
int nextExtent;
if (!shift && !wordModifier && !lineModifier && newSelection.start != newSelection.end) {
......@@ -1849,6 +1851,9 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
}
/// Select text between the global positions [from] and [to].
///
/// [from] corresponds to the [TextSelection.baseOffset], and [to] corresponds
/// to the [TextSelection.extentOffset].
void selectPositionAt({ required Offset from, Offset? to, required SelectionChangedCause cause }) {
assert(cause != null);
assert(from != null);
......@@ -1861,12 +1866,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
? null
: _textPainter.getPositionForOffset(globalToLocal(to - _paintOffset));
int baseOffset = fromPosition.offset;
int extentOffset = fromPosition.offset;
if (toPosition != null) {
baseOffset = math.min(fromPosition.offset, toPosition.offset);
extentOffset = math.max(fromPosition.offset, toPosition.offset);
}
final int baseOffset = fromPosition.offset;
final int extentOffset = toPosition?.offset ?? fromPosition.offset;
final TextSelection newSelection = TextSelection(
baseOffset: baseOffset,
......
......@@ -1458,8 +1458,8 @@ void main() {
await gesture.up();
await tester.pumpAndSettle();
expect(controller.selection.baseOffset, testValue.indexOf('e'));
expect(controller.selection.extentOffset, testValue.indexOf('g'));
expect(controller.selection.baseOffset, testValue.indexOf('g'));
expect(controller.selection.extentOffset, testValue.indexOf('e'));
});
testWidgets('Slow mouse dragging also selects text', (WidgetTester tester) async {
......
......@@ -570,8 +570,8 @@ void main() {
pumpFrame();
expect(currentSelection.isCollapsed, isFalse);
expect(currentSelection.baseOffset, 1);
expect(currentSelection.extentOffset, 3);
expect(currentSelection.baseOffset, 3);
expect(currentSelection.extentOffset, 1);
});
test('selection does not flicker as user is dragging', () {
......@@ -1006,7 +1006,79 @@ void main() {
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 2);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/58068
test('arrow keys with selection text and shift', () 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.shift);
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowRight);
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
expect(currentSelection.isCollapsed, false);
expect(currentSelection.baseOffset, 2);
expect(currentSelection.extentOffset, 5);
editable.selection = const TextSelection(baseOffset: 4, extentOffset: 2);
pumpFrame();
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowRight);
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
expect(currentSelection.isCollapsed, false);
expect(currentSelection.baseOffset, 4);
expect(currentSelection.extentOffset, 3);
editable.selection = const TextSelection(baseOffset: 2, extentOffset: 4);
pumpFrame();
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
expect(currentSelection.isCollapsed, false);
expect(currentSelection.baseOffset, 2);
expect(currentSelection.extentOffset, 3);
editable.selection = const TextSelection(baseOffset: 4, extentOffset: 2);
pumpFrame();
await simulateKeyDownEvent(LogicalKeyboardKey.shift);
await simulateKeyDownEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.arrowLeft);
await simulateKeyUpEvent(LogicalKeyboardKey.shift);
expect(currentSelection.isCollapsed, false);
expect(currentSelection.baseOffset, 4);
expect(currentSelection.extentOffset, 1);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/58068
group('delete', () {
......
......@@ -765,8 +765,8 @@ void main() {
await gesture.up();
await tester.pumpAndSettle();
expect(controller.selection.baseOffset, 5);
expect(controller.selection.extentOffset, 8);
expect(controller.selection.baseOffset, 8);
expect(controller.selection.extentOffset, 5);
});
testWidgets('Slow mouse dragging also selects text', (WidgetTester tester) async {
......
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