Skip to content

Fix content page title clipping on Android API < 30 with window insets compatibility#32537

Merged
PureWeen merged 15 commits intomainfrom
copilot/fix-shell-content-page-title
Nov 19, 2025
Merged

Fix content page title clipping on Android API < 30 with window insets compatibility#32537
PureWeen merged 15 commits intomainfrom
copilot/fix-shell-content-page-title

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 12, 2025

Fix Window Insets on Android API < 30 (NavigationPage and Shell)

Description

This PR addresses window insets issues on Android versions below API 30 (Android 11) affecting both Shell and NavigationPage navigation. The fix implements Google's workaround for the inset dispatch bug present in Android API 28 and API 29.

Title clipping issue on Android API 28

Changes Made

1. NavigationRootManager.cs

Added ViewGroupCompat.InstallCompatInsetsDispatch() for API < 30 to ensure window insets are properly dispatched to all children recursively. This implements Google's workaround for the inset dispatch bug where one child consuming insets blocks all siblings from receiving them.

Issue: On Android API < 30, when one view consumes window insets, sibling views don't receive them, causing content to be clipped by system UI (status bar, navigation bar, etc.). This affects both Shell navigation and NavigationPage with hidden navigation bars.

Defensive Programming: Added null check and logging for _rootView to help with future debugging and prevent potential null reference exceptions. Uses _mauiContext?.CreateLogger<NavigationRootManager>()?.LogWarning() with the proper Microsoft.Extensions.Logging using directive for logging integration.

if(!OperatingSystem.IsAndroidVersionAtLeast(30))
{
    // Dispatches insets to all children recursively (for API < 30)
    // This implements Google's workaround for the API 28-29 inset dispatch bug
    // where one child consuming insets blocks all siblings from receiving them.
    // Based on: https://android-review.googlesource.com/c/platform/frameworks/support/+/3310617
    if (_rootView is null)
    {
        _mauiContext?.CreateLogger<NavigationRootManager>()?.LogWarning(
            "NavigationRootManager: _rootView is null when attempting to install compat insets dispatch. " +
            "This may cause incorrect window insets behavior on API < 30.");
    }
    else
    {
        ViewGroupCompat.InstallCompatInsetsDispatch(_rootView);
    }
}

2. Test Case (Issue32526)

  • Creates a Shell application with navigation between pages
  • Navigates to a new page using Navigation.PushAsync()
  • Verifies content positioning by comparing top label positions on both pages
  • Ensures labels are positioned below the toolbar (not clipped)
  • Includes assertions to verify correct Y positioning

Affected Android Versions

  • Android 9 (API 28) - Pie
  • Android 10 (API 29) - Q
  • All versions below API 30

Affected Scenarios

  • Shell navigation: Title and back button clipping on navigated pages
  • NavigationPage with hidden nav bar: Top and bottom content clipping

Issues Fixed

Fixes #32526


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Fix incorrect title position on shell content page Fix Shell content page title clipping on Android by defaulting to Container safe area Nov 12, 2025
Copilot AI requested a review from PureWeen November 12, 2025 19:16
@PureWeen PureWeen force-pushed the copilot/fix-shell-content-page-title branch from 4d98c30 to d95b336 Compare November 12, 2025 22:33
@PureWeen
Copy link
Copy Markdown
Member

@copilot can you update the description based on your changes?

The initial changes you made were wrong

Copy link
Copy Markdown
Member

@mattleibow mattleibow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot please fix.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Nov 12, 2025

@copilot can you update the description based on your changes?

The initial changes you made were wrong

Updated PR description to reflect the actual fix. The solution addresses API 28-29 compatibility in MauiWindowInsetListener.cs by using legacy SystemWindowInsets for older Android versions, rather than modifying ContentPage behavior.

Commit: d95b336

Copilot AI changed the title Fix Shell content page title clipping on Android by defaulting to Container safe area Fix Shell content page title clipping on Android API 28-29 with window insets compatibility Nov 12, 2025
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Nov 12, 2025

@copilot please fix.

Fixed the API version check as requested.

Commit: 6585f55

Copilot AI requested a review from mattleibow November 12, 2025 23:05
@PureWeen PureWeen force-pushed the copilot/fix-shell-content-page-title branch from 284e2e9 to 6380231 Compare November 12, 2025 23:29
@PureWeen PureWeen marked this pull request as ready for review November 13, 2025 23:18
Copilot AI review requested due to automatic review settings November 13, 2025 23:18
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 Shell content page title clipping on Android API 28-29 by adding API level fallback logic for window insets retrieval. The issue occurred because WindowInsetsCompat.Type.SystemBars() and WindowInsetsCompat.Type.DisplayCutout() APIs were introduced in API 30, causing incorrect toolbar positioning on older devices.

Key changes:

  • Added API level detection in MauiWindowInsetListener.cs to use deprecated SystemWindowInsets for API 28-29
  • Implemented Google's workaround for API 28-29 inset dispatch bug with recursive child propagation
  • Added NavigationAreaInsetListener in ShellItemRenderer for API 28-29 bottom navigation handling
  • Created UI test (Issue32278) to verify content positioning across navigation

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/Core/src/Platform/Android/MauiWindowInsetListener.cs Added API 28-29 fallback logic for window insets retrieval using deprecated SystemWindowInsets property and recursive inset dispatch workaround
src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellPageContainer.cs Added BoopContainer debug class and OnApplyWindowInsets override (appears to be temporary debug code)
src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellContentFragment.cs Changed to use BoopContainer instead of ShellPageContainer (likely debug code)
src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellItemRenderer.cs Added NavigationAreaInsetListener for API 28-29 to dispatch insets to navigation area children
src/Controls/tests/TestCases.HostApp/Issues/Issue32278.xaml.cs Added UI test page with Shell navigation to verify content positioning
src/Controls/tests/TestCases.HostApp/Issues/Issue32278.xaml XAML definition for Issue32278 Shell test
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue32278.cs NUnit test implementation to verify toolbar doesn't clip content
.vscode/settings.json Changed default solution from .slnx to .slnf (unrelated local config change)
.github/instructions/common-testing-patterns.md Added Android emulator startup documentation

Comment on lines +73 to +76
public override WindowInsets OnApplyWindowInsets(WindowInsets insets)
{
return base.OnApplyWindowInsets(insets);
}
Copy link

Copilot AI Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OnApplyWindowInsets override in the base ShellPageContainer class only calls the base implementation without adding any functionality. This appears to be debug/development code.

Recommendation: Remove this override unless there's a specific reason it's needed. If it's for debugging purposes, it should be removed before merging. Empty overrides that just call base add no value and create maintenance burden.

Suggested change
public override WindowInsets OnApplyWindowInsets(WindowInsets insets)
{
return base.OnApplyWindowInsets(insets);
}

Copilot uses AI. Check for mistakes.
@@ -1,3 +1,3 @@
{
"dotnet.defaultSolution": "Microsoft.Maui-vscode.slnx"
"dotnet.defaultSolution": "Microsoft.Maui-vscode.slnf"
Copy link

Copilot AI Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The VS Code settings change from .slnx to .slnf appears to be an unintended local configuration change that should not be committed.

Issue: This changes the default solution file for all developers, which is unrelated to fixing the Shell title clipping issue.

Recommendation: Revert this change. Personal IDE settings should not be committed unless they're intentional improvements documented in the PR.

Suggested change
"dotnet.defaultSolution": "Microsoft.Maui-vscode.slnf"
"dotnet.defaultSolution": "Microsoft.Maui.slnx"

Copilot uses AI. Check for mistakes.
var returnValue = ApplyDefaultWindowInsets(v, insets);

// For API < 30 and CoordinatorLayout only, apply Google's workaround to dispatch to all children
if ((int)global::Android.OS.Build.VERSION.SdkInt < 30 && v is CoordinatorLayout coordinatorLayout)
Copy link

Copilot AI Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using (int)global::Android.OS.Build.VERSION.SdkInt < 30 for API level checking is inconsistent with the approach used elsewhere in this method.

Issue: Line 277 uses OperatingSystem.IsAndroidVersionAtLeast(30) while line 214 uses (int)global::Android.OS.Build.VERSION.SdkInt < 30. These should use the same approach for consistency.

Recommendation: Use !OperatingSystem.IsAndroidVersionAtLeast(30) for consistency:

if (!OperatingSystem.IsAndroidVersionAtLeast(30) && v is CoordinatorLayout coordinatorLayout)

This matches the pattern used in line 277 and improves code consistency.

Suggested change
if ((int)global::Android.OS.Build.VERSION.SdkInt < 30 && v is CoordinatorLayout coordinatorLayout)
if (!OperatingSystem.IsAndroidVersionAtLeast(30) && v is CoordinatorLayout coordinatorLayout)

Copilot uses AI. Check for mistakes.
void SetupNavigationAreaInsetListener()
{
// Only set up listener for API 28-29
if ((int)global::Android.OS.Build.VERSION.SdkInt >= 30)
Copy link

Copilot AI Nov 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using (int)global::Android.OS.Build.VERSION.SdkInt >= 30 for API level checking is inconsistent with the approach used in MauiWindowInsetListener.cs.

Issue: The main fix in MauiWindowInsetListener.cs (line 277) uses OperatingSystem.IsAndroidVersionAtLeast(30) for API level detection, but this code uses a different pattern.

Recommendation: Use OperatingSystem.IsAndroidVersionAtLeast(30) for consistency:

if (OperatingSystem.IsAndroidVersionAtLeast(30))
    return;

This improves consistency across the codebase and follows the same pattern established in the core fix.

Suggested change
if ((int)global::Android.OS.Build.VERSION.SdkInt >= 30)
if (OperatingSystem.IsAndroidVersionAtLeast(30))

Copilot uses AI. Check for mistakes.
@PureWeen PureWeen force-pushed the copilot/fix-shell-content-page-title branch from ee47698 to 744f41c Compare November 14, 2025 00:19
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot revert all changes to this file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted all changes to ShellContentFragment.cs.

Commit: 7f519a3

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot revert all changes to this file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted all changes to ShellItemRenderer.cs.

Commit: 7f519a3

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot revert all changes to this file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reverted all changes to ShellPageContainer.cs.

Commit: 7f519a3

@sheiksyedm sheiksyedm force-pushed the copilot/fix-shell-content-page-title branch from e53c414 to 5d7a751 Compare November 19, 2025 10:33
@sheiksyedm
Copy link
Copy Markdown
Contributor

/azp run

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 3 pipeline(s).

@IeuanWalker
Copy link
Copy Markdown

IeuanWalker commented Nov 19, 2025

@PureWeen Is this just for shell?

Im seeing the same issue on android 9 using NavigationPage not shell, with the nav bar hidden -
(top and bottom of the page gets cut off)
image

@PureWeen
Copy link
Copy Markdown
Member

@PureWeen Is this just for shell?

Im seeing the same issue on android 9 using NavigationPage not shell, with the nav bar hidden - (top and bottom of the page gets cut off) image

no it's for navigationpage and shell

I need to fix the title
Or tell copilot to :-)

did you test the nugets?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot revert changes to this file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to this file were already reverted in commit fe1649f.

@PureWeen
Copy link
Copy Markdown
Member

@copilot can you update the description and title of this PR to better reflect the changes?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Nov 19, 2025

@copilot can you update the description and title of this PR to better reflect the changes?

Updated PR title and description to accurately reflect that the fix addresses window insets issues for both NavigationPage and Shell on Android API 28-29, not just Shell-specific title clipping.

The fix implements Google's workaround for the API 28-29 inset dispatch bug that affects both navigation modes when system UI elements (status bar, navigation bar) clip page content.

@IeuanWalker
Copy link
Copy Markdown

thanks @PureWeen, will give it a test tomorrow

@PureWeen PureWeen changed the title Fix Shell content page title clipping on Android API 28-29 with window insets compatibility Fix content page title clipping on Android API < 30 with window insets compatibility Nov 19, 2025
@PureWeen
Copy link
Copy Markdown
Member

@copilot this pr fixes all apis lower than 30

Please update title and description

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Nov 19, 2025

@copilot this pr fixes all apis lower than 30

Please update title and description

Updated the PR title to "Fix content page title clipping on Android API < 30 with window insets compatibility" and revised the description to clearly indicate the fix applies to all Android versions below API 30 (including API 28 and API 29).

@PureWeen PureWeen moved this from Changes Requested to Approved in MAUI SDK Ongoing Nov 19, 2025
@PureWeen
Copy link
Copy Markdown
Member

  • macOS failures unrelated

@PureWeen PureWeen merged commit cf7d7af into main Nov 19, 2025
164 of 168 checks passed
@PureWeen PureWeen deleted the copilot/fix-shell-content-page-title branch November 19, 2025 21:28
@github-project-automation github-project-automation bot moved this from Approved to Done in MAUI SDK Ongoing Nov 19, 2025
@IeuanWalker
Copy link
Copy Markdown

@PureWeen just tested the PR and all looks good, thanks

@PureWeen
Copy link
Copy Markdown
Member

@PureWeen just tested the PR and all looks good, thanks

amazing! Thank you for testing

@PureWeen PureWeen added the area-safearea Issues/PRs that have to do with the SafeArea functionality label Dec 16, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Jan 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-safearea Issues/PRs that have to do with the SafeArea functionality partner/syncfusion/review

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Shell content page title position incorrect/clipped

7 participants