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
Combine floating mode's per-panel independent positioning/dragging with Desktop Wallpaper mode's WorkerW integration, so each panel is its own small window living in the desktop background layer (survives Win+D, sits behind desktop icons, never covers anything) instead of the wallpaper host's current single fixed dashboard layout.
Explicitly not in scope here: per-pixel transparency. See "Scope: opaque only" below.
Background — what already exists and works
Two pieces of this are already built and proven, separately:
Per-panel independent windowing — src-egui/src/main.rs::render_floating_panels. Each visible panel is its own OS window via ctx.show_viewport_immediate, individually draggable, position persisted per panel key in Settings::floating_positions. Handles drag zones, padlock lock/unlock, per-panel auto-resize-to-content, and (for "Always Behind") a throttled HWND_BOTTOM re-assertion (win32_behind.rs) to avoid a CPU-spiking repaint loop.
WorkerW reparenting — src-egui/src/win32_wallpaper.rs. attach(hwnd) / is_attached(hwnd) / detach(hwnd), proven working (issue Spike: per-pixel translucency in Desktop Wallpaper mode via DirectComposition #131): survives Win+D, sits behind icons, re-attaches if Explorer rebuilds the WorkerW hierarchy. Currently used for exactly one HWND — the single rigstats-wallpaper host window.
The wallpaper host is a separate process (rigstats-wallpaper.exe) specifically because a WorkerW child window is destroyed if Explorer restarts — cross-process included — so reparenting the main app's own window would risk taking the whole app down with it. See docs/architecture.md "Desktop wallpaper mode (WorkerW)".
Proposed approach
Generalize the wallpaper host (src-egui/src/bin/wallpaper.rs) from "one fixed-layout window" to "N independently-positioned panel windows," reusing render_floating_panels' per-panel viewport/drag/position code (adapted to the host binary) and win32_wallpaper.rs's attach/re-attach logic generalized from a single self.hwnd: isize to a HashMap<String, isize> keyed by panel key — each panel gets its own attach-on-creation + periodic is_attached safety net.
Keep it a single host process, not one process per panel. The host already owns telemetry polling (poll_loop) and the sensor pipe's single client slot; N separate processes would mean either N independent pollers (wasteful, duplicates GPU/CPU/WMI polling work — directly against the resource-utilization concern raised when scoping this) or new inter-process telemetry distribution (real added complexity for no clear benefit). One process rendering N viewports is the natural fit and mirrors what floating mode already does today within the main process.
Each panel window still needs the existing "cache HWND on first frame, SetParent into WorkerW, periodic is_attached re-check" sequence — per-window state, not global.
Scope: opaque only (no per-pixel transparency in this issue)
Keep panels opaque (or using the existing WS_EX_LAYERED uniform-dim opacity, same as floating mode has today) for this issue. Per-pixel translucency is a separate, harder problem: issue #169 (extend #101's DComp per-pixel transparency to floating mode) found that applying WS_EX_NOREDIRECTIONBITMAP to a secondary show_viewport_immediate viewport's HWND breaks its rendering (washed-out color), reproduced with zero opacity logic involved — a real eframe 0.34.3/egui-wgpu limitation in how the swap-chain surface is created for non-root immediate viewports combined with a DComp (DxgiFromVisual) backend. This issue's multi-window wallpaper host would hit the exact same limitation if it tried to add translucency. Do this issue without transparency first; revisit combining it with #169 once that's resolved.
Risks / open questions
Explorer-restart robustness at N windows instead of 1. The existing single-window re-attach safety net (is_attached polled ~1/s, re-attach() if detached) generalizes mechanically to a loop over N HWNDs, but there's more surface area for something to go wrong — verify no crash/hang if Explorer restarts while several panels are attached.
Panel add/remove while running. Floating mode already handles a panel being toggled visible/invisible mid-session (main.rs's panels_positioned tracking). The host needs the same for its own per-panel HWND map — attach newly-shown panels, clean up state for hidden ones (their OS window is presumably destroyed by show_viewport_immediate simply no longer being called for that key each frame — confirm this doesn't leak).
Resource cost. Should stay roughly comparable to today's floating mode (same N-viewport-per-frame rendering cost that Floating mode - reduce multi-window rendering cost #104 already investigated and accepted as not worth optimizing further) plus today's single-window wallpaper host's WorkerW-attach overhead, multiplied by N. Worth a before/after CPU measurement (same methodology Floating mode - reduce multi-window rendering cost #104 used: TotalProcessorTime delta over 10s) once implemented, given resource utilization was explicitly flagged as a priority while scoping this.
Settings/UX: does this become a new "Window Layer" option (e.g. "Desktop Wallpaper — Floating"), or a checkbox/toggle combining the existing "Desktop Wallpaper" layer with the existing "Floating Mode" toggle (currently mutually exclusive — wallpaper mode force-disables floating mode, see main.rs around the window-layer selector)? Needs a decision before implementing the Settings UI change.
Acceptance criteria
Each visible panel renders as its own window living in the WorkerW desktop-background layer: survives Win+D, sits behind desktop icons, doesn't cover anything.
Panels remain individually draggable/positionable, with positions persisted the same way floating mode already does.
Re-attaches correctly after an Explorer restart, for all currently-attached panels.
No meaningful resource-usage regression vs. today's floating mode + wallpaper mode individually (measure, don't assume).
Opaque / WS_EX_LAYERED-dimmed only — no attempt at per-pixel transparency in this issue.
Goal
Combine floating mode's per-panel independent positioning/dragging with Desktop Wallpaper mode's WorkerW integration, so each panel is its own small window living in the desktop background layer (survives
Win+D, sits behind desktop icons, never covers anything) instead of the wallpaper host's current single fixed dashboard layout.Explicitly not in scope here: per-pixel transparency. See "Scope: opaque only" below.
Background — what already exists and works
Two pieces of this are already built and proven, separately:
src-egui/src/main.rs::render_floating_panels. Each visible panel is its own OS window viactx.show_viewport_immediate, individually draggable, position persisted per panel key inSettings::floating_positions. Handles drag zones, padlock lock/unlock, per-panel auto-resize-to-content, and (for "Always Behind") a throttledHWND_BOTTOMre-assertion (win32_behind.rs) to avoid a CPU-spiking repaint loop.src-egui/src/win32_wallpaper.rs.attach(hwnd)/is_attached(hwnd)/detach(hwnd), proven working (issue Spike: per-pixel translucency in Desktop Wallpaper mode via DirectComposition #131): survivesWin+D, sits behind icons, re-attaches if Explorer rebuilds the WorkerW hierarchy. Currently used for exactly one HWND — the singlerigstats-wallpaperhost window.The wallpaper host is a separate process (
rigstats-wallpaper.exe) specifically because a WorkerW child window is destroyed if Explorer restarts — cross-process included — so reparenting the main app's own window would risk taking the whole app down with it. Seedocs/architecture.md"Desktop wallpaper mode (WorkerW)".Proposed approach
src-egui/src/bin/wallpaper.rs) from "one fixed-layout window" to "N independently-positioned panel windows," reusingrender_floating_panels' per-panel viewport/drag/position code (adapted to the host binary) andwin32_wallpaper.rs's attach/re-attach logic generalized from a singleself.hwnd: isizeto aHashMap<String, isize>keyed by panel key — each panel gets its own attach-on-creation + periodicis_attachedsafety net.poll_loop) and the sensor pipe's single client slot; N separate processes would mean either N independent pollers (wasteful, duplicates GPU/CPU/WMI polling work — directly against the resource-utilization concern raised when scoping this) or new inter-process telemetry distribution (real added complexity for no clear benefit). One process rendering N viewports is the natural fit and mirrors what floating mode already does today within the main process.SetParentinto WorkerW, periodicis_attachedre-check" sequence — per-window state, not global.Scope: opaque only (no per-pixel transparency in this issue)
Keep panels opaque (or using the existing
WS_EX_LAYEREDuniform-dim opacity, same as floating mode has today) for this issue. Per-pixel translucency is a separate, harder problem: issue #169 (extend #101's DComp per-pixel transparency to floating mode) found that applyingWS_EX_NOREDIRECTIONBITMAPto a secondaryshow_viewport_immediateviewport's HWND breaks its rendering (washed-out color), reproduced with zero opacity logic involved — a real eframe 0.34.3/egui-wgpu limitation in how the swap-chain surface is created for non-root immediate viewports combined with a DComp (DxgiFromVisual) backend. This issue's multi-window wallpaper host would hit the exact same limitation if it tried to add translucency. Do this issue without transparency first; revisit combining it with #169 once that's resolved.Risks / open questions
is_attachedpolled ~1/s, re-attach()if detached) generalizes mechanically to a loop over N HWNDs, but there's more surface area for something to go wrong — verify no crash/hang if Explorer restarts while several panels are attached.main.rs'spanels_positionedtracking). The host needs the same for its own per-panel HWND map — attach newly-shown panels, clean up state for hidden ones (their OS window is presumably destroyed byshow_viewport_immediatesimply no longer being called for that key each frame — confirm this doesn't leak).TotalProcessorTimedelta over 10s) once implemented, given resource utilization was explicitly flagged as a priority while scoping this.main.rsaround the window-layer selector)? Needs a decision before implementing the Settings UI change.Acceptance criteria
Win+D, sits behind desktop icons, doesn't cover anything.WS_EX_LAYERED-dimmed only — no attempt at per-pixel transparency in this issue.Related issues
Affected files (entry points)
src-egui/src/bin/wallpaper.rs— the host; needs the per-panel windowing loopsrc-egui/src/main.rs::render_floating_panels— source of the per-panel viewport/drag/position logic to adaptsrc-egui/src/win32_wallpaper.rs— attach/is_attached/detach, needs generalizing to N HWNDssrc-egui/src/windows/settings.rs— Settings UX decision (new layer option vs. combined toggle)docs/architecture.md"Desktop wallpaper mode (WorkerW)" — update once shipped