Start the fade-in only after the menu surface has been submitted - #76
Merged
Conversation
The OS hit-tests a layered window against its last submitted surface, which lags Window.Show by several frames. Running the fade immediately meant the animation played against an invisible, click-through window: the menu popped in mid-fade at high opacity, and clicks in the gap fell through to the window beneath, dismissing the menu via deactivation. Deferring the fade to the second composition tick makes the menu hittable from the first visible pixel and makes the fade visible at all. Fixes #74
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #74.
Mechanism (measured, not guessed)
The OS hit-tests a layered window against its last submitted surface, and the first submission after
Window.Show()lags by ~120-150 ms on a cold open (~30-60 ms warm). The fade animation started immediately on show, so its clock ran against a window that was still invisible and click-through. ProbingWindowFromPoint(the same OS path real clicks take) against the fade timeline proved the point:Fix
Defer
BeginFadeInby twoCompositionTarget.Renderingticks afterShowMenu: one tick renders the shown surface, the second guarantees it was submitted. Event-driven, no timers. A version counter cancels a pending fade-in if the menu hides first.Measured result (same probe, fixed build)
The menu is now hittable before the first visible pixel on every open, and the full 0-to-1 fade actually renders instead of popping in near-full opacity. Clicking a slice the instant it appears executes it (verified 3/3 opens, cold included).
Verification
dotnet test: 148/148.main: 3 of 121,905 pixels within anti-aliasing tolerance - no visual change to the rendered menu.Residual (inherent to layered windows): a truly blind click in the first ~50-70 ms - before anything is on screen - still lands beneath the menu; that window shrank from ~150 ms and can't reach zero because a surface cannot be hit-tested before it exists.