opt paint text selection rect

add patch desc

Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-07-29 19:39:23 +08:00
parent 557585334a
commit 133f45945c
7 changed files with 155 additions and 32 deletions

View File

@@ -1,7 +1,70 @@
diff --git a/packages/flutter/lib/src/rendering/editable.dart b/packages/flutter/lib/src/rendering/editable.dart
index 5d0121e3f37..a42c758b2fb 100644
--- a/packages/flutter/lib/src/rendering/editable.dart
+++ b/packages/flutter/lib/src/rendering/editable.dart
@@ -321,7 +321,7 @@ class RenderEditable extends RenderBox
Offset cursorOffset = Offset.zero,
double devicePixelRatio = 1.0,
ui.BoxHeightStyle selectionHeightStyle = ui.BoxHeightStyle.max,
- ui.BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.max,
+ ui.BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.tight,
bool? enableInteractiveSelection,
this.floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5),
TextRange? promptRectRange,
@@ -2912,17 +2912,31 @@ class _TextHighlightPainter extends RenderEditablePainter {
highlightPaint.color = color;
final TextPainter textPainter = renderEditable._textPainter;
- final Set<TextBox> boxes = textPainter
- .getBoxesForSelection(
- TextSelection(baseOffset: range.start, extentOffset: range.end),
- boxHeightStyle: selectionHeightStyle,
- boxWidthStyle: selectionWidthStyle,
- )
- .toSet();
- for (final box in boxes) {
+ final List<ui.TextBox> boxes = textPainter.getBoxesForSelection(
+ TextSelection(baseOffset: range.start, extentOffset: range.end),
+ boxHeightStyle: ui.BoxHeightStyle.max,
+ boxWidthStyle: ui.BoxWidthStyle.tight,
+ );
+ ui.TextBox? mergedBox;
+ for (final textBox in boxes) {
+ if (mergedBox == null) {
+ mergedBox = textBox;
+ } else if (mergedBox.top != textBox.top) {
+ canvas.drawRect(
+ Rect.fromLTRB(mergedBox.left, mergedBox.top, size.width, mergedBox.bottom)
+ .shift(renderEditable._paintOffset)
+ .intersect(Rect.fromLTRB(0, 0, textPainter.width, textPainter.height)),
+ highlightPaint,
+ );
+ mergedBox = textBox;
+ } else {
+ mergedBox = TextBox.fromLTRBD(mergedBox.left, mergedBox.top, textBox.right, mergedBox.bottom, mergedBox.direction);
+ }
+ }
+ if (mergedBox != null) {
canvas.drawRect(
- box
+ mergedBox
.toRect()
.shift(renderEditable._paintOffset)
.intersect(Rect.fromLTWH(0, 0, textPainter.width, textPainter.height)),
diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart
index b1ae878f2cc..8a7540350ef 100644
index b1ae878f2cc..7b179c7e3b3 100644
--- a/packages/flutter/lib/src/widgets/editable_text.dart
+++ b/packages/flutter/lib/src/widgets/editable_text.dart
@@ -2099,7 +2099,7 @@ class EditableText extends StatefulWidget {
}
return ui.BoxWidthStyle.tight;
}
- return ui.BoxWidthStyle.max;
+ return ui.BoxWidthStyle.tight;
}
/// The default value for [stylusHandwritingEnabled].
@@ -5046,7 +5046,9 @@ class EditableTextState extends State<EditableText>
void userUpdateTextEditingValue(TextEditingValue value, SelectionChangedCause? cause) {
// Compare the current TextEditingValue with the pre-format new

View File

@@ -6,6 +6,7 @@ param(
# https://github.com/flutter/flutter/issues/182281
$NewOverScrollIndicator = "362b1de29974ffc1ed6faa826e1df870d7bec75f";
# set `gestureSettings`
$BottomSheetAndroidPatch = "lib/scripts/bottom_sheet_android.patch"
# https://github.com/bggRGjQaUbCoE/PiliPlus/issues/1906
@@ -17,9 +18,11 @@ $BottomSheetIOSPiliPlusPatch = "lib/scripts/bottom_sheet_ios_piliplus.patch"
$TextSelectionMenuFix = "beb2ad17004a1b118ff2bd09f55cee23198f6652";
# https://github.com/bggRGjQaUbCoE/PiliPlus/issues/1662
# handle bottom scroll event
$ScrollViewPatch = "lib/scripts/scroll_view.patch"
# https://github.com/bggRGjQaUbCoE/PiliPlus/issues/2106
# use `TouchGestureRecognizer` on all platforms
$TextSelectionPatch = "lib/scripts/text_selection.patch"
# https://github.com/bggRGjQaUbCoE/PiliPlus/issues/1947
@@ -28,28 +31,46 @@ $NavigatorPatch = "lib/scripts/navigator.patch"
# https://github.com/bggRGjQaUbCoE/PiliPlus/issues/2107
$ImageAnimPatch = "lib/scripts/image_anim.patch"
# remove `_scheduleRebuild`
$LayoutBuilderPatch = "lib/scripts/layout_builder.patch"
# https://github.com/bggRGjQaUbCoE/PiliPlus/issues/2308
$NavigationDrawerPatch = "lib/scripts/navigation_drawer.patch"
# apply text color to icon color
$PopupMenuPatch = "lib/scripts/popup_menu.patch"
# remove `Hero` effect
$FABPatch = "lib/scripts/fab.patch"
$SelectableRegionSelectionPatch = "lib/scripts/selectable_region.patch"
# https://github.com/flutter/flutter/issues/139890
# https://github.com/flutter/flutter/issues/174689
# separator support
# clamp handle offset
# widgetspan selection support
# clear selection when tapping outside
# free selection if there is only one text
# clamp dragging selection behavior on Android
# show selection menu if secondary tap position is in text region on desktop
$SelectableRegionPatch = "lib/scripts/selectable_region.patch"
# https://github.com/flutter/flutter/issues/132047
# https://github.com/flutter/flutter/issues/174689
$EditableTextPatch = "lib/scripts/editable_text.patch"
# set `selectAllOnFocus` to `false` by default
$TextFieldPatch = "lib/scripts/text_field.patch"
# notify `userScrollDirection` only if position is actually changing
$ScrollPositionPatch = "lib/scripts/scroll_position.patch"
# expose `_shouldIgnorePointer`
$ScrollablePatch = "lib/scripts/scrollable.patch"
# TODO: remove
# https://github.com/flutter/flutter/issues/124078
# https://github.com/flutter/flutter/pull/183261
$SelectableRegionPatch = "lib/scripts/null_safety_for_selectable_region.patch"
$NullSafetySelectableRegionPatch = "lib/scripts/null_safety_for_selectable_region.patch"
# TODO: remove
# https://github.com/flutter/flutter/issues/90223
@@ -78,9 +99,9 @@ $picks = @($TextSelectionMenuFix)
$reverts = @()
$patches = @($ModalBarrierPatch, $TextSelectionPatch, $MouseCursorPatch,
$ImageAnimPatch, $LayoutBuilderPatch, $NavigationDrawerPatch,
$PopupMenuPatch, $FABPatch, $SelectableRegionPatch, $SelectableRegionSelectionPatch,
$EditableTextPatch, $TextFieldPatch, $ScrollPositionPatch,
$ScrollablePatch)
$PopupMenuPatch, $FABPatch, $NullSafetySelectableRegionPatch,
$SelectableRegionPatch, $EditableTextPatch, $TextFieldPatch,
$ScrollPositionPatch, $ScrollablePatch)
switch ($platform.ToLower()) {
"android" {

View File

@@ -119,7 +119,7 @@ index 09fba7fc4fb..57ee469358e 100644
void computeSemanticsInformation(
List<InlineSpanSemanticsInformation> collector, {
diff --git a/packages/flutter/lib/src/rendering/paragraph.dart b/packages/flutter/lib/src/rendering/paragraph.dart
index 97a41dafb8d..15e7ce055e9 100644
index 97a41dafb8d..1dc2f36538d 100644
--- a/packages/flutter/lib/src/rendering/paragraph.dart
+++ b/packages/flutter/lib/src/rendering/paragraph.dart
@@ -7,6 +7,7 @@
@@ -341,18 +341,34 @@ index 97a41dafb8d..15e7ce055e9 100644
_setSelectionPosition(position, isEnd: isEnd);
if (position.offset == range.end) {
return SelectionResult.next;
@@ -3568,7 +3626,10 @@ class _SelectableFragment
@@ -3568,8 +3626,25 @@ class _SelectableFragment
final selectionPaint = Paint()
..style = PaintingStyle.fill
..color = paragraph.selectionColor!;
- for (final TextBox textBox in paragraph.getBoxesForSelection(selection)) {
+ for (final TextBox textBox in paragraph.getBoxesForSelection(
- context.canvas.drawRect(textBox.toRect().shift(offset), selectionPaint);
+
+ final List<ui.TextBox> boxes = paragraph.getBoxesForSelection(
+ selection,
+ boxHeightStyle: ui.BoxHeightStyle.max,
+ )) {
context.canvas.drawRect(textBox.toRect().shift(offset), selectionPaint);
+ boxWidthStyle: ui.BoxWidthStyle.tight,
+ );
+ ui.TextBox? mergedBox;
+ for (final textBox in boxes) {
+ if (mergedBox == null) {
+ mergedBox = textBox;
+ } else if (mergedBox.top != textBox.top) {
+ context.canvas.drawRect(Rect.fromLTRB(mergedBox.left, mergedBox.top, paragraph.size.width, mergedBox.bottom).shift(offset), selectionPaint);
+ mergedBox = textBox;
+ } else {
+ mergedBox = TextBox.fromLTRBD(mergedBox.left, mergedBox.top, textBox.right, mergedBox.bottom, mergedBox.direction);
+ }
+ }
+ if (mergedBox != null) {
+ context.canvas.drawRect(mergedBox.toRect().shift(offset), selectionPaint);
}
}
if (_startHandleLayerLink != null && value.startSelectionPoint != null) {
diff --git a/packages/flutter/lib/src/rendering/selection.dart b/packages/flutter/lib/src/rendering/selection.dart
index a813e141dc4..d045236d031 100644
--- a/packages/flutter/lib/src/rendering/selection.dart