Fix Text selection handler disappear when dragged to new words#108808
Fix Text selection handler disappear when dragged to new words#108808auto-submit[bot] merged 10 commits intoflutter:masterfrom
Conversation
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat (don't just cc him here, he won't see it! He's on Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
There was a problem hiding this comment.
I know this a little hack.
If we can figure out why the engine change the affinity maybe we have a better solution.
CC @LongCatIsLooong
There was a problem hiding this comment.
The engine doesn't know/care about text affinity I believe. It always sets it to downstream.
There was a problem hiding this comment.
I have correct the value when receive the remote value. WDYT?
There was a problem hiding this comment.
Could you double check deleting this is safety? @LongCatIsLooong THX : )
There was a problem hiding this comment.
In UIKit/Android apps, the text edit menu should go away once the user starts typing. Would this change that behavior?
There was a problem hiding this comment.
Will add a test to cover this.
There was a problem hiding this comment.
Ah _handleSelectionChanged is called in _formatAndSave too, that seems to be a messy callpath. Do you mind adding a comment to explain why we're not hiding the handles here (or link the issue)?
|
@LongCatIsLooong @justinmc Hi, guys, I think this is ready for review :) |
There was a problem hiding this comment.
Do you still want to revert the affinity change if the user actually typed something?
There was a problem hiding this comment.
As you point out that the input server never know the actually affinity and can not change the affinity by key board.
Currently we can only change the affinity by tap the text string and change the selection.
Additional, the affinity is only valid when line breaks cause by render wrapping, not explicit newline characters.
There was a problem hiding this comment.
Ah sorry I misspoke, the engine doesn't care but the framework does (for rendering the caret at the right place).
As far as I can tell on iOS/Android when the user types using a virtual/hardware keyboard the affinity is always set to TextAffinity.downstream. TextAffinity.upstream is only used when the selection is change by certain gestures when the caret position is located at a soft-wrap line boundary, or bidi boundary. For example when the text field needs to show
aa|
bb
instead of
aa
|bb
There was a problem hiding this comment.
Absolutely correct, so we can override the affinity from engine, right?
Otherwise, the only affinity change will trigger selection change and dismiss the handler by mistake.
There was a problem hiding this comment.
Say the line can only accommodate 2 characters, and the text editing state was initially
(text: 'a', textSelection.collapsed(1, affinity: upstream)), when the user types another a the affinity should be changed to downstream, so the framework knows the caret should be rendered at the start of line 2?
There was a problem hiding this comment.
Could you explain why? The documentation says that affinity only makes sense when there is ambiguity in the visual location, and is used to paint the caret. Am I miss something?
There was a problem hiding this comment.
When the user types something, or changes the selection using a keyboard, the caret typically shouldn't be painted using the upstream affinity. In other words it should be
aa
|bb
instead of
aa|
bb
There was a problem hiding this comment.
I almost understand what you mean.
Another case, if the aa| is composed, and I wanna to type aaa| with composed, it should be painted using upstream affinity?
There was a problem hiding this comment.
That I'm not sure. On Android it's behaving like it's upstream. But I vaguely remember there's no cursor affinity on Android.
There was a problem hiding this comment.
In UIKit/Android apps, the text edit menu should go away once the user starts typing. Would this change that behavior?
justinmc
left a comment
There was a problem hiding this comment.
LGTM 👍 Thanks again!
I tried running this locally and it does indeed appear to fix both of those issues!
| value.selection.affinity != _value.selection.affinity) { | ||
| return true; | ||
| } | ||
| return false; |
There was a problem hiding this comment.
Could you get rid of the if and just return the condition directly?
Fixes #108673
Fixes #84849
Issue 1 - Tap the word the handler appear randomly
1, Tap on the middle of 'Hello'
2, Local value update to
3, Send the new local value to remote, and then, the auto correction will update the composing back to framework
But the affinity will mutate randomly. I'm not sure if this is a problem with the engine, but I understand that in this scenario, affinity is meaningless.
If the affinity was mutate, the handle will be hide by
_TextFieldState._handleSelectionChangedbecause the cause is keyboard.Issue 2 - The handler can not drag to a new word
flutter/packages/flutter/lib/src/widgets/editable_text.dart
Lines 2148 to 2149 in 2d771d4
This is because we remove the handler overlay during drag because the engine update the composing during drag.
I found that we can remove the line, the handler's visibility will be updated by
_TextFieldState._handleSelectionChangedCC @LongCatIsLooong