-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[Android] Fixed soft input inconsistency #32146
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -62,20 +62,6 @@ internal static SafeAreaRegions GetSafeAreaRegionForEdge(int edge, ICrossPlatfor | |||||||||||||
| var right = GetSafeAreaForEdge(GetSafeAreaRegionForEdge(2, layout), baseSafeArea.Right, 2, isKeyboardShowing, keyboardInsets); | ||||||||||||||
| var bottom = GetSafeAreaForEdge(GetSafeAreaRegionForEdge(3, layout), baseSafeArea.Bottom, 3, isKeyboardShowing, keyboardInsets); | ||||||||||||||
|
|
||||||||||||||
| if (isKeyboardShowing && | ||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does the new logic handle AdjustPan mode correctly without this check?, no longer necessary?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jsuarezruiz , The new approach uses
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When |
||||||||||||||
| context.GetActivity()?.Window is Window window && | ||||||||||||||
| window?.Attributes is WindowManagerLayoutParams attr) | ||||||||||||||
| { | ||||||||||||||
| // If the window is panned from the keyboard being open | ||||||||||||||
| // and there isn't a bottom inset to apply then just don't touch anything | ||||||||||||||
| var softInputMode = attr.SoftInputMode; | ||||||||||||||
| if (softInputMode == SoftInput.AdjustPan | ||||||||||||||
| && bottom == 0 | ||||||||||||||
| ) | ||||||||||||||
| { | ||||||||||||||
| return WindowInsetsCompat.Consumed; | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| var globalWindowInsetsListener = context.GetGlobalWindowInsetListener(); | ||||||||||||||
| bool hasTrackedViews = globalWindowInsetsListener?.HasTrackedView == true; | ||||||||||||||
|
|
@@ -237,7 +223,7 @@ internal static SafeAreaRegions GetSafeAreaRegionForEdge(int edge, ICrossPlatfor | |||||||||||||
| } | ||||||||||||||
| else | ||||||||||||||
| { | ||||||||||||||
| newWindowInsets = windowInsets; | ||||||||||||||
| newWindowInsets = windowInsets; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Fallback: return the base safe area for legacy views | ||||||||||||||
|
|
@@ -248,27 +234,28 @@ internal static double GetSafeAreaForEdge(SafeAreaRegions safeAreaRegion, double | |||||||||||||
| { | ||||||||||||||
| // Edge-to-edge content - no safe area padding | ||||||||||||||
| if (safeAreaRegion == SafeAreaRegions.None) | ||||||||||||||
| { | ||||||||||||||
| return 0; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // Handle SoftInput specifically - only apply keyboard insets for bottom edge when keyboard is showing | ||||||||||||||
| if (isKeyboardShowing && edge == 3) | ||||||||||||||
| // Handle SoftInput specifically for bottom edge when keyboard is showing | ||||||||||||||
| if (edge == 3 && SafeAreaEdges.IsSoftInput(safeAreaRegion)) | ||||||||||||||
| { | ||||||||||||||
| if (SafeAreaEdges.IsSoftInput(safeAreaRegion)) | ||||||||||||||
| return keyBoardInsets.Bottom; | ||||||||||||||
|
|
||||||||||||||
| // if they keyboard is showing then we will just return 0 for the bottom inset | ||||||||||||||
| // because that part of the view is covered by the keyboard so we don't want to pad the view | ||||||||||||||
| return 0; | ||||||||||||||
| return HandleSoftInputRegion(safeAreaRegion, originalSafeArea, isKeyboardShowing, keyBoardInsets); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| // All other regions respect safe area in some form | ||||||||||||||
| // This includes: | ||||||||||||||
| // - Default: Platform default behavior | ||||||||||||||
| // - All: Obey all safe area insets | ||||||||||||||
| // - Container: Content flows under keyboard but stays out of bars/notch | ||||||||||||||
| // - Any combination of the above flags | ||||||||||||||
| // All other regions respect safe area (Default, All, Container, etc.) | ||||||||||||||
| return originalSafeArea; | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| static double HandleSoftInputRegion(SafeAreaRegions safeAreaRegion, double originalSafeArea, bool isKeyboardShowing, SafeAreaPadding keyBoardInsets) | ||||||||||||||
| { | ||||||||||||||
| if (!isKeyboardShowing) | ||||||||||||||
| { | ||||||||||||||
| // When keyboard is hidden, only apply safe area for "All" regions | ||||||||||||||
| return safeAreaRegion == SafeAreaRegions.All ? originalSafeArea : 0; | ||||||||||||||
|
Comment on lines
+253
to
+254
|
||||||||||||||
| // When keyboard is hidden, only apply safe area for "All" regions | |
| return safeAreaRegion == SafeAreaRegions.All ? originalSafeArea : 0; | |
| // When keyboard is hidden, only apply safe area for regions that include "All" | |
| return (safeAreaRegion & SafeAreaRegions.All) != 0 ? originalSafeArea : 0; |
Copilot
AI
Oct 22, 2025
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 logic unconditionally returns the maximum of keyboard inset and original safe area for all SoftInput regions when the keyboard is showing, but this doesn't align with the original behavior. The previous code (line 242) returned keyBoardInsets.Bottom directly when SafeAreaRegion was SoftInput and keyboard was showing. Using Math.Max will always apply at least the original safe area padding even when SoftInput is set alone (without All), which changes the behavior. For SafeAreaRegions.SoftInput only (without All), it should return just the keyboard inset, not the maximum. Consider checking if All flag is present: return (safeAreaRegion & SafeAreaRegions.All) != 0 ? Math.Max(keyboardInset, originalSafeArea) : keyboardInset;
| // When keyboard is showing, use the larger of keyboard inset or original safe area | |
| var keyboardInset = keyBoardInsets.Bottom; | |
| return Math.Max(keyboardInset, originalSafeArea); | |
| // When keyboard is showing, use the larger of keyboard inset or original safe area only if "All" is present | |
| var keyboardInset = keyBoardInsets.Bottom; | |
| return (safeAreaRegion & SafeAreaRegions.All) != 0 ? Math.Max(keyboardInset, originalSafeArea) : keyboardInset; |
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.
Previously just returned keyboardInset. With floating/split keyboards, the keyboard inset might be smaller than the navigation bar safe area. Could verify?
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.
Why remove it? Still have sense to validate orientation changes, no?
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.
@jsuarezruiz , In Android Once the orientation is changed to Landscape, the input control and the keyboard occupies the entire screen, this will cause failure in the Rect lookup. The portrait soft input scenarios are already handled in other test files (SafeAreaPerEdgeValidation).
