Fix text cursor or input can be outside of the text field (#91698)
This commit is contained in:
@@ -780,7 +780,7 @@ class TextPainter {
|
||||
|
||||
final double caretEnd = box.end;
|
||||
final double dx = box.direction == TextDirection.rtl ? caretEnd - caretPrototype.width : caretEnd;
|
||||
return Rect.fromLTRB(min(dx, _paragraph!.width), box.top, min(dx, _paragraph!.width), box.bottom);
|
||||
return Rect.fromLTRB(dx.clamp(0, _paragraph!.width), box.top, dx.clamp(0, _paragraph!.width), box.bottom);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -822,7 +822,7 @@ class TextPainter {
|
||||
final TextBox box = boxes.last;
|
||||
final double caretStart = box.start;
|
||||
final double dx = box.direction == TextDirection.rtl ? caretStart - caretPrototype.width : caretStart;
|
||||
return Rect.fromLTRB(min(dx, _paragraph!.width), box.top, min(dx, _paragraph!.width), box.bottom);
|
||||
return Rect.fromLTRB(dx.clamp(0, _paragraph!.width), box.top, dx.clamp(0, _paragraph!.width), box.bottom);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1664,8 +1664,8 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin,
|
||||
final Offset start = Offset(0.0, preferredLineHeight) + caretOffset + paintOffset;
|
||||
return <TextSelectionPoint>[TextSelectionPoint(start, null)];
|
||||
} else {
|
||||
final Offset start = Offset(boxes.first.start, boxes.first.bottom) + paintOffset;
|
||||
final Offset end = Offset(boxes.last.end, boxes.last.bottom) + paintOffset;
|
||||
final Offset start = Offset(boxes.first.start.clamp(0, _textPainter.size.width), boxes.first.bottom) + paintOffset;
|
||||
final Offset end = Offset(boxes.last.end.clamp(0, _textPainter.size.width), boxes.last.bottom) + paintOffset;
|
||||
return <TextSelectionPoint>[
|
||||
TextSelectionPoint(start, boxes.first.direction),
|
||||
TextSelectionPoint(end, boxes.last.direction),
|
||||
@@ -2741,14 +2741,19 @@ class _TextHighlightPainter extends RenderEditablePainter {
|
||||
}
|
||||
|
||||
highlightPaint.color = color;
|
||||
final List<TextBox> boxes = renderEditable._textPainter.getBoxesForSelection(
|
||||
final TextPainter textPainter = renderEditable._textPainter;
|
||||
final List<TextBox> boxes = textPainter.getBoxesForSelection(
|
||||
TextSelection(baseOffset: range.start, extentOffset: range.end),
|
||||
boxHeightStyle: selectionHeightStyle,
|
||||
boxWidthStyle: selectionWidthStyle,
|
||||
);
|
||||
|
||||
for (final TextBox box in boxes)
|
||||
canvas.drawRect(box.toRect().shift(renderEditable._paintOffset), highlightPaint);
|
||||
canvas.drawRect(
|
||||
box.toRect().shift(renderEditable._paintOffset)
|
||||
.intersect(Rect.fromLTWH(0, 0, textPainter.width, textPainter.height)),
|
||||
highlightPaint,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1097,6 +1097,33 @@ void main() {
|
||||
expect(cursorOffsetSpaces.dx, inputWidth - kCaretGap);
|
||||
});
|
||||
|
||||
testWidgets('Overflowing a line with spaces stops the cursor at the end (rtl direction)', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
overlay(
|
||||
child: const TextField(
|
||||
textDirection: TextDirection.rtl,
|
||||
maxLines: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
const String testValueOneLine = 'enough text to be exactly at the end of the line.';
|
||||
const String testValueSpaces = '$testValueOneLine ';
|
||||
|
||||
// Positioning the cursor at the end of a line overflowing with spaces puts
|
||||
// it inside the input still.
|
||||
await tester.enterText(find.byType(TextField), testValueSpaces);
|
||||
await skipPastScrollingAnimation(tester);
|
||||
await tester.tapAt(textOffsetToPosition(tester, testValueSpaces.length));
|
||||
await tester.pump();
|
||||
|
||||
final Offset cursorOffsetSpaces = findRenderEditable(tester).getLocalRectForCaret(
|
||||
const TextPosition(offset: testValueSpaces.length),
|
||||
).topLeft;
|
||||
|
||||
expect(cursorOffsetSpaces.dx >= 0, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('mobile obscureText control test', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
overlay(
|
||||
|
||||
Reference in New Issue
Block a user