-
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: net10.0
Are you sure you want to change the base?
Conversation
|
Hey there @@NirmalKumarYuvaraj! Thank you so much for your PR! Someone from the team will get assigned to your PR shortly and we'll get it reviewed. |
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.
Pull Request Overview
This PR fixes inconsistent soft input handling on Android by refactoring the safe area logic and re-enabling previously failing tests. The changes simplify keyboard inset calculations and remove Android-specific test exclusions that are now passing.
Key Changes
- Refactored
SafeAreaExtensions.csto remove theSoftInput.AdjustPanspecial case and introduce a clearerHandleSoftInputRegionmethod for calculating bottom safe areas when the keyboard is visible - Removed
#if TEST_FAILS_ON_ANDROIDpreprocessor directives from three test files (Issue28986.cs,Issue28986_ContentPage.cs,Issue28986_SafeAreaBorderOrientation.cs), enabling previously skipped tests to run on Android - Deleted one entire test method (
SafeAreaBorderSoftInputWithOrientationChange) that was previously excluded on Android
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/Core/src/Platform/Android/SafeAreaExtensions.cs |
Refactored safe area calculation logic by removing AdjustPan special case and introducing HandleSoftInputRegion helper method |
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986_SafeAreaBorderOrientation.cs |
Removed Android test exclusion directives and deleted SafeAreaBorderSoftInputWithOrientationChange test |
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986_ContentPage.cs |
Removed Android test exclusion directives for SafeAreaPerEdgeValidation test |
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986.cs |
Removed Android test exclusion directives for SafeAreaPerEdgeValidation test |
| // When keyboard is hidden, only apply safe area for "All" regions | ||
| return safeAreaRegion == SafeAreaRegions.All ? 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.
The logic for when the keyboard is hidden appears incorrect. When safeAreaRegion is SafeAreaRegions.SoftInput and the keyboard is hidden, this returns 0. However, according to the previous logic (line 242 in the old code), when the keyboard is not showing for bottom edge SoftInput, it should return 0, which matches. But this new implementation doesn't account for other safe area region combinations that include SoftInput flag. The check safeAreaRegion == SafeAreaRegions.All is too restrictive - it won't apply safe area for combinations like SafeAreaRegions.All | SafeAreaRegions.SoftInput or other valid flag combinations. Consider using SafeAreaEdges.HasFlag pattern or checking if the region includes the All flag: return (safeAreaRegion & SafeAreaRegions.All) != 0 ? originalSafeArea : 0;
| // 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 uses AI. Check for mistakes.
| // When keyboard is showing, use the larger of keyboard inset or original safe area | ||
| var keyboardInset = keyBoardInsets.Bottom; | ||
| return Math.Max(keyboardInset, originalSafeArea); |
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; |
Copilot uses AI. Check for mistakes.
|
/azp run MAUI-UITests-public |
|
Azure Pipelines successfully started running 1 pipeline(s). |
| var right = GetSafeAreaForEdge(GetSafeAreaRegionForEdge(2, layout), baseSafeArea.Right, 2, isKeyboardShowing, keyboardInsets); | ||
| var bottom = GetSafeAreaForEdge(GetSafeAreaRegionForEdge(3, layout), baseSafeArea.Bottom, 3, isKeyboardShowing, keyboardInsets); | ||
|
|
||
| if (isKeyboardShowing && |
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.
How does the new logic handle AdjustPan mode correctly without this check?, no longer necessary?
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 , The new approach uses SafeAreaRegions flags to determine if SoftInput should be handled, making it more flexible and declarative rather than checking the window's SoftInput mode directly.
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 SafeAreaRegions.SoftInput is not set for the bottom edge, GetSafeAreaForEdge will return the original safe area or 0, effectively achieving the same result as the AdjustPan check but in a more systematic way.
|
|
||
| // When keyboard is showing, use the larger of keyboard inset or original safe area | ||
| var keyboardInset = keyBoardInsets.Bottom; | ||
| return Math.Max(keyboardInset, originalSafeArea); |
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?
| #if TEST_FAILS_ON_ANDROID // Landscape orientation causes keyboard to occupy fullview | ||
| [Test] | ||
| [Category(UITestCategories.SafeAreaEdges)] | ||
| public void SafeAreaBorderSoftInputWithOrientationChange() |
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).

Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description of Change
This pull request primarily removes Android-specific test exclusion directives (
#if TEST_FAILS_ON_ANDROIDand related#endif) from several test files, making previously excluded tests run on Android. Additionally, it refactors the safe area logic for handling keyboard insets on Android, simplifying and improving the calculation for the bottom edge when the keyboard is visible.Test coverage improvements:
#if TEST_FAILS_ON_ANDROIDpreprocessor directives fromIssue28986.cs,Issue28986_ContentPage.cs, andIssue28986_SafeAreaBorderOrientation.cs, enabling tests that were previously skipped on Android to now run on that platform. [1] [2] [3] [4] [5] [6]Safe area logic refactoring:
SafeAreaExtensions.csby removing a special case forSoftInput.AdjustPanand refactoring how the bottom safe area is calculated when the keyboard is showing, delegating to a new helper method for clarity and correctness. [1] [2]HandleSoftInputRegionhelper method to ensure the bottom safe area uses the larger of the keyboard inset or the original safe area when the keyboard is visible, and applies safe area only for "All" regions when the keyboard is hidden.Issues Fixed
Fixes #
Output
Before.mov
After.mov