-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Add handling of 'TextInput.clearClient' message from platform to framework (#35054). #35100
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
Add handling of 'TextInput.clearClient' message from platform to framework (#35054). #35100
Conversation
|
I think it's worth adding a unit test, maybe:
Writing this scenario I realize using the exact same method name |
@amirh the reason I named it the same was because, as far as I could tell, the "clearClient" request is the same request. The only difference is that the request can now originate from either the framework or the platform. Since both sides maintain state related to an input client, that seemed reasonable to me. Did I miss anything? PS - I'll try to add the test. |
|
I was just a little confused by that name. In my mental model the framework is the one who's making the decisions regarding the current text client, and the engine is executing whatever the framework says. I feel like it's still the case with the new "clearClient" we added (while the engine could clear the client locally, it notified the framework and waits for the framework to ask for the client to be cleared). Under this mental model I'd maybe call the new method "connectionLost" or maybe something with the word "notify". Just a suggestion. |
|
After chatting with @xster I'm going to pause this PR to see if we might find a framework-level resolution by way of platform lifecycle events. If not, then I'll return to these PRs, fix them up, and merge them in. |
|
(PR triage): Sound like this needs further discussion? Can we close the PR for now (since it is not really actionable right now) and move the discussion to an issue? |
|
Closing this PR as per @goderbauer's comment. We may need a more holistic solution to this issue. Will follow up once we've figured that out. |
|
After discussion with @xster and @goderbauer I'm re-opening this PR because this approach seems reasonable for the specific issue in question. |
0372083 to
ccc1aef
Compare
|
I updated the PR with a different approach that utilizes I also renamed the Android side message from 'clearClient' to 'onConnectionClosed'. I'm still dubious about where and how I'm invoking |
xster
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.
Let's add tests
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 tend to think this might be a bit too all-encompassing and doesn't leave us room to expand later (if we're implying that the only reason why this object would call you back is to disconnect). I'd just add an explicit listener.
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.
Doesn't ChangeNotifier mean "something has changed, query me to determine what you need to do"?
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.
add a comment here? i.e. we think it's safe to assume that the platform already hide what needed to hiding if the platform calls us to tell us that we disconnected?
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'm not sure I understand...the line you commented is the one that actually does hide the keyboard. Did you mean that we should comment from the other place where _onConnectionClosed() is invoked? or something else?
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.
This call seems reasonable. @HansMuller @gspencergoog any concerns for calling this when the platform disconnects the focus from the Flutter view?
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.
This seems fine to me.
ccc1aef to
38c3123
Compare
|
After some investigating, the failing test is here: The specific line in this PR that causes the failure is here: I'm unclear on the connection between this PR and the failing test so I reached out to @chunhtai for help fixing this PR. |
When textfield switch from non-readonly to readonly, Textfield will close the input connection if it is present. In your pr, it will listen to the connection close which will also unfocus the editable text and that will cause the selection overlay to be hidden. This is why the test is failing. The correct behavior is from non-readonly to readonly transition, the input connection should be close, but it should still have focus as the selectionoverlay should still present in readonly mode. Is there a reason why we want to unfocus when the input connection closes? |
WRT to this PR, the reason for that behavior is that when the input connection closes on the platform, it means that text editing has ended. The keyboard should disappear and any cursor should disappear as well. Otherwise, it looks like the text input is still legitimate even though no input connection exists. My perception of this situation is that the way we should do this is by unfocusing the text field. Based on the intended behavior that you mentioned, it sounds like a text field should be able to receive focus without an input connection, but I'm surprised by this. Are you sure that's the desired behavior? What does it mean for a text field to be focused if it can't receive text input? And how do we differentiate between situations where we should open a text input connection vs not open a text input connection if focus is unrelated to text input? |
It can be focused to receive text selection. and selection (long press on text) does not necessary required an input connection. The reason why we only have selection when it is focused is that we want to hide the selection if the textfield lose focus. |
|
Also, we will eventually need to support keyboard navigation of the selection (e.g. SHIFT RIGHT_ARROW to extend the selection), and in order to get key events from hardware keyboards, the widget needs to be focused.
|
|
(PR triage): @matthew-carroll Do you still have plans for this PR? |
|
yes |
…d' and instructed EditableTextState to unfocus() upon losing connection.
38c3123 to
aee8753
Compare
|
@gspencergoog @chunhtai I removed the explicit unfocus and the existing tests pass again. |
gspencergoog
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.
|
It will be good to have a test or two to guard it. |
|
/cc @nturgut |
|
@chunhtai I pushed a Dart test in text_input_test.dart. I attempted to add one at the textfield widget layer, too, but discovered that the way we fake text input makes such a test superfluous. We essentially bypass the channel behavior of text_input, which is the whole point of the test. I chatted with @gspencergoog about this and he also found the same limitation. So I don't think we can test at that level. |
chunhtai
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
… to framework (flutter#35054). (flutter#35100)" This reverts commit 324fe20.
|
Since this was reverted, is there a corresponding issue that this originally fixed that needs to be re-opened? |
|
The issue is still open. I never got around to closing it: #35054 |
|
I am still seeing the issue. is there any workaround ? |
|
For posterity, Matt's analysis for the cause of the revert from #39523
|
|
Has the issue been settled yet |

Problem:
Flutter is not setup to handle backgrounding and then foregrounding an app when an input control has focus. The issue is visible in the new embedding because the new embedding loosens platform restrictions around
FlutterActivitycontinuity.Repro Steps:
The issue is that Flutter is unaware that the app was backgrounded and therefore expects the same input connection to exist when re-foregrounded. But on the Android side, the input connection was lost when the app was backgrounded and therefore needs to be recreated when foregrounded again.
Solution:
When
FlutterActivitygoes to the background and detaches from theFlutterEngineinstance, instruct the framework to clear the input client. By clearing it, when the user taps on the control after being re-foregrounded, Flutter will request a new input connection and things should continue as expected.Corresponding Engine PR:
flutter/engine#9498