microsoft / microsoft/microsoft-ui-xaml
Proposal: smooth launch, don't show a Xaml Window until the first frame is rendered
- Dominant language
- C++
- Stars
- 8.4k
- Forks
- 942
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 105
Description
### Title
Smooth launch: synchronize showing a Xaml `Window` with its first rendered frame.
### Summary
A WinUI 3 `Window` becomes visible before Xaml has rendered anything into it, so the frame animates in empty and the content pops in after. Xaml should hold the window back until the first frame is ready, the way UWP Xaml used to.
### Rationale
* Every WinUI 3 app flickers on launch today, and it is the very first thing users see.
* UWP Xaml did not have this problem, so this is a regression for anyone moving to WinUI 3. Some of the plumbing is still in the tree (`JupiterWindowActivationState`, `CJupiterWindow::NotifyFirstFramePending` and `NotifyFirstFrameDrawn`), but `NotifyFirstFrameDrawn` early returns when there is no `CoreWindow`, so only UWP ever got the deferred activation.
* It is needed to unblock the GDI redirection surface optimization from #11523 (PR #11587). Skipping the redirection surface also removes the themed `WM_ERASEBKGND` fill that was partly covering the gap, so the flicker becomes more obvious. The flicker is there either way, that change just stops hiding it.
### Scope
| Capability | Priority |
| :---------- | :------- |
| A Xaml `Window` only becomes visible after its first frame has been rendered | Must |
| Apps get this without having to change any code | Must |
| There is a fallback so a window still shows if the first frame never arrives | Must |
| Windows shown after launch, not just the first one, behave the same way | Should |
| Apps can opt out if they depend on the current timing | Could |
| Providing a splash screen or any launch UI of its own | Won't |
### Important Notes
Videos are from https://github.com/microsoft/microsoft-ui-xaml/pull/11587#issuecomment-5414186235.
With the GDI redirection surface (today's default), the themed `WM_ERASEBKGND` fill partly covers the gap:
Without it, the empty window frame animating in is plainly visible:
Related: #11523, #11587, #7892.
### Open Questions
* Should this be on by default, or start behind a `XamlChangeId` opt-in?
* Sould there be some fallback be if the first frame takes too long?
* Is hooking `Window.Activate` enough, or does this also need to cover the `Microsoft.UI.Windowing` `AppWindow.Show` paths?
Contributor guide
Research direction
Start by tracing JupiterWindowActivationState and CJupiterWindow::NotifyFirstFramePending/NotifyFirstFrameDrawn, especially the CoreWindow early return. Compare the launch and later-window paths discussed with #11523 and #11587, then resolve the default, fallback, opt-out, and AppWindow.Show questions. Done means Xaml windows reveal their first rendered frame reliably without app changes, including a fallback when rendering does not arrive.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- desktop
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100