-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Changing TextPainter.getOffsetForCaret implementation to remove the logarithmic search
#143281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changing TextPainter.getOffsetForCaret implementation to remove the logarithmic search
#143281
Conversation
bf061fe to
dd926a7
Compare
418c5d2 to
d213ac0
Compare
TextPainter.getOffsetForCaretTextPainter.getOffsetForCaret implementation to remove the logarithmic search
justinmc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with nits 👍
| 0x000B || // Form Feed | ||
| 0x000C || // Vertical Feed | ||
| 0x2028 || // Line Separator | ||
| 0x2029 => true, // Paragraph Separator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much better, thanks!
| assert(lastLineIndex >= 0); | ||
| final ui.LineMetrics lineMetrics = _paragraph.getLineMetricsAt(lastLineIndex)!; | ||
| // SkParagraph currently treats " " and "\t" as white spaces. Trailing white | ||
| // spaces don't contribute to the line width thus require special handling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this say "and thus"?
| // TODO(LongCatIsLooong): handle the case where maxLine is set to non-null | ||
| // and the last line ends with trailing whitespaces. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you mean to handle this in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. I need to expose the text range from line metrics for this. Currently it only checks if textLength - 1 is a trailing space.
| /// ligature component. | ||
| final class _LineCaretMetrics { | ||
| const _LineCaretMetrics({required this.offset, required this.writingDirection}); | ||
| /// The offset from the top left corner of the paragraph to the the caret's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplicate "the".
| // | ||
| // For a TextPosition, typically when its TextAffinity is downstream, the | ||
| // corresponding I-beam caret is anchored to the leading edge of the | ||
| // `offset`-th character in the text. When the TextAffinity is upstream, the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe: "offset-th character" => "character at offset"
So for offset 1 and affinity downstream, it's anchored to the leading edge of the 2nd character (the character at index 1), right? If so, I think the above change is more clear. When I first read this paragraph, I think I incorrectly interpreted it to mean the 1st character.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's right.
| // too close to the right. | ||
| controller.dispose(); | ||
| controller = TextEditingController(text: List<String>.filled(200, 'a').join()); | ||
| controller = TextEditingController(text: 'a' * 200); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did Dart not always have the multiplying a String thing?
| ).topRight.dx; | ||
| inputWidth = editable.size.width; | ||
| expect(cursorRight, inputWidth - kCaretGap); | ||
| expect(cursorRight, inputWidth - kCaretGap - text.length * 10 - 2.0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the 2.0?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
caret width
| } | ||
|
|
||
| Offset textOffsetToPosition(WidgetTester tester, int offset, {int index = 0}) { | ||
| assert(0 <= offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Yoda ordering.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed the assert.
| }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.android })); | ||
|
|
||
|
|
||
| for (final TextDirection textDirection in TextDirection.values) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not run this for both TextDirections any more?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The LTR variation is exactly the same test as the one above.
| return _caretMetrics; | ||
| } | ||
|
|
||
| final ui.GlyphInfo? glyphInfo = cachedLayout.paragraph.getGlyphInfoAt(offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain the secret to removing the logarithmic search? Are you able to get the bounds of the glyph using this getGlyphInfoAt method instead? What does it do internally if so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getBoxForSelection doesn't include a multi-code-unit character if the input selection doesn't include the full range of it. Alternatively the same can be done using the characters package.
|
Reason for revert: #143797 |
…emove the logarithmic search (#143281)" (#143801) Reverts #143281 Initiated by: LongCatIsLooong Reason for reverting: #143797 Original PR Author: LongCatIsLooong Reviewed By: {justinmc, jason-simmons} This change reverts the following previous change: Original Description: The behavior largely remains the same, except: 1. The EOT cursor `(textLength, downstream)` for text ending in the opposite writing direction as the paragraph is now placed at the visual end of the last line. For example, in a LTR paragraph, the EOT cursor for `aA` (lowercase for LTR and uppercase for RTL) is placed to the right of the line: `aA|` (it was `a|A` before). This matches the behavior of most applications that do logical order arrow key navigation instead of visual order navigation. And it makes the navigation order consistent for `aA\naA`: ``` |aA => aA| => aA| => aA => aA => aA aA aA aA |aA aA| aA| (1) (2) (3) (4) (5) (6) ``` This is indeed still pretty confusing as (2) and (3), as well as (5) and (6) are hard to distinguish (when the I beam has a large width they are actually visually distinguishable -- they use the same anchor but one gets painted to the left and the other to the right. I noticed that emacs does the same). But logical order navigation will always be confusing in bidi text, in one way or another. Interestingly there are 3 different behaviors I've observed in chrome: - the chrome download dialog (which I think uses GTK text widgets but not sure which version) gives me 2 cursors when navigating bidi text, and - its HTML fields only show one, and presumably they place the I beam at the **trailing edge** of the character (which makes more sense for backspacing I guess). - On the other hand, its (new) omnibar seems to use visual order arrow navigation Side note: we may need to update the "tap to place the caret here" logic to handle the case where the tap lands outside of the text and the text ends in the opposite writing direction. 2. Removed the logarithmic search. The same could be done using the characters package but when glyphInfo tells you about the baseline location in the future we probably don't need the `getBoxesForRange` call. This should fix #123424. ## Internal Tests This is going to change the image output of some internal golden tests. I'm planning to merge #143281 before this to avoid updating the same golden files twice for invalid selections.
…move the logarithmic search (flutter/flutter#143281)
…move the logarithmic search (flutter/flutter#143281)
…move the logarithmic search (flutter/flutter#143281)
…move the logarithmic search (flutter/flutter#143281)
…move the logarithmic search (flutter/flutter#143281)
Manual roll Flutter from 5129806 to efee280 (47 revisions) Manual roll requested by [email protected] flutter/flutter@5129806...efee280 2024-02-22 [email protected] Roll Flutter Engine from bf5c003085fd to 7eeb697687d5 (16 revisions) (flutter/flutter#143911) 2024-02-22 [email protected] Update PR template for dart fix (flutter/flutter#143879) 2024-02-22 [email protected] Re-use methods to calculate leading and trailing garbage in RenderSliverMultiBoxAdaptor (flutter/flutter#143884) 2024-02-21 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[Impeller] Make impeller goldens test blocking. (#143864)" (flutter/flutter#143896) 2024-02-21 [email protected] [Impeller] Make impeller goldens test blocking. (flutter/flutter#143864) 2024-02-21 [email protected] Disable color filter sepia test for Impeller. (flutter/flutter#143861) 2024-02-21 [email protected] Roll Flutter Engine from 52ffcaadea41 to bf5c003085fd (12 revisions) (flutter/flutter#143875) 2024-02-21 [email protected] Roll Flutter Engine from 4128895d79a1 to 52ffcaadea41 (1 revision) (flutter/flutter#143862) 2024-02-21 [email protected] Deprecate redundant itemExtent in RenderSliverFixedExtentBoxAdaptor methods (flutter/flutter#143412) 2024-02-21 [email protected] Add aab as alias for appbundle (flutter/flutter#143855) 2024-02-21 [email protected] Roll Flutter Engine from e16f43eeaaa4 to 4128895d79a1 (1 revision) (flutter/flutter#143856) 2024-02-21 [email protected] Roll Packages from 8bba41b to 48048f6 (2 revisions) (flutter/flutter#143853) 2024-02-21 [email protected] Update `hourMinuteTextStyle` defaults for Material 3 Time Picker (flutter/flutter#143749) 2024-02-21 [email protected] Roll Flutter Engine from 93063f61943a to e16f43eeaaa4 (2 revisions) (flutter/flutter#143827) 2024-02-21 [email protected] Roll Flutter Engine from ed49634486e9 to 93063f61943a (1 revision) (flutter/flutter#143826) 2024-02-21 [email protected] `CalendarDatePicker` doesn't announce selected date on desktop (flutter/flutter#143583) 2024-02-21 [email protected] Roll Flutter Engine from 9100d326475a to ed49634486e9 (2 revisions) (flutter/flutter#143824) 2024-02-21 [email protected] Add `timeSelectorSeparatorColor` and `timeSelectorSeparatorTextStyle` for Material 3 Time Picker (flutter/flutter#143739) 2024-02-21 [email protected] Roll Flutter Engine from efc69946cb1e to 9100d326475a (2 revisions) (flutter/flutter#143820) 2024-02-21 [email protected] Roll Flutter Engine from 700250436e3f to efc69946cb1e (2 revisions) (flutter/flutter#143816) 2024-02-21 [email protected] Roll Flutter Engine from 3557277c575c to 700250436e3f (1 revision) (flutter/flutter#143814) 2024-02-21 [email protected] more fixes to unstable impeller goldens. (flutter/flutter#143811) 2024-02-21 [email protected] Roll Flutter Engine from cb12a8cc97a1 to 3557277c575c (2 revisions) (flutter/flutter#143807) 2024-02-21 [email protected] [flutter_tools] enable wasm compile on beta channel (flutter/flutter#143779) 2024-02-21 [email protected] Fix initialization of time in repeat on AnimationController (flutter/flutter#142887) 2024-02-21 [email protected] Disable debug banner to stabilize impeller goldens. (flutter/flutter#143794) 2024-02-21 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Changing `TextPainter.getOffsetForCaret` implementation to remove the logarithmic search (#143281)" (flutter/flutter#143801) 2024-02-20 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Add UI Benchmarks (#143542)" (flutter/flutter#143798) 2024-02-20 [email protected] Avoid applying partial dartfixes on CI (flutter/flutter#143551) 2024-02-20 [email protected] Add UI Benchmarks (flutter/flutter#143542) 2024-02-20 [email protected] Roll Flutter Engine from 1ae2c10e8071 to cb12a8cc97a1 (1 revision) (flutter/flutter#143791) 2024-02-20 [email protected] Implement `_suspendedNode` fix (flutter/flutter#143556) 2024-02-20 [email protected] Change `ItemExtentBuilder`'s return value nullable (flutter/flutter#142428) 2024-02-20 [email protected] Roll Flutter Engine from 27828054f07a to 1ae2c10e8071 (6 revisions) (flutter/flutter#143783) 2024-02-20 [email protected] Roll Flutter Engine from e16a260265ad to 27828054f07a (1 revision) (flutter/flutter#143769) 2024-02-20 [email protected] [gold] Always provide host ABI to gold config (flutter/flutter#143621) 2024-02-20 [email protected] instead of exiting the tool, print a warning when using --flavor with an incompatible device (flutter/flutter#143735) 2024-02-20 [email protected] Implementing `switch` expressions: everything in `flutter/lib/src/` (flutter/flutter#143634) 2024-02-20 [email protected] Changing `TextPainter.getOffsetForCaret` implementation to remove the logarithmic search (flutter/flutter#143281) 2024-02-20 [email protected] Delete local.properties that shouldn't have been pushed (flutter/flutter#143774) 2024-02-20 [email protected] Clean leaks. (flutter/flutter#142818) 2024-02-20 [email protected] Introduce tone-based surfaces and accent color add-ons - Part 2 (flutter/flutter#138521) 2024-02-20 [email protected] Explain when and why to use CrossAxisAlignment.baseline (flutter/flutter#143632) 2024-02-20 [email protected] Roll Flutter Engine from a41da3701923 to e16a260265ad (2 revisions) (flutter/flutter#143763) ...
remove the logarithmic search (flutter#143281)" (reverted in flutter#143801) This reverts commit f9b3b84.
) Manual roll Flutter from 5129806 to efee280 (47 revisions) Manual roll requested by [email protected] flutter/flutter@5129806...efee280 2024-02-22 [email protected] Roll Flutter Engine from bf5c003085fd to 7eeb697687d5 (16 revisions) (flutter/flutter#143911) 2024-02-22 [email protected] Update PR template for dart fix (flutter/flutter#143879) 2024-02-22 [email protected] Re-use methods to calculate leading and trailing garbage in RenderSliverMultiBoxAdaptor (flutter/flutter#143884) 2024-02-21 98614782+auto-submit[bot]@users.noreply.github.com Reverts "[Impeller] Make impeller goldens test blocking. (#143864)" (flutter/flutter#143896) 2024-02-21 [email protected] [Impeller] Make impeller goldens test blocking. (flutter/flutter#143864) 2024-02-21 [email protected] Disable color filter sepia test for Impeller. (flutter/flutter#143861) 2024-02-21 [email protected] Roll Flutter Engine from 52ffcaadea41 to bf5c003085fd (12 revisions) (flutter/flutter#143875) 2024-02-21 [email protected] Roll Flutter Engine from 4128895d79a1 to 52ffcaadea41 (1 revision) (flutter/flutter#143862) 2024-02-21 [email protected] Deprecate redundant itemExtent in RenderSliverFixedExtentBoxAdaptor methods (flutter/flutter#143412) 2024-02-21 [email protected] Add aab as alias for appbundle (flutter/flutter#143855) 2024-02-21 [email protected] Roll Flutter Engine from e16f43eeaaa4 to 4128895d79a1 (1 revision) (flutter/flutter#143856) 2024-02-21 [email protected] Roll Packages from 8bba41b to 48048f6 (2 revisions) (flutter/flutter#143853) 2024-02-21 [email protected] Update `hourMinuteTextStyle` defaults for Material 3 Time Picker (flutter/flutter#143749) 2024-02-21 [email protected] Roll Flutter Engine from 93063f61943a to e16f43eeaaa4 (2 revisions) (flutter/flutter#143827) 2024-02-21 [email protected] Roll Flutter Engine from ed49634486e9 to 93063f61943a (1 revision) (flutter/flutter#143826) 2024-02-21 [email protected] `CalendarDatePicker` doesn't announce selected date on desktop (flutter/flutter#143583) 2024-02-21 [email protected] Roll Flutter Engine from 9100d326475a to ed49634486e9 (2 revisions) (flutter/flutter#143824) 2024-02-21 [email protected] Add `timeSelectorSeparatorColor` and `timeSelectorSeparatorTextStyle` for Material 3 Time Picker (flutter/flutter#143739) 2024-02-21 [email protected] Roll Flutter Engine from efc69946cb1e to 9100d326475a (2 revisions) (flutter/flutter#143820) 2024-02-21 [email protected] Roll Flutter Engine from 700250436e3f to efc69946cb1e (2 revisions) (flutter/flutter#143816) 2024-02-21 [email protected] Roll Flutter Engine from 3557277c575c to 700250436e3f (1 revision) (flutter/flutter#143814) 2024-02-21 [email protected] more fixes to unstable impeller goldens. (flutter/flutter#143811) 2024-02-21 [email protected] Roll Flutter Engine from cb12a8cc97a1 to 3557277c575c (2 revisions) (flutter/flutter#143807) 2024-02-21 [email protected] [flutter_tools] enable wasm compile on beta channel (flutter/flutter#143779) 2024-02-21 [email protected] Fix initialization of time in repeat on AnimationController (flutter/flutter#142887) 2024-02-21 [email protected] Disable debug banner to stabilize impeller goldens. (flutter/flutter#143794) 2024-02-21 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Changing `TextPainter.getOffsetForCaret` implementation to remove the logarithmic search (#143281)" (flutter/flutter#143801) 2024-02-20 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Add UI Benchmarks (#143542)" (flutter/flutter#143798) 2024-02-20 [email protected] Avoid applying partial dartfixes on CI (flutter/flutter#143551) 2024-02-20 [email protected] Add UI Benchmarks (flutter/flutter#143542) 2024-02-20 [email protected] Roll Flutter Engine from 1ae2c10e8071 to cb12a8cc97a1 (1 revision) (flutter/flutter#143791) 2024-02-20 [email protected] Implement `_suspendedNode` fix (flutter/flutter#143556) 2024-02-20 [email protected] Change `ItemExtentBuilder`'s return value nullable (flutter/flutter#142428) 2024-02-20 [email protected] Roll Flutter Engine from 27828054f07a to 1ae2c10e8071 (6 revisions) (flutter/flutter#143783) 2024-02-20 [email protected] Roll Flutter Engine from e16a260265ad to 27828054f07a (1 revision) (flutter/flutter#143769) 2024-02-20 [email protected] [gold] Always provide host ABI to gold config (flutter/flutter#143621) 2024-02-20 [email protected] instead of exiting the tool, print a warning when using --flavor with an incompatible device (flutter/flutter#143735) 2024-02-20 [email protected] Implementing `switch` expressions: everything in `flutter/lib/src/` (flutter/flutter#143634) 2024-02-20 [email protected] Changing `TextPainter.getOffsetForCaret` implementation to remove the logarithmic search (flutter/flutter#143281) 2024-02-20 [email protected] Delete local.properties that shouldn't have been pushed (flutter/flutter#143774) 2024-02-20 [email protected] Clean leaks. (flutter/flutter#142818) 2024-02-20 [email protected] Introduce tone-based surfaces and accent color add-ons - Part 2 (flutter/flutter#138521) 2024-02-20 [email protected] Explain when and why to use CrossAxisAlignment.baseline (flutter/flutter#143632) 2024-02-20 [email protected] Roll Flutter Engine from a41da3701923 to e16a260265ad (2 revisions) (flutter/flutter#143763) ...
…ion to remove the logarithmic search (flutter#143281)" (reverted in flutter#143801) (flutter#143954)" This reverts commit a0a854a.
…move the logarithmic search (flutter/flutter#143281)
The behavior largely remains the same, except:
(textLength, downstream)for text ending in the opposite writing direction as the paragraph is now placed at the visual end of the last line.For example, in a LTR paragraph, the EOT cursor for
aA(lowercase for LTR and uppercase for RTL) is placed to the right of the line:aA|(it wasa|Abefore).This matches the behavior of most applications that do logical order arrow key navigation instead of visual order navigation.
And it makes the navigation order consistent for
aA\naA:This is indeed still pretty confusing as (2) and (3), as well as (5) and (6) are hard to distinguish (when the I beam has a large width they are actually visually distinguishable -- they use the same anchor but one gets painted to the left and the other to the right. I noticed that emacs does the same).
But logical order navigation will always be confusing in bidi text, in one way or another.
Interestingly there are 3 different behaviors I've observed in chrome:
Side note: we may need to update the "tap to place the caret here" logic to handle the case where the tap lands outside of the text and the text ends in the opposite writing direction.
getBoxesForRangecall. This should fix Caret misplaced in bidi text #123424.Internal Tests
This is going to change the image output of some internal golden tests. I'm planning to merge #143281 before this to avoid updating the same golden files twice for invalid selections.
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.