-
Notifications
You must be signed in to change notification settings - Fork 26.7k
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
False Window inset is set when dismissing keyboard preventing apps from using the full screen. #118761
Comments
On api 30+ the red bar from the screenshot is a transient and causes content to shift at the end of the keyboard close animation. On earlier than api30 this condition can be suck. |
If you come across this issue as an app developer the quick fix is to depend on the androidx library for setting fullscreen. Using WindowInsetsControllerCompat you avoid an edge condition in the flutter engine and get the expected behavior. |
To fix this in the engine we need to modify Technical description of issue and fix: On window there are bits you set for behavior. The newer one a customer was setting is BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE. FlutterView is calling a deprecated (in api 30) but still working method getWindowSystemUiVisibility and was checking for the bit SYSTEM_UI_FLAG_HIDE_NAVIGATION. Which best I can tell was making our code believe that there were nav bars and then we set the inset correctly assuming those nav bars were permanent. Then the close animation triggered and we dropped the bottom inset. Bottom line: We can override
Note Googlers can see a longer more winding discovery here https://buganizer.corp.google.com/issues/258263557#comment73 |
Suggested Task Order:
|
Dropped to a p3 since its being worked on this quarter and no longer blocking a google customer with a work around. |
Sorry this has gone so long without update! Had other things take priority and this went too long without extra info. I'm currently working on a PR to fix this, am just finishing up writing the testing. I plan to have it up in review by tomorrow at the latest. |
Still finishing up local testing of the other WindowInsetController behaviors, so I still have the pr in draft - will get the testing finished tomorrow and mark ready for review |
I've spent a while testing this change, and I'm no longer convinced that the current fix is the right one - In particular, I dont believe we can override I currently believe that the issue is that the fact that we called |
Updates from more investigation:
I've tried overriding the cc'ing @Piinks as I can see you've done a lot of work on android fullscreen related code - if you have any thoughts ways in which an add-to-app use case using a FlutterFragment and manipulating system ui component visibility directly could clash with how flutter deals with system ui component visibility, I'd appreciate it! Understand if you're not the right person to ask though :) |
Other things of note from testing:
Will also get a false window inset on dismissal of the keyboard.
From printing out the insets that are passed to onApplyWindowInsets, I can see that the "final state" that is passed in (and that we save, and apply in onEnd) has visible, full height navbars:
but insets that are passed to onProgress are animating towards 0:
which means that somehow the animation is receiving insets progressing towards a state that is different from the "final state" passed to onApplyWindowInsets. I'm still trying to find out why this is the case |
It looks like this problem is coming from the fact that when we dismiss the keyboard, we have two different animations: one corresponding to the keyboard, and one corresponding to the navigation bar. The key is that they run almost at the same time, but the keyboard animation starts a millisecond before the navbar animation. For context, the ImeSyncDeferringInsetsCallback works like this: for each animation that starts, we get a call to onPrepare with the animation, a call to onApplyWindowInsets with insets representing the post-animation state, and then calls to onStart, (multiple) onProgress, onEnd. So what happens in this case is that:
|
…ck (#42700) Fixes flutter/flutter#118761. For some context: ImeSyncDeferringInsetsCallback extends [WindowInsetsAnimation.Callback](https://developer.android.com/reference/android/view/WindowInsetsAnimation.Callback) specifically to handle insets related to keyboard animations. When a keyboard animation happens, we get a call to onPrepare with the animation, and then to onApplyWindowInsets with [WindowInsets](https://developer.android.com/reference/android/view/WindowInsets) that represent the post animation state. For example, for hiding the keyboard, we would get WindowInsets with height of 0 for insets of type WindowInsets.Type.ime() (input method editor). We save these post-animation insets. We then get calls to onProgress for each frame of the animation, and use the WindowInsets passed to onProgress to build new WindowInsets based on the saved post-animation insets, but with the keyboard insets overridden by the WindowInsets passed to onProgress. Finally, we get a call to onEnd, where we apply the saved insets. However, there can be multiple animation running at the same time. For example, dismissing the keyboard can result in an animation associated solely with the keyboard happening, as well as an animation associated only with the navigation bar happening. And they can start at slightly different times. This can result in the situation described in this comment: flutter/flutter#118761 (comment) Re-setting needsSave to false ensures we don't ignore any updates to the final state, ensuring correct insets in onProgress and onEnd. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of |
This issue appears on android api 30 and above. (pre api 30 takes a different path and uses a heuristic to set window metrics).
When setting that the app wants full screen behavior by using WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
The app will go fullscreen but then when keyboard is opened and closed the app incorrectly sets a window inset the size of the navigation bars even though there is no navigation bar.
Example screenshot showing the content in white and the background in red.
Original bug content "Extracting generic issue from b/258263557 where incorrect viewInsets were transiently being reported as the soft keyboard is being shown. "
The text was updated successfully, but these errors were encountered: