Repository navigation
[web] Respect text affinity in getLineBoundary at a soft wrap - #192664
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the getLineBoundary method in both CkParagraph and SkwasmParagraph to respect position affinity at soft wraps, aligning the web engine's behavior with the native implementation. It introduces a helper method _lineBoundaryAtOffset to determine line boundaries and adds unit tests to verify the behavior under soft wraps and hard line breaks. There are no review comments, and I have no feedback to provide.
mdebbar
left a comment
There was a problem hiding this comment.
We need to do something similar in WebParagraph:
flutter/engine/src/flutter/lib/web_ui/lib/src/engine/web_paragraph/paragraph.dart
Lines 1000 to 1005 in 3ea50fa
|
CI had a failure that stopped further tests from running. We need to investigate to determine the root cause. SHA at time of execution: 2aa8fd1. Possible causes:
A blank commit, or merging to head, will be required to resume running CI for this PR. Error Details: Stack trace: |
|
autosubmit label was removed for flutter/flutter/192664, because - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
autosubmit label was removed for flutter/flutter/192664, because - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label. |
# Conflicts: # engine/src/flutter/lib/web_ui/lib/src/engine/web_paragraph/layout.dart
flutter/flutter@55b8f88...d649d2b 2026-09-30 [email protected] [Android] Update the CLI to reject passing engine configuration flags with a prebuilt binary in release mode (flutter/flutter#190870) 2026-09-30 [email protected] Roll Skia from af1e8b356dd1 to c7b323126bf0 (1 revision) (flutter/flutter#193569) 2026-09-30 [email protected] [web] Respect text affinity in getLineBoundary at a soft wrap (flutter/flutter#192664) 2026-09-30 [email protected] [tool] Migrate TestCommand and platform runner to modular dependency injection (flutter/flutter#190789) 2026-09-30 [email protected] Roll Skia from 3a20a0464d25 to af1e8b356dd1 (1 revision) (flutter/flutter#193564) 2026-09-30 [email protected] Roll Skia from 554ef62d11a9 to 3a20a0464d25 (6 revisions) (flutter/flutter#193556) 2026-09-30 [email protected] Use null aware elements in `platform_views.dart` (flutter/flutter#193214) 2026-09-30 [email protected] Replace deprecated `withOpacity` in `flutter_logo.dart` (flutter/flutter#192583) 2026-09-30 [email protected] Roll Skia from f441ca223b2b to 554ef62d11a9 (72 revisions) (flutter/flutter#193548) 2026-09-30 [email protected] Fix StrcmpFixed matching prefixes in the Vulkan embedder tests (flutter/flutter#192999) 2026-09-30 [email protected] Update Engine to test Android 17 AVD (flutter/flutter#193239) 2026-09-29 [email protected] Give the Vulkan test context the extensions Impeller requires (flutter/flutter#193002) 2026-09-29 [email protected] Rename "subtext" to "supportingTextPadding" in `FormField`'s documentation (flutter/flutter#183582) 2026-09-29 [email protected] Set --no-js-strongly-connected-components for DDC compiles by default (flutter/flutter#193485) 2026-09-29 [email protected] Split pre-AGP 8.3 module AAR test into a Java 17 pinned target (flutter/flutter#193467) 2026-09-29 [email protected] Remove no-shuffle from gen_defaults_test (flutter/flutter#192280) 2026-09-29 [email protected] Update guidance on bumping Dart (flutter/flutter#193131) 2026-09-29 [email protected] Remove vestigial `download_jdk` gclient var (flutter/flutter#188571) 2026-09-29 [email protected] Roll pub packages (flutter/flutter#193522) 2026-09-29 [email protected] [flutter_tools] Lazily initialize AndroidSdk platform and build-tools discovery (flutter/flutter#191972) 2026-09-29 [email protected] [tool] Migrate Web build subcommands and toolchain to modular dependency injection (flutter/flutter#190783) 2026-09-29 [email protected] Pin androidx.test dependencies in integration_test (flutter/flutter#193316) 2026-09-29 [email protected] [flutter_tools] Include flutter.js.map in web builds (flutter/flutter#192257) 2026-09-29 [email protected] [WebParagraph] Fixing edge cases for wrapping text (with newlines) (flutter/flutter#189858) 2026-09-29 [email protected] Bump customer testing version for flutter/devtools update (flutter/flutter#193511) 2026-09-29 [email protected] Roll Packages from ba0364a to 3c6ce59 (14 revisions) (flutter/flutter#193507) 2026-09-29 [email protected] [flutter_tools] Guard socket streams and done futures against socket reset errors (flutter/flutter#192941) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md

Fixes #188874
Problem
When text wraps onto a second line, one offset sits in two places at once: the end of line 1 and the start of line 2.
TextPosition.affinityis what says which of the two you mean. Web ignored it.For
'Test Text'wrapping after'Test ', asking about the start of line 2:Skia reports line bounds inclusively, so line 1's
endand line 2'sstartare both 5 and the lookup always matched line 1 first. Line 2 was unreachable from any caret position, which broke line navigation keys and triple-tap line selection on web. Both shipping web renderers, CanvasKit and skwasm, had the bug independently.Fix
Ported the lookahead native has used since flutter-team-archive/engine#28008. If the position is downstream and sits exactly where one line's
endmeets the next line'sstart, return the next line instead.Hard line breaks are unaffected, because a newline takes an offset of its own so the two ranges never touch and the rule cannot fire. A test pins that.
Demo
Before: https://flutter-demo-60-before.web.app
After: https://flutter-demo-60-after.web.app
Repro steps:
Aon the second line. The readout confirms offset 15.getLineBoundaryreturns for that position.0..15, which is line 1, so the panel reads MISMATCH.15..16and the panel reads AGREE.Every other offset behaves identically in both builds. Offset 15 with downstream affinity is the only input whose answer changes.