[iOS] Fix Shell long-press back button not triggering navigation events#33380
Conversation
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
✅ Agent Review: APPROVEAutomated review completed. This PR correctly fixes the test regression by restoring the 📊 Phase Status
🔍 Root Cause AnalysisTimeline of Changes1. PR #24003 (Feb 2025) - Original fix for #23892
2. PR #29825 (Jul 2025) - Fix for tab blank issue
3. PR #32456 (Jan 2026) - Fix for navigation hang
The Core ProblemiOS Shell has two navigation types that need different handling:
PR #29825 broke this by removing the mechanism to distinguish between them. This PR's SolutionRestores the bool DidPopItem(...)
{
// User-initiated → delegate to SendPop() (fires events)
if (!_popRequested)
return SendPop();
// Programmatic → manual sync (preserves PR #29825 logic)
[... null checks and manual synchronization ...]
}🧪 Test Verification✅ Gate Verification: PASSEDWITHOUT fix (current ✅ Issue successfully reproduced WITH fix (PR #33380 applied): ✅ Fix successfully resolves the issue Test Coverage
⚖️ Comparison & AssessmentWhy This Approach is Optimal
Alternative Approaches (Rejected)
🔬 Regression AnalysisEdge Cases Verified✅ Long-press navigation (#23892) - Test confirms fixed No Regressions Expected
📝 SummaryThis PR:
Recommendation: APPROVE and merge ✅ Review generated by GitHub Copilot CLI PR Agent |
|
/azp run maui-pr-uitests |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
PureWeen
left a comment
There was a problem hiding this comment.
Can you review the suggested changes in the agent-pr-session
97b0833 to
4acaf62
Compare
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
The PR has been updated to implement a simpler approach for stack sync detection, resulting in a net reduction of 49 lines of code. The simpler method removes unnecessary complexity while maintaining functionality and passing all tests.
|
/azp run |
|
Azure Pipelines successfully started running 2 pipeline(s). |
4d73f0a to
8eab1e5
Compare
…s navigation The test was failing because PR dotnet#32456 removed the _popRequested flag and logic that was originally added in PR dotnet#24003 to fix issue dotnet#23892 (long-press back button navigation not updating Shell's current page). Later, PR dotnet#29825 expanded the DidPopItem method with null checks and manual synchronization, but removed the _popRequested flag handling. This commit restores the _popRequested logic while keeping the null checks: - For user-initiated navigation (_popRequested == false), call SendPop() which triggers GoToAsync and properly fires navigation events - For programmatic navigation (_popRequested == true), use manual synchronization with null checks to prevent crashes Also fixes ElementForViewController to properly handle null ViewControllers by avoiding property pattern matching that requires non-null values. Fixes dotnet#33379
Replace _popRequested flag approach with simpler stateless detection: - Check if Shell stack and iOS stack are in sync - In sync = programmatic navigation (Shell already updated) - Out of sync = user-initiated navigation (iOS popped directly) Benefits over previous approach: - No state tracking needed (removes _popRequested field) - Removes 17 lines of manual stack sync code - Simpler logic that's easier to maintain Tests passing: - Issue23892 (long-press navigation) - Issue29798 (tab blank scenario) - Issue21119 (Shell navigation) Fixes dotnet#33379
The PR has been updated to implement a simpler approach for stack sync detection, resulting in a net reduction of 49 lines of code. The simpler method removes unnecessary complexity while maintaining functionality and passing all tests.
77aead4 to
dfd1613
Compare
|
@sheiksyedm Great question! I investigated this concern and can confirm the PR does NOT regress Issue #29798. VerificationI ran the Why the Simplified Approach Works for Both ScenariosThe key insight is that the simplified stack-sync detection handles both issues correctly:
The About the PR DescriptionYou're right that the description mentions "restoring |
|
/azp run maui-pr-uitests |
|
Azure Pipelines could not run because the pipeline triggers exclude this branch/path. |
|
/azp run maui-pr-devicetests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
@sheiksyedm Thanks! I didn't update the description after I've committed the agent's suggestions |
<!-- Please let the below note in for people that find this PR --> > [!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](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ## Description The `maui-pr-uitests` pipeline was not running for PRs targeting `inflight/*` branches because they were not included in the trigger configuration. This was discovered in PR #33380 where `/azp run maui-pr-uitests` returned: > Azure Pipelines could not run because the pipeline triggers exclude this branch/path. ## Changes Added `inflight/*` to both `trigger:` and `pr:` branch includes in `eng/pipelines/ci-uitests.yml`, matching what `ci-device-tests.yml` already has. ## Related - Unblocks: #33380
…ts (#33380) ### Description of Change Fixes long-press back button navigation not triggering `OnAppearing` and other navigation events in Shell. **Problem:** Test expected `OnAppearing count: 2`, got `OnAppearing count: 1` **Root cause:** PR #29825 replaced `SendPop()` with manual stack synchronization (`SyncStackDownTo()`), which doesn't trigger navigation events. **Fix:** Simplified `DidPopItem` to use stack-sync detection: - Stacks in sync → Shell already handled pop → return early - Stacks out of sync → user-initiated (long-press) → call `SendPop()` **Key insight:** Tab tap updates Shell's stack BEFORE `DidPopItem` is called, but iOS long-press pops directly without notifying Shell first. **Regression chain:** | PR | What happened | |-----|---------------| | #24003 | Fixed #23892 with `_popRequested` flag | | #29825 | Removed flag, added `SyncStackDownTo()` - **broke long-press** | | #32456 | Added null checks, maintained broken state | | #33380 | **This PR** - simplified fix using stack-sync detection | **Removed:** `SyncStackDownTo()` method (44 lines) **What to avoid:** Don't remove stack count comparison - distinguishes user vs programmatic navigation. ### Issues Fixed Fixes #33379 **Related:** #23892, #29798 (verified not regressed ✅) --------- Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…ts (#33380) ### Description of Change Fixes long-press back button navigation not triggering `OnAppearing` and other navigation events in Shell. **Problem:** Test expected `OnAppearing count: 2`, got `OnAppearing count: 1` **Root cause:** PR #29825 replaced `SendPop()` with manual stack synchronization (`SyncStackDownTo()`), which doesn't trigger navigation events. **Fix:** Simplified `DidPopItem` to use stack-sync detection: - Stacks in sync → Shell already handled pop → return early - Stacks out of sync → user-initiated (long-press) → call `SendPop()` **Key insight:** Tab tap updates Shell's stack BEFORE `DidPopItem` is called, but iOS long-press pops directly without notifying Shell first. **Regression chain:** | PR | What happened | |-----|---------------| | #24003 | Fixed #23892 with `_popRequested` flag | | #29825 | Removed flag, added `SyncStackDownTo()` - **broke long-press** | | #32456 | Added null checks, maintained broken state | | #33380 | **This PR** - simplified fix using stack-sync detection | **Removed:** `SyncStackDownTo()` method (44 lines) **What to avoid:** Don't remove stack count comparison - distinguishes user vs programmatic navigation. ### Issues Fixed Fixes #33379 **Related:** #23892, #29798 (verified not regressed ✅) --------- Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…ts (#33380) ### Description of Change Fixes long-press back button navigation not triggering `OnAppearing` and other navigation events in Shell. **Problem:** Test expected `OnAppearing count: 2`, got `OnAppearing count: 1` **Root cause:** PR #29825 replaced `SendPop()` with manual stack synchronization (`SyncStackDownTo()`), which doesn't trigger navigation events. **Fix:** Simplified `DidPopItem` to use stack-sync detection: - Stacks in sync → Shell already handled pop → return early - Stacks out of sync → user-initiated (long-press) → call `SendPop()` **Key insight:** Tab tap updates Shell's stack BEFORE `DidPopItem` is called, but iOS long-press pops directly without notifying Shell first. **Regression chain:** | PR | What happened | |-----|---------------| | #24003 | Fixed #23892 with `_popRequested` flag | | #29825 | Removed flag, added `SyncStackDownTo()` - **broke long-press** | | #32456 | Added null checks, maintained broken state | | #33380 | **This PR** - simplified fix using stack-sync detection | **Removed:** `SyncStackDownTo()` method (44 lines) **What to avoid:** Don't remove stack count comparison - distinguishes user vs programmatic navigation. ### Issues Fixed Fixes #33379 **Related:** #23892, #29798 (verified not regressed ✅) --------- Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
…ts (dotnet#33380) ### Description of Change Fixes long-press back button navigation not triggering `OnAppearing` and other navigation events in Shell. **Problem:** Test expected `OnAppearing count: 2`, got `OnAppearing count: 1` **Root cause:** PR dotnet#29825 replaced `SendPop()` with manual stack synchronization (`SyncStackDownTo()`), which doesn't trigger navigation events. **Fix:** Simplified `DidPopItem` to use stack-sync detection: - Stacks in sync → Shell already handled pop → return early - Stacks out of sync → user-initiated (long-press) → call `SendPop()` **Key insight:** Tab tap updates Shell's stack BEFORE `DidPopItem` is called, but iOS long-press pops directly without notifying Shell first. **Regression chain:** | PR | What happened | |-----|---------------| | dotnet#24003 | Fixed dotnet#23892 with `_popRequested` flag | | dotnet#29825 | Removed flag, added `SyncStackDownTo()` - **broke long-press** | | dotnet#32456 | Added null checks, maintained broken state | | dotnet#33380 | **This PR** - simplified fix using stack-sync detection | **Removed:** `SyncStackDownTo()` method (44 lines) **What to avoid:** Don't remove stack count comparison - distinguishes user vs programmatic navigation. ### Issues Fixed Fixes dotnet#33379 **Related:** dotnet#23892, dotnet#29798 (verified not regressed ✅) --------- Co-authored-by: Shane Neuville <shneuvil@microsoft.com>
Description of Change
Fixes long-press back button navigation not triggering
OnAppearingand other navigation events in Shell.Problem: Test expected
OnAppearing count: 2, gotOnAppearing count: 1Root cause: PR #29825 replaced
SendPop()with manual stack synchronization (SyncStackDownTo()), which doesn't trigger navigation events.Fix: Simplified
DidPopItemto use stack-sync detection:SendPop()Key insight: Tab tap updates Shell's stack BEFORE
DidPopItemis called, but iOS long-press pops directly without notifying Shell first.Regression chain:
_popRequestedflagSyncStackDownTo()- broke long-pressRemoved:
SyncStackDownTo()method (44 lines)What to avoid: Don't remove stack count comparison - distinguishes user vs programmatic navigation.
Issues Fixed
Fixes #33379
Related: #23892, #29798 (verified not regressed ✅)