-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Fix Text selection handler disappear when dragged to new words #108808
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
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The engine doesn't know/care about text affinity I believe. It always sets it to downstream.
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 have correct the value when receive the remote value. WDYT?
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.
Could you double check deleting this is safety? @LongCatIsLooong THX : )
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 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will add a test to cover this.
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.
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)?
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.
done
|
@LongCatIsLooong @justinmc Hi, guys, I think this is ready for review :) |
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.
Do you still want to revert the affinity change if the user actually typed something?
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
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 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! I was thinking this might have needed a tricky engine fix, I'm happy if that's not true.
Can you check if this fixes/improves #84849?
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 👍 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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