You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a NavigationView is narrow enough to use Minimal display mode, opening its overlay pane and then maximizing the window can leave the pane, list-size visual state, and pane lifecycle events inconsistent.
Depending on the event ordering, I have observed the following outcomes:
The pane transitions normally.
The pane remains open after maximizing. Closing it with the toggle button leaves the navigation item labels visible beside the compact icons.
More rarely, maximizing immediately produces a compact-width pane whose item labels remain visible.
The issue does not require rapid clicking. Repeating the same resize sequence is sufficient to reproduce it.
Why is this important?
NavigationView is commonly used as the main navigation surface of a desktop application. The bug leaves the control in a visibly invalid state and can also suppress a subsequent PaneClosing event.
I reproduced the behavior in WinUI Gallery and in a newly initialized, minimal WinUI 3 project. I have also observed the same visible behavior in the Windows Photos and Settings apps, although I cannot confirm that those applications reach exactly the same internal code path.
Steps to reproduce the bug
Run the attached minimal reproduction project, or open WinUI Gallery.
Resize the window until NavigationView enters Minimal display mode.
Click the pane toggle button to open the overlay pane.
Maximize the window.
If the pane remains visually open, click the pane toggle button once to close it.
Observe that the pane can become compact while the navigation item label remain visible.
Repeat the sequence if necessary. The exact result is ordering-dependent, but no rapid interaction is required.
The logical pane state, SplitView visual state, and NavigationView list-size visual state can disagree.
In one ordering, the close completion is interpreted as an open completion, PaneClosed is not raised for the close, and a later PaneClosing event can be suppressed.
In another ordering, the pane ends in a compact closed state while NavigationView remains in ListSizeFull, leaving labels visible beside the compact icons.
Expected behavior
After the adaptive layout change completes:
an open pane must use the full list-size state;
a closed pane in a compact SplitView mode must use ListSizeCompact;
each committed close/open transition must produce the corresponding lifecycle completion without suppressing a later manual close.
Windows 11 (25H2): Build 26200, Windows Insider Build (xxxxx)
Additional context
Similar historical symptoms were reported in #450 and #5474. I have not established that those reports have the same underlying cause.
Preliminary source analysis found two independent ordering problems:
SplitView::OnDisplayModeStateChanged handles an asynchronously delivered CurrentStateChanged event by reading the latest shared m_isPaneOpeningOrClosing and IsPaneOpen values. If a close is followed by an open before the queued close state notification is delivered, the close notification can be interpreted as an open completion. PaneClosed is then lost and m_isPaneClosingByLightDismiss can remain set. As a result, the next manual close can be mistaken for the completion of the earlier light-dismiss operation, suppressing its PaneClosing event.
NavigationView::OnSplitViewPaneClosing only enters ListSizeCompact when SplitView is already in a compact display mode. During the preparation phase of light-dismiss, PaneClosing can be delivered while the display mode is still Overlay, so we not change the list size. Adaptive layout can then change the mode to CompactInline while the pane remains open. During the deferred execution phase, the pane is finally closed, but SplitView::OnPaneClosing suppresses the second PaneClosing notification because the close is already marked as a light-dismiss operation. Consequently, neither phase changes the list from ListSizeFull, and no later callback reconciles it with the final compact closed state.
I have a proposed fix for both orderings and am willing to submit a PR.
Describe the bug
When a NavigationView is narrow enough to use Minimal display mode, opening its overlay pane and then maximizing the window can leave the pane, list-size visual state, and pane lifecycle events inconsistent.
Depending on the event ordering, I have observed the following outcomes:
The issue does not require rapid clicking. Repeating the same resize sequence is sufficient to reproduce it.
Why is this important?
NavigationView is commonly used as the main navigation surface of a desktop application. The bug leaves the control in a visibly invalid state and can also suppress a subsequent PaneClosing event.
I reproduced the behavior in WinUI Gallery and in a newly initialized, minimal WinUI 3 project. I have also observed the same visible behavior in the Windows Photos and Settings apps, although I cannot confirm that those applications reach exactly the same internal code path.
Steps to reproduce the bug
demo.zip
log-annotated.log
Actual behavior
The logical pane state, SplitView visual state, and NavigationView list-size visual state can disagree.
In one ordering, the close completion is interpreted as an open completion, PaneClosed is not raised for the close, and a later PaneClosing event can be suppressed.
In another ordering, the pane ends in a compact closed state while NavigationView remains in ListSizeFull, leaving labels visible beside the compact icons.
Expected behavior
After the adaptive layout change completes:
Screenshots
Demo:
https://github.com/user-attachments/assets/286c39f7-4a83-42a0-8aab-079c86385f46
https://github.com/user-attachments/assets/2d3c70d3-ef07-4a1a-ba1e-d9a939ede0ff
WinUI 3 Gallery:
https://github.com/user-attachments/assets/b0355129-67d7-4b7c-b21a-9e3b9cdbe548
Photos:
photos-bug1.mp4
NuGet package version
Microsoft.WindowsAppSDK 2.4.0
Windows version
Windows 11 (25H2): Build 26200, Windows Insider Build (xxxxx)
Additional context
Similar historical symptoms were reported in #450 and #5474. I have not established that those reports have the same underlying cause.
Preliminary source analysis found two independent ordering problems:
SplitView::OnDisplayModeStateChangedhandles an asynchronously deliveredCurrentStateChangedevent by reading the latest sharedm_isPaneOpeningOrClosingandIsPaneOpenvalues. If a close is followed by an open before the queued close state notification is delivered, the close notification can be interpreted as an open completion.PaneClosedis then lost andm_isPaneClosingByLightDismisscan remain set. As a result, the next manual close can be mistaken for the completion of the earlier light-dismiss operation, suppressing itsPaneClosingevent.NavigationView::OnSplitViewPaneClosingonly entersListSizeCompactwhen SplitView is already in a compact display mode. During the preparation phase of light-dismiss,PaneClosingcan be delivered while the display mode is stillOverlay, so we not change the list size. Adaptive layout can then change the mode toCompactInlinewhile the pane remains open. During the deferred execution phase, the pane is finally closed, butSplitView::OnPaneClosingsuppresses the secondPaneClosingnotification because the close is already marked as a light-dismiss operation. Consequently, neither phase changes the list fromListSizeFull, and no later callback reconciles it with the final compact closed state.I have a proposed fix for both orderings and am willing to submit a PR.
Please assign the issue to me if appropriate.