Fix Android layout jump when navigating with IME open and NavBarIsVisible=false#34621
Fix Android layout jump when navigating with IME open and NavBarIsVisible=false#34621jpd21122012 wants to merge 2 commits intodotnet:mainfrom
Conversation
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34621Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34621" |
There was a problem hiding this comment.
Pull request overview
Fixes an Android Shell navigation layout jump when transitioning while the soft keyboard (IME) is visible—especially when navigating to destinations with Shell.NavBarIsVisible=false.
Changes:
- Dismisses the soft keyboard before committing the fragment transaction in
ShellRenderer.SwitchFragment. - Adds a HostApp repro page for issue #34584 (keyboard open → navigate to NavBar hidden page).
- Adds an Android UI test intended to validate the destination content is not laid out under the status bar.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cs | Attempts to hide IME before fragment replacement to stabilize insets/layout. |
| src/Controls/tests/TestCases.HostApp/Issues/Issue34584.cs | Adds a Shell-based repro page with an Entry + navigation to a NavBar-hidden destination. |
| src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34584.cs | Adds an Android UI test to verify final element Y-position is below the status bar after navigation. |
src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellRenderer.cs
Show resolved
Hide resolved
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue34584.cs
Outdated
Show resolved
Hide resolved
Update the test to trigger navigation from Entry.Completed instead of a button tap, ensuring the soft keyboard (IME) remains visible at the moment navigation occurs. This makes the test deterministic and accurately reproduces the original issue scenario.
🧪 PR Test EvaluationOverall Verdict: The test exercises the correct code path and the fix is Android-only with a matching platform guard, but the assertion is weak and there are minor issues (unused HostApp element, redundant null check, missing edge cases).
📊 Expand Full EvaluationPR Test Evaluation ReportPR: #34621 — Fix Android layout jump when navigating with IME open and NavBarIsVisible=false Overall VerdictThe test correctly exercises the fix's code path, but the assertion ( 1. Fix Coverage — ✅The fix calls 2. Edge Cases & Gaps —
|
## Summary Enables the copilot-evaluate-tests gh-aw workflow to run on fork PRs by adding `forks: ["*"]` to the `pull_request` trigger and removing the fork guard from `Checkout-GhAwPr.ps1`. ## Changes 1. **copilot-evaluate-tests.md**: Added `forks: ["*"]` to opt out of gh-aw auto-injected fork activation guard. Scoped `Checkout-GhAwPr.ps1` step to `workflow_dispatch` only (redundant for other triggers since platform handles checkout). 2. **copilot-evaluate-tests.lock.yml**: Recompiled via `gh aw compile` — fork guard removed from activation `if:` conditions. 3. **Checkout-GhAwPr.ps1**: Removed the `isCrossRepository` fork guard. Updated header docs and restore comments to accurately describe behavior for all trigger×fork combinations (including corrected step ordering). 4. **gh-aw-workflows.instructions.md**: Updated all stale references to the removed fork guard. Documented `forks: ["*"]` opt-in, clarified residual risk model for fork PRs, and updated troubleshooting table. ## Security Model Fork PRs are safe because: - Agent runs in **sandboxed container** with all credentials scrubbed - Output limited to **1 comment** via `safe-outputs: add-comment: max: 1` - Agent **prompt comes from base branch** (`runtime-import`) — forks cannot alter instructions - Pre-flight check catches missing `SKILL.md` if fork isn't rebased on `main` - No workspace code is executed with `GITHUB_TOKEN` (checkout without execution) ## Testing - ✅ `workflow_dispatch` tested against fork PR #34621 - ✅ Lock.yml statically verified — fork guard removed from `if:` conditions - ⏳ `pull_request` trigger on fork PRs can only be verified post-merge (GitHub Actions reads lock.yml from default branch) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Description
On Android, navigating from a page with the soft keyboard (IME) open to a page with
Shell.NavBarIsVisible="False"causes the destination page to initially render under the status bar and then jump into the correct position.This behavior is more noticeable when the destination page performs heavier UI work, and in some cases the layout may remain incorrectly positioned.
Root Cause
During
ShellRenderer.SwitchFragment, the fragment transaction is committed while the IME is still visible. Android continues to report IME-relatedWindowInsets, causing the new layout to be measured with incorrect top insets.Once the IME state stabilizes, the layout is corrected, resulting in a visible jump.
Fix
Dismiss the soft keyboard before performing the fragment transaction:
IsSoftInputShowingHideSoftInput()prior toFragmentTransactionThis ensures that
WindowInsetsare stable before the new layout is measured.Result
Testing
Added a UI test (
Issue34584) that:EntryShell.NavBarIsVisible="False"Y > 0)Note: The test validates final layout correctness, not visual animation.
Related Issues