-
Notifications
You must be signed in to change notification settings - Fork 6k
Conversation
shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm
Outdated
Show resolved
Hide resolved
shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm
Outdated
Show resolved
Hide resolved
@LongCatIsLooong might know the most about this #26486 |
2e042e8
to
7f953c3
Compare
Is this implementing this feature?
I think we should do that in the framework if possible. Is there a way that allows us to detect the second force press? Sending the bounding boxes of visible glyphs is going to be very expensive. |
I haven't found any way to detect the second press, the keyboard just changes the selection based on the position of the floating cursor. |
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
@LongCatIsLooong do you have any more review requests or can this land? |
@LongCatIsLooong We are already sending the rects since flutter/flutter#113048. I don't know how to look up benchmark results, maybe you can check the impact? |
Sorry for the delayed response. I'm not aware of any existing benchmarks that cover this, the framework only sends new rects when the underlying text layout changes, or when the text field stops scrolling (and if the text is too long when the floating cursor moves close enough to an edge the text field may scroll, that could break the interaction here too), and I don't think the performance of entering text is currently measured/monitored ( Is the 2nd force press event detectable via |
We can't find out about the second force press, the system just sends selection updates if used once we have the correct rectangles. |
Ah I see it's using |
Right now only the rects of the visible characters are sent so you can't scroll outside of the current viewport. I just tried always sending all the rects, it works surprisingly well, as since the rects aren't updated during scroll, they remain stable as UIKit changes the selection, which causes the framework to scroll. But it sometimes seems kind of glitchy, there may be some update leaking through from somewhere. In general you wouldn't need to send all the rects to get scrolling to work, since the keyboard is only a fixed width. Probably it would be optimal to send the current visible characters as well as the same width of the view off of each edge. No idea about vertical scrolling though... |
Are we making progress on this? Can we land this perhaps and file a followup? |
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 implementation LGTM.
characterAfterCaret.size.height); | ||
} | ||
CGRect characterBeforeCaret = rects[0].rect; | ||
// Return a zero-width rectangle along the right edge of the character before the caret position. |
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 use the center instead? I think that would probably work better for RTL and Bidi text since we don't send the bidi info along with the selection rects.
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.
I don't think centre would work correctly, it should stay where it is for LTR. But for RTL you're right it likely won't work properly. Maybe a better approach would be putting the rectangle midway between the closest two edges of the adjacent selectionRects to the cursor. Then we don't care about the paint direction v.s. semantic direction.
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.
it should stay where it is for LTR
Sorry I'm not sure how UIKit is going to use this for floating cursor, could you explain why that wouldn't work?
two edges of the adjacent selectionRects to the cursor.
If the position happens to be at a line break or bidi text boundary then the logically adjacent selection rects won't necessarily be visually adjacent right?
Almost ready to land, waiting on answer to last questions from @LongCatIsLooong |
Upon revisiting this to check out linebreak / RTL text I think we will need some other framework changes first. Mainly to avoid existing floating cursor implementation from conflicting. Also working on engine improvements to handle various edge cases in caret rect positioning. |
7f953c3
to
e1d1d27
Compare
@moffatman let us know when this is ready to re-review. |
@jmagman It's ready for re-review |
|
||
- (CGRect)bounds { | ||
return _isFloatingCursorActive ? kSpacePanBounds : super.bounds; | ||
NSInteger index = ((FlutterTextPosition*)position).index; |
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 I think this is a NSUInteger
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.
It have it as signed to do MAX(0, index - 1)
later
// There is no character before the caret, so this will be the bounds of the character after the | ||
// caret position. | ||
CGRect characterAfterCaret = rects[0].rect; | ||
// Return a zero-width rectangle 30% in from the left edge of the character after the caret |
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.
Does this work RTL?
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.
I thought it did but I tested the wrong way, looking into changes now to handle proper RTL unicode chars.
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.
I think there is a bug in Skia getGlyphPositionAtCoordinate in RTL, looking at that now
Here is the Skia change: https://skia-review.googlesource.com/c/skia/+/619838 Will also need another framework PR to send the text directionality of each selection rect |
It fixes issues with characters of varying heights Don't reduce the precision for pencil usage
Instead of the hack using the _selectionAffinity for the user's current cursor position, which may not be the same as the one passed to caretRectForPosition. Also optimize closestPositionToPoint, we don't need a second loop. The only possible closer position is the far edge of the current closest position.
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. Thanks for making all these changes.
BOOL isFartherToRight = | ||
selectionRect.origin.x + (checkRightBoundary ? selectionRect.size.width : 0) > | ||
otherSelectionRect.origin.x; | ||
BOOL isFarther; |
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: maybe isCloserToTrailing
?
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.
It's not about "closer" to anything, just further in the direction of text layout.
if (_selectionRects[i].position >= start && _selectionRects[i].position <= end) { | ||
if (_selectionRects[i].position >= start && | ||
(_selectionRects[i].position < end || | ||
(start == end && _selectionRects[i].position <= end))) { |
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 is this new condition for?
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.
In the old behaviour, you would always get one more extra rect (since it was comparing <= end
). Now, we are correctly using < end
. But we still want to return the special rect (zero-width) if start == end
instead of no rects. So we can use the old comparison <= end
but only if we have start == end
.
Text Range | Old rects returned | New rects returned |
---|---|---|
0..0 | [0] with width zero | [0] with width zero |
0..1 | [0], [1] | [0] |
0..2 | [0], [1], [2] | [0], [1] |
And so on...
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.
Gotcha. Looks like the old behavior is a bug then.
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. Thanks for making all these changes.
…126622) flutter/engine@f38f46f...748ef96 2023-05-11 [email protected] Roll Skia from aed81125e6bc to ccec5093ca38 (10 revisions) (flutter/engine#41963) 2023-05-11 [email protected] Roll Fuchsia Mac SDK from 2tQjI0g3aDmjHAtMw... to MjcKzcsqMDkuRKopu... (flutter/engine#41960) 2023-05-11 [email protected] iPhone floating cursor selection (flutter/engine#36643) 2023-05-11 [email protected] Update README.md (flutter/engine#41953) 2023-05-11 [email protected] Roll Clang from 5344d8e10bb7 to 6d667d4b261e (flutter/engine#41949) 2023-05-11 [email protected] Use moved SkImage procs (flutter/engine#41947) 2023-05-11 [email protected] allow supplying custom gn args in gn wrapper (flutter/engine#41794) 2023-05-11 [email protected] fix: platform_dispatcher documentation typo (flutter/engine#41739) 2023-05-11 [email protected] Remove GN staging flag for save layer bounds (flutter/engine#41940) 2023-05-11 [email protected] switch MockTexture off of MockCanvas calls (flutter/engine#41906) 2023-05-11 [email protected] [Android] Lifecycle defaults to focused instead of unfocused (flutter/engine#41875) 2023-05-11 [email protected] Roll Skia from ccf73af6ca91 to aed81125e6bc (9 revisions) (flutter/engine#41946) 2023-05-11 [email protected] Clobber caches in licenses test. (flutter/engine#41942) Also rolling transitive DEPS: fuchsia/sdk/core/mac-amd64 from 2tQjI0g3aDmj to MjcKzcsqMDku If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…lutter#126622) flutter/engine@f38f46f...748ef96 2023-05-11 [email protected] Roll Skia from aed81125e6bc to ccec5093ca38 (10 revisions) (flutter/engine#41963) 2023-05-11 [email protected] Roll Fuchsia Mac SDK from 2tQjI0g3aDmjHAtMw... to MjcKzcsqMDkuRKopu... (flutter/engine#41960) 2023-05-11 [email protected] iPhone floating cursor selection (flutter/engine#36643) 2023-05-11 [email protected] Update README.md (flutter/engine#41953) 2023-05-11 [email protected] Roll Clang from 5344d8e10bb7 to 6d667d4b261e (flutter/engine#41949) 2023-05-11 [email protected] Use moved SkImage procs (flutter/engine#41947) 2023-05-11 [email protected] allow supplying custom gn args in gn wrapper (flutter/engine#41794) 2023-05-11 [email protected] fix: platform_dispatcher documentation typo (flutter/engine#41739) 2023-05-11 [email protected] Remove GN staging flag for save layer bounds (flutter/engine#41940) 2023-05-11 [email protected] switch MockTexture off of MockCanvas calls (flutter/engine#41906) 2023-05-11 [email protected] [Android] Lifecycle defaults to focused instead of unfocused (flutter/engine#41875) 2023-05-11 [email protected] Roll Skia from ccf73af6ca91 to aed81125e6bc (9 revisions) (flutter/engine#41946) 2023-05-11 [email protected] Clobber caches in licenses test. (flutter/engine#41942) Also rolling transitive DEPS: fuchsia/sdk/core/mac-amd64 from 2tQjI0g3aDmj to MjcKzcsqMDku If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-engine-flutter-autoroll Please CC [email protected],[email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
The `isRTLAtPosition` method had a bug, it used `NSInteger max = [_selectionRects count]` instead of `NSInteger max = [_selectionRects count] - 1`. But I realized we don't even need the function any more, it was used in a few places in previous iterations of #36643, but in the only place remaining, we actually already have the selection rect and don't need to search for it by position. Btw as an explanation of the crash, I guess there is some mismatch between code point and character count somewhere. UIKit was asking for `caretRectForPosition:2` when we only had 1 character. This could have only crashed when floating cursor selection was used, but actually when switching to CJK keyboard, UIKit turns out to use `caretRectForPosition` to calculate something about the composing rect. Fixes flutter/flutter#128031
The `isRTLAtPosition` method had a bug, it used `NSInteger max = [_selectionRects count]` instead of `NSInteger max = [_selectionRects count] - 1`. But I realized we don't even need the function any more, it was used in a few places in previous iterations of #36643, but in the only place remaining, we actually already have the selection rect and don't need to search for it by position. Btw as an explanation of the crash, I guess there is some mismatch between code point and character count somewhere. UIKit was asking for `caretRectForPosition:2` when we only had 1 character. This could have only crashed when floating cursor selection was used, but actually when switching to CJK keyboard, UIKit turns out to use `caretRectForPosition` to calculate something about the composing rect. Fixes flutter/flutter#128031
…42539) The `isRTLAtPosition` method had a bug, it used `NSInteger max = [_selectionRects count]` instead of `NSInteger max = [_selectionRects count] - 1`. But I realized we don't even need the function any more, it was used in a few places in previous iterations of flutter#36643, but in the only place remaining, we actually already have the selection rect and don't need to search for it by position. Btw as an explanation of the crash, I guess there is some mismatch between code point and character count somewhere. UIKit was asking for `caretRectForPosition:2` when we only had 1 character. This could have only crashed when floating cursor selection was used, but actually when switching to CJK keyboard, UIKit turns out to use `caretRectForPosition` to calculate something about the composing rect. Fixes flutter/flutter#128031
…42540) The `isRTLAtPosition` method had a bug, it used `NSInteger max = [_selectionRects count]` instead of `NSInteger max = [_selectionRects count] - 1`. But I realized we don't even need the function any more, it was used in a few places in previous iterations of flutter#36643, but in the only place remaining, we actually already have the selection rect and don't need to search for it by position. Btw as an explanation of the crash, I guess there is some mismatch between code point and character count somewhere. UIKit was asking for `caretRectForPosition:2` when we only had 1 character. This could have only crashed when floating cursor selection was used, but actually when switching to CJK keyboard, UIKit turns out to use `caretRectForPosition` to calculate something about the composing rect. Fixes flutter/flutter#128031
Floating cursor selection hasn't worked as we haven't been returning a real value for
caretRectForPosition:
. If we have the selection rectangles, we can do so.Fixes #30476
Requires selection rects to be turned on for iPhone (flutter/flutter#113048)
Pre-launch Checklist
writing and running engine tests.
///
).