Skip to content

perf(wallpaper): draw the dashboard in its own window, not the host's root - #664

Merged
dvalfrid merged 1 commit into
mainfrom
perf/wallpaper-dashboard-window
Oct 27, 2026
Merged

dvalfrid merged 1 commit into
mainfrom
perf/wallpaper-dashboard-window

Conversation

@dvalfrid

@dvalfrid dvalfrid commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Correction (2026-10-28): the CPU claims below are wrong. "Cause (verified)" was not verified. Every measurement here was taken 15–35 s after start, inside AMD's start-up burst (#515): a thread in amdxc64.dll that polls with zero-timeout waits for ~30–120 s after a process starts rendering. Measured from ~50 s on, 1.52.0 (dashboard in the root window) and this PR both cost ~1 % of a core for the host on an RX 9070 XT and 2–3 % on a Radeon 890M. "100 % → 0.9 %" compared the burst with a window where it had moved or ended. This PR does not shorten the burst either: since this PR it mostly lands in the main app instead of the host, for about the same total time. Data: "Startup burst" in docs/architecture.md.

The change is kept for the host's structure: one path for every window (a 1×1 root anchor plus viewports), and two state fields and a no-op WS_EX_LAYERED call gone. It also brought two regressions, fixed in #667 before any release: a landscape dashboard ~200 px too tall, and a white flash when leaving wallpaper mode. The "A lighter desktop wallpaper mode" highlight has been dropped. The changelog line is overridden below so it no longer lists this as a performance change.


In ordinary Desktop wallpaper mode the host used ~100 % of a CPU core, already in 1.52.0 (#663).

Cause (verified):

Fix: the host's root window is that 1×1 transparent anchor for the dashboard too. The dashboard is drawn in a viewport (render_panel_windows, key dashboard) with the floating panels' DComp burst, fills its background at the profile's opacity and fits its height to the content. The old root drawing, its fit fields and its WS_EX_LAYERED opacity call (rejected in WorkerW anyway) are gone.

Measured on the owner's desktop (RX 9070 XT, release builds, 20 s after 15 s warm-up):

Host
Before: installed 1.52.0 and local v1.52.0, #642, #644, #641, main (five runs) ~100 %
After (two runs) 0.9 %, 1.0 %
Floating panels in the wallpaper 0.6 %

Verified:

  • The owner checked the dashboard with Win+D on the final build: it shows right and is see-through. Floating panels were checked by screenshot.
  • tools/smoke-app.ps1 6/6, clippy clean, egui tests pass.

Not measured: NVIDIA or Intel graphics. The G14 can show it.

Highlights: a 1.53.0 line, "A lighter desktop wallpaper mode".

Closes #663

🤖 Generated with Claude Code

BEGIN_COMMIT_OVERRIDE
refactor(wallpaper): draw the dashboard in its own window, not the host's root
END_COMMIT_OVERRIDE

… root

In Desktop wallpaper mode the host used ~100 % of a CPU core, already in
1.52.0. The probe showed ~2 frames a second and no resizes; the hot thread
started in amdxc64.dll (AMD's DX12 driver). The floating panels in the
wallpaper (#662) — viewports beside a 1x1 root — used 0.7 %. So the host's
root window is now that 1x1 transparent anchor for the dashboard too, and
the dashboard is drawn in a viewport with the floating panels' DComp burst,
fitting its height to the content. The old root drawing, its fit and its
WS_EX_LAYERED opacity call are gone.

Measured on the owner's desktop (RX 9070 XT, release, 20 s): host 100 %
(five runs, 1.52.0 and main) -> 0.9 % and 1.0 %; floating panels 0.6 %.
smoke-app 6/6. Not measured on NVIDIA or Intel graphics.

Closes #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dvalfrid
dvalfrid merged commit 30fdbc3 into main Oct 27, 2026
6 checks passed
@dvalfrid
dvalfrid deleted the perf/wallpaper-dashboard-window branch October 27, 2026 17:09
dvalfrid added a commit that referenced this pull request Oct 28, 2026
The host line now says the dashboard has its own window to take the
floating panels' path, and that the CPU cost after the burst is the same as
in 1.52.0 (RX 9070 XT ~1 %, Radeon 890M 2-3 %). The landscape window fits
its content too, not the fixed profile size. "Startup burst" gets the RX
9070 XT runs: #664 did not shorten the burst; in main it mostly lands in the
main app instead of the host.

Drops the "A lighter desktop wallpaper mode" highlight: the measurements
don't support it once the burst is over.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dvalfrid added a commit that referenced this pull request Oct 28, 2026
…indow

Since #664 the dashboard is drawn in a viewport inside a CentralPanel, and
the height fit read the panel's ui.min_rect(). egui's CentralPanel expands
that to the whole window, so the fit could only grow: a landscape dashboard
of compact panels stayed at its start-up estimate, ~200 px of panel fill
below the panels. The fit now measures the content in a ui.scope.

Reproduced on the owner's desktop (landscape-xl, all panels compact): the
dashboard window was 1922x464; 1.52.0, drawing in the root window, 1920x243.
After: 1920x243, stable over 10 reads in 10 s. portrait-xl 450x924 before,
after and in 1.52.0. smoke-app wallpaper, floating, wallpaper-floating pass.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dvalfrid added a commit that referenced this pull request Oct 28, 2026
…#667)

* chore(tools): measure the app's CPU over time after start

tools/measure-startup-cpu.ps1 starts the app in a window layer and prints
its CPU in 20 s windows at set times after start, then puts the settings
back. A window right after start only measures AMD's start-up burst
(#515): on the G14 (Radeon 890M) the wallpaper host and the main app hold
a core for ~30-120 s and then settle at 2-3 %, 1.52.0 and main alike.

docs/architecture.md: the burst on the 890M, and that the #663/#664
numbers were taken 15-35 s after start, so their steady state on the
RX 9070 XT is not measured yet.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor(wallpaper): name what each host window draws

The host's windows were all "panels", the dashboard being the one with the
key "dashboard", tested in three places (size, fill, drawing). A
WindowContent enum (Dashboard { size } / Panel(key)) in HostWindow says it
instead, the dashboard's drawing is its own function, and
render_panel_windows is render_windows. The dashboard window's starting
size moves into its variant. No behaviour change: same titles, sizes, fills
and log lines.

The comment at the call no longer says the root window held a core: that
was AMD's start-up burst, not the root (#663). The dashboard has its own
window to take the floating panels' path.

Checked: the height fit sends at most two InnerSize per window after start
and then none, at egui zoom 1.0 / 1.25 / 1.5 (temporary logging, removed).
smoke-app wallpaper, floating, wallpaper-floating pass; CPU from 120 s
0.7-1.7 % (three runs, RX 9070 XT).

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(wallpaper): the ~100 % in #663 was AMD's start-up burst

The host line now says the dashboard has its own window to take the
floating panels' path, and that the CPU cost after the burst is the same as
in 1.52.0 (RX 9070 XT ~1 %, Radeon 890M 2-3 %). The landscape window fits
its content too, not the fixed profile size. "Startup burst" gets the RX
9070 XT runs: #664 did not shorten the burst; in main it mostly lands in the
main app instead of the host.

Drops the "A lighter desktop wallpaper mode" highlight: the measurements
don't support it once the burst is over.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(wallpaper): one line for the "still no wallpaper WorkerW" warning

The string literal broke onto a second line without a backslash, so the
logged warning had a run of 30 spaces in the middle. Text unchanged
otherwise.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore(tools): lists through pwsh -File, and no CPU numbers across a sleep

`pwsh -File` hands `-At 15,60` and `-Only a,b` over as one string, which
[int[]] refused and smoke-app took for an unknown mode; both now split it.
measure-startup-cpu: a window that takes more than 5 s longer than asked
(the PC slept, or the script stalled) is reported invalid and ends the run,
since the process's CPU time stops while the clock runs on; an exited
process says so instead of a negative number; and the settings backup is
per run, so one run's clean-up can't delete another's. Tested: comma lists
through -File in both scripts, and a run frozen for 12 s inside a window.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(wallpaper): fit the dashboard window to its content, not to the window

Since #664 the dashboard is drawn in a viewport inside a CentralPanel, and
the height fit read the panel's ui.min_rect(). egui's CentralPanel expands
that to the whole window, so the fit could only grow: a landscape dashboard
of compact panels stayed at its start-up estimate, ~200 px of panel fill
below the panels. The fit now measures the content in a ui.scope.

Reproduced on the owner's desktop (landscape-xl, all panels compact): the
dashboard window was 1922x464; 1.52.0, drawing in the root window, 1920x243.
After: 1920x243, stable over 10 reads in 10 s. portrait-xl 450x924 before,
after and in 1.52.0. smoke-app wallpaper, floating, wallpaper-floating pass.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(wallpaper): no white flash when leaving wallpaper mode

Closing the host takes a few frames. In the one where it decided to close,
ui() returned before showing the dashboard viewport, so egui destroyed it;
the next frame showed it again, and egui created a fresh top-level window
outside WorkerW - visible, white, until the process exited. The host now
remembers it is closing and shows no window again.

Reproduced with the host standalone, flipping the layer to normal and
listing visible top-level host windows every 5 ms: a new "RIGStats
Wallpaper - dashboard" window for ~100 ms in 2 runs of 2 (1920x1023, then
1920x243); none with 1.52.0 (2 runs) or after the fix (3 runs). The log's
"panel dashboard waits for a wallpaper WorkerW" on closing is gone too.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(wallpaper): the dashboard in the same place in every window layer

Positioned in Normal and switched to Desktop Wallpaper (or back), the
dashboard's corner landed on the same pixel, but its panels sat 17 px
higher in wallpaper mode: the main window starts with an empty drag strip
(DRAG_HANDLE_H plus egui's item spacing) the host doesn't need. The host
now leaves the same strip, and is 2 px narrower in portrait like the main
window, so both cover the same pixels.

Measured on the owner's desktop, launching each layer at the same position
and reading the window rect and the first row of header text: before,
text 89 vs 72 px (portrait) and 88 vs 71 (landscape), the same in 1.52.0;
after, 89/89 and 88/88, windows 448x941 and 1920x260 in both layers.

Refs #663

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(wallpaper): highlight that the dashboard stays put in the desktop background

Refs #666

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(wallpaper): the wallpaper host uses a whole CPU core — a thread in AMD's DX12 driver

1 participant