Skip to content

Commit 5a4df7a

Browse files
Fixed softinput behavior
1 parent 68f5a7d commit 5a4df7a

File tree

4 files changed

+23
-145
lines changed

4 files changed

+23
-145
lines changed

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ public void SafeAreaMainGridSequentialButtonTesting()
9797
Assert.That(finalAllPosition.Y, Is.EqualTo(allPosition.Y), "Final All position should match initial All position");
9898
}
9999

100-
#if TEST_FAILS_ON_ANDROID
101100
[Test]
102101
[Category(UITestCategories.SafeAreaEdges)]
103102
public void SafeAreaPerEdgeValidation()
@@ -128,6 +127,5 @@ public void SafeAreaPerEdgeValidation()
128127
Assert.That(containerPositionWithoutSoftInput.Height, Is.EqualTo(containerPosition.Height), "ContentGrid height should return to original when Soft Input is dismissed with Container edges");
129128
});
130129
}
131-
#endif
132130
}
133131
#endif

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986_ContentPage.cs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ namespace Microsoft.Maui.TestCases.Tests.Issues;
77

88
public class Issue28986_ContentPage : _IssuesUITest
99
{
10-
public override string Issue => "Test SafeArea ContentPage for per-edge safe area control";
10+
public override string Issue => "Test SafeArea ContentPage for per-edge safe area control";
1111

12-
public Issue28986_ContentPage(TestDevice device) : base(device)
13-
{
14-
}
12+
public Issue28986_ContentPage(TestDevice device) : base(device)
13+
{
14+
}
1515

16-
[Test]
16+
[Test]
1717
[Category(UITestCategories.SafeAreaEdges)]
1818
public void SafeAreaMainGridBasicFunctionality()
1919
{
@@ -97,8 +97,6 @@ public void SafeAreaMainGridSequentialButtonTesting()
9797
Assert.That(finalAllPosition.Y, Is.EqualTo(allPosition.Y), "Final All position should match initial All position");
9898
}
9999

100-
101-
#if TEST_FAILS_ON_ANDROID
102100
[Test]
103101
[Category(UITestCategories.SafeAreaEdges)]
104102
public void SafeAreaPerEdgeValidation()
@@ -129,6 +127,5 @@ public void SafeAreaPerEdgeValidation()
129127
Assert.That(containerPositionWithoutSoftInput.Height, Is.EqualTo(containerPosition.Height), "ContentGrid height should return to original when Soft Input is dismissed with Container edges");
130128
});
131129
}
132-
#endif
133130
}
134131
#endif

src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue28986_SafeAreaBorderOrientation.cs

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ public void SafeAreaBorderMultipleOrientationChanges()
224224
"Dimensions should still differ between portrait and landscape after multiple changes");
225225
}
226226

227-
#if TEST_FAILS_ON_ANDROID
228227
[Test]
229228
[Category(UITestCategories.SafeAreaEdges)]
230229
public void SafeAreaBorderSoftInputBehavior()
@@ -320,116 +319,5 @@ public void SafeAreaBorderSoftInputBehavior()
320319
Assert.That(borderHeightChanged || safeAreaChanged, Is.True,
321320
"Test should demonstrate that keyboard interaction affects either safe area or border layout");
322321
}
323-
#endif
324-
325-
#if TEST_FAILS_ON_ANDROID // Landscape orientation causes keyboard to occupy fullview
326-
[Test]
327-
[Category(UITestCategories.SafeAreaEdges)]
328-
public void SafeAreaBorderSoftInputWithOrientationChange()
329-
{
330-
var borderContent = App.WaitForElement("BorderContent");
331-
332-
// 1. Set bottom edge to SoftInput mode for keyboard behavior
333-
App.Tap("SetBottomSoftInputButton");
334-
335-
// Wait for the test status to confirm the change
336-
var softInputSet = App.WaitForTextToBePresentInElement("TestStatus", "SoftInput", TimeSpan.FromSeconds(3));
337-
Assert.That(softInputSet, Is.True, "Bottom edge should be set to SoftInput mode");
338-
339-
// 2. Show keyboard in portrait mode
340-
App.Tap("TestEntry");
341-
342-
Thread.Sleep(1000);
343-
344-
Assert.That(App.IsKeyboardShown(), Is.True, "Keyboard should become visible in portrait mode");
345-
346-
// 3. Record portrait state with keyboard visible
347-
var portraitWithKeyboardBounds = borderContent.GetRect();
348-
var portraitWithKeyboardSafeArea = App.WaitForElement("SafeAreaInsets").GetText();
349-
350-
Assert.That(App.IsKeyboardShown(), Is.True, "IsKeyboardShown should confirm keyboard is visible");
351-
352-
// Verify we start in portrait with keyboard
353-
Assert.That(portraitWithKeyboardBounds.Height, Is.GreaterThan(portraitWithKeyboardBounds.Width * 0.6),
354-
"Should be in portrait orientation even with keyboard visible");
355-
356-
// 4. Change orientation to landscape while keyboard is still visible
357-
App.SetOrientationLandscape();
358-
Thread.Sleep(2000); // Wait for orientation change and layout to settle
359-
360-
// 5. Record landscape state with keyboard visible
361-
var landscapeWithKeyboardBounds = borderContent.GetRect();
362-
var landscapeWithKeyboardSafeArea = App.WaitForElement("SafeAreaInsets").GetText();
363-
364-
Assert.That(App.IsKeyboardShown(), Is.True, "Keyboard should remain visible after orientation change");
365-
366-
// Verify orientation changed to landscape
367-
Assert.That(landscapeWithKeyboardBounds.Width, Is.GreaterThan(landscapeWithKeyboardBounds.Height * 0.6),
368-
"Should now be in landscape orientation with keyboard visible");
369-
370-
// 6. Verify border maintains visibility in landscape with keyboard
371-
Assert.That(landscapeWithKeyboardBounds.Width, Is.GreaterThan(0),
372-
"Border should remain visible in landscape with keyboard");
373-
Assert.That(landscapeWithKeyboardBounds.Height, Is.GreaterThan(0),
374-
"Border should remain visible in landscape with keyboard");
375-
376-
// 7. Verify dimensions differ between orientations even with keyboard visible
377-
Assert.That(portraitWithKeyboardBounds.Width, Is.Not.EqualTo(landscapeWithKeyboardBounds.Width).Within(10),
378-
"Border width should differ between portrait and landscape with keyboard visible");
379-
Assert.That(portraitWithKeyboardBounds.Height, Is.Not.EqualTo(landscapeWithKeyboardBounds.Height).Within(10),
380-
"Border height should differ between portrait and landscape with keyboard visible");
381-
382-
// 8. Verify landscape has wider aspect ratio even with keyboard
383-
var portraitAspectRatio = portraitWithKeyboardBounds.Height / portraitWithKeyboardBounds.Width;
384-
var landscapeAspectRatio = landscapeWithKeyboardBounds.Height / landscapeWithKeyboardBounds.Width;
385-
386-
Assert.That(portraitAspectRatio, Is.GreaterThan(landscapeAspectRatio),
387-
"Portrait should still have higher aspect ratio than landscape, even with keyboard visible");
388-
389-
// 9. Verify safe area insets adapted to landscape with keyboard
390-
Assert.That(portraitWithKeyboardSafeArea, Is.Not.EqualTo(landscapeWithKeyboardSafeArea),
391-
"Safe area insets should be different between portrait and landscape with keyboard");
392-
393-
// 10. Hide keyboard in landscape mode using proper dismiss method
394-
App.DismissKeyboard();
395-
Thread.Sleep(1000);
396-
397-
Assert.That(App.IsKeyboardShown(), Is.False, "Keyboard should be hidden in landscape mode");
398-
399-
// 11. Record landscape state with keyboard hidden
400-
var landscapeWithoutKeyboardBounds = borderContent.GetRect();
401-
402-
Assert.That(App.IsKeyboardShown(), Is.False, "IsKeyboardShown should confirm keyboard is hidden");
403-
404-
// 12. Verify border expanded when keyboard was dismissed in landscape
405-
Assert.That(landscapeWithoutKeyboardBounds.Height, Is.GreaterThan(landscapeWithKeyboardBounds.Height),
406-
"Border should expand when keyboard is hidden in landscape mode");
407-
408-
// 13. Change back to portrait without keyboard
409-
App.SetOrientationPortrait();
410-
Thread.Sleep(2000); // Wait for orientation change and layout to settle
411-
412-
// 14. Record final portrait state without keyboard
413-
var finalPortraitBounds = borderContent.GetRect();
414-
415-
// Verify back in portrait
416-
Assert.That(finalPortraitBounds.Height, Is.GreaterThan(finalPortraitBounds.Width * 0.8),
417-
"Should be back in portrait orientation");
418-
419-
// 15. Verify overall stability - border should be functional in final state
420-
Assert.That(finalPortraitBounds.Width, Is.GreaterThan(0),
421-
"Border should be visible in final portrait state");
422-
Assert.That(finalPortraitBounds.Height, Is.GreaterThan(0),
423-
"Border should be visible in final portrait state");
424-
425-
// 16. Verify no errors occurred during complex interaction
426-
var testStatus = App.WaitForElement("TestStatus");
427-
Assert.That(testStatus.GetText(), Does.Not.Contain("Error"),
428-
"No errors should occur during orientation change with keyboard interaction");
429-
430-
// 17. Verify final state is stable (keyboard hidden)
431-
Assert.That(App.IsKeyboardShown(), Is.False, "Keyboard should remain hidden in final state");
432-
}
433-
#endif
434322
}
435323
#endif

src/Core/src/Platform/Android/SafeAreaExtensions.cs

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ internal static SafeAreaRegions GetSafeAreaRegionForEdge(int edge, ICrossPlatfor
223223
}
224224
else
225225
{
226-
newWindowInsets = windowInsets;
226+
newWindowInsets = windowInsets;
227227
}
228228

229229
// Fallback: return the base safe area for legacy views
@@ -234,33 +234,28 @@ internal static double GetSafeAreaForEdge(SafeAreaRegions safeAreaRegion, double
234234
{
235235
// Edge-to-edge content - no safe area padding
236236
if (safeAreaRegion == SafeAreaRegions.None)
237-
{
238237
return 0;
239-
}
240238

241-
// Handle SoftInput specifically - only apply keyboard insets for bottom edge when keyboard is showing
242-
if (isKeyboardShowing && edge == 3)
239+
// Handle SoftInput specifically for bottom edge when keyboard is showing
240+
if (edge == 3 && SafeAreaEdges.IsSoftInput(safeAreaRegion))
243241
{
244-
// Always apply keyboard insets when keyboard is showing to prevent content overlap
245-
// Use keyboard height or original safe area, whichever is larger
246-
var keyboardInset = keyBoardInsets.Bottom;
247-
if (SafeAreaEdges.IsSoftInput(safeAreaRegion))
248-
return Math.Max(keyboardInset, originalSafeArea);
249-
250-
// For non-SoftInput regions, still apply keyboard padding to prevent overlap
251-
// unless explicitly set to None region
252-
if (safeAreaRegion != SafeAreaRegions.None)
253-
return Math.Max(keyboardInset, originalSafeArea);
254-
255-
return keyboardInset;
242+
return HandleSoftInputRegion(safeAreaRegion, originalSafeArea, isKeyboardShowing, keyBoardInsets);
256243
}
257244

258-
// All other regions respect safe area in some form
259-
// This includes:
260-
// - Default: Platform default behavior
261-
// - All: Obey all safe area insets
262-
// - Container: Content flows under keyboard but stays out of bars/notch
263-
// - Any combination of the above flags
245+
// All other regions respect safe area (Default, All, Container, etc.)
264246
return originalSafeArea;
265247
}
248+
249+
static double HandleSoftInputRegion(SafeAreaRegions safeAreaRegion, double originalSafeArea, bool isKeyboardShowing, SafeAreaPadding keyBoardInsets)
250+
{
251+
if (!isKeyboardShowing)
252+
{
253+
// When keyboard is hidden, only apply safe area for "All" regions
254+
return safeAreaRegion == SafeAreaRegions.All ? originalSafeArea : 0;
255+
}
256+
257+
// When keyboard is showing, use the larger of keyboard inset or original safe area
258+
var keyboardInset = keyBoardInsets.Bottom;
259+
return Math.Max(keyboardInset, originalSafeArea);
260+
}
266261
}

0 commit comments

Comments
 (0)