Skip to content

[web] Respect text affinity in getLineBoundary at a soft wrap - #192664

Merged
auto-submit[bot] merged 23 commits into
flutter:masterfrom
flutter-zl:issue_188874_fix
Sep 30, 2026
Merged

auto-submit[bot] merged 23 commits into
flutter:masterfrom
flutter-zl:issue_188874_fix

Conversation

@flutter-zl

Copy link
Copy Markdown
Contributor

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.affinity is what says which of the two you mean. Web ignored it.

For 'Test Text' wrapping after 'Test ', asking about the start of line 2:

getLineBoundary(TextPosition(offset: 5))

native:  TextRange(5, 9)   line 2   correct
web:     TextRange(0, 5)   line 1   wrong

Skia reports line bounds inclusively, so line 1's end and line 2's start are 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 end meets the next line's start, 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:

  1. Click in the text box, then drag the caret so it sits just before the A on the second line. The readout confirms offset 15.
  2. The panel underneath follows the caret and shows the range getLineBoundary returns for that position.
  3. Before: the caret is drawn on line 2, but the boundary comes back as 0..15, which is line 1, so the panel reads MISMATCH.
  4. After: the boundary comes back as 15..16 and the panel reads AGREE.

Every other offset behaves identically in both builds. Offset 15 with downstream affinity is the only input whose answer changes.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Sep 12, 2026
@github-actions github-actions Bot added a: text input Entering text in a text field or keyboard related problems engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team labels Sep 12, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@flutter-zl
flutter-zl requested a review from mdebbar September 17, 2026 20:30

@mdebbar mdebbar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to do something similar in WebParagraph:

ui.TextRange getLineBoundary(ui.TextPosition position) {
final int codepointPosition = position.offset;
final ui.TextRange result = _layout.getLineBoundary(codepointPosition);
WebParagraphDebug.apiTrace('getLineBoundary($position): $result');
return result;
}

mdebbar
mdebbar previously approved these changes Sep 23, 2026

@mdebbar mdebbar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@flutter-zl flutter-zl added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 23, 2026
@flutter-dashboard

Copy link
Copy Markdown

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:

  • Configuration Changes: The .ci.yaml file might have been modified between the creation of this pull request and the start of this test run. This can lead to ci yaml validation errors.
  • Infrastructure Issues: Problems with the CI environment itself (e.g., quota) could have caused the failure.

A blank commit, or merging to head, will be required to resume running CI for this PR.

Error Details:

FormatException: ERROR: Mac_arm64_ios basic_material_app_ios__compile is a new builder added. it needs to be marked bringup: true
If ci.yaml wasn't changed, try `git fetch upstream && git merge upstream/master`



Stack trace:

#0      CiYaml._validate (package:cocoon_service/src/model/ci_yaml/ci_yaml.dart:395:7)
#1      new CiYaml (package:cocoon_service/src/model/ci_yaml/ci_yaml.dart:128:7)
#2      new CiYamlSet (package:cocoon_service/src/model/ci_yaml/ci_yaml.dart:48:23)
#3      CiYamlFetcher._getCiYaml (package:cocoon_service/src/service/scheduler/ci_yaml_fetcher.dart:124:12)
<asynchronous suspension>
#4      Scheduler.getPresubmitTargets (package:cocoon_service/src/service/scheduler.dart:1064:20)
<asynchronous suspension>
#5      Scheduler._getTestsForStage (package:cocoon_service/src/service/scheduler.dart:1367:14)
<asynchronous suspension>
#6      Scheduler._runCiTestingStage (package:cocoon_service/src/service/scheduler.dart:1408:30)
<asynchronous suspension>
#7      Scheduler.proceedToCiTestingStage (package:cocoon_service/src/service/scheduler.dart:1517:7)
<asynchronous suspension>
#8      Scheduler._closeSuccessfulEngineBuildStage (package:cocoon_service/src/service/scheduler.dart:1312:5)
<asynchronous suspension>
#9      Scheduler.processCheckRunCompleted (package:cocoon_service/src/service/scheduler.dart:1253:11)
<asynchronous suspension>
#10     PresubmitSubscription._processBuild (package:cocoon_service/src/request_handlers/presubmit_subscription.dart:228:7)
<asynchronous suspension>
#11     PresubmitSubscription.post (package:cocoon_service/src/request_handlers/presubmit_subscription.dart:119:5)
<asynchronous suspension>
#12     RequestHandler.service (package:cocoon_service/src/request_handling/request_handler.dart:42:20)
<asynchronous suspension>
#13     SubscriptionHandler.service (package:cocoon_service/src/request_handling/subscription_handler.dart:134:5)
<asynchronous suspension>
#14     createServer.<anonymous closure> (package:cocoon_service/server.dart:462:7)
<asynchronous suspension>
#15     main.<anonymous closure>.<anonymous closure> (file:///app/app_dart/bin/gae_server.dart:192:9)
<asynchronous suspension>

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 23, 2026
@auto-submit

auto-submit Bot commented Sep 23, 2026

Copy link
Copy Markdown
Contributor

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.

@flutter-zl flutter-zl added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 25, 2026
@auto-submit

auto-submit Bot commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

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.

@auto-submit auto-submit Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 25, 2026
@mdebbar mdebbar added the autosubmit Merge PR when tree becomes green via auto submit App label Sep 30, 2026
@auto-submit
auto-submit Bot added this pull request to the merge queue Sep 30, 2026
Merged via the queue into flutter:master with commit 468422c Sep 30, 2026
23 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Sep 30, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Sep 30, 2026
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems CICD Run CI/CD engine flutter/engine related. See also e: labels. platform-web Web applications specifically team-web Owned by Web platform team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Wrong TextRange result in TextPainter on web

2 participants