Skip to content

feat: add "On desktop" overlay layer that survives Show Desktop - #78

Merged
gyng merged 2 commits into
gyng:mainfrom
naessenskjell:feat/desktop-layer
Oct 26, 2026
Merged

gyng merged 2 commits into
gyng:mainfrom
naessenskjell:feat/desktop-layer

Conversation

@naessenskjell

Copy link
Copy Markdown
Contributor

Problem

With the default "Below windows" layer, Show Desktop / Win+D hides every widget: Explorer raises the desktop-icons host (Progman on 24H2+) above all normal windows. "Behind desktop icons" survives Show Desktop, but its widgets sit under SHELLDLL_DefView, so they can't be clicked.

Approach

A new opt-in layer, Settings → window layer → On desktop. The default is unchanged. It ports Rainmeter's "On desktop" mode (System.cpp, CheckDesktopState / PrepareHelperWindow):

  • A hidden sentinel window is parked at HWND_BOTTOM. If the icon host moves above it, Show Desktop is active. A foreground WinEvent hook triggers the check, with a 250 ms timer as fallback (100 ms while shown).
  • While Show Desktop is active, overlays are placed above the icon host and below the taskbar, using SWP_NOSENDCHANGING so that tao's always-on-bottom WM_WINDOWPOSCHANGING rewrite doesn't undo it. Afterwards they return to HWND_BOTTOM.
  • Overlays stay ordinary top-level windows, so per-widget click-through keeps working.

Testing

Windows 11 25H2 (build 26200), single monitor, using Shell.Application.ToggleDesktop():

Checks: cargo clippy clean, cargo test (4 new tests for the decision logic), npm run check, npm run lint, and unit tests. Two AiUsage tests fail, but they also fail on unmodified main.

Not tested: Windows before 24H2, multiple monitors, [clicking widgets during Show Desktop].

Written with help from Claude (Claude Code); the commit carries a Co-Authored-By trailer.

The 'bottom' layer disappears on Show Desktop / Win+D because Explorer
raises the desktop-icons host (Progman on 24H2+) above every normal
window. The 'wallpaper' layer survives it but sits under SHELLDLL_DefView,
so interactive widgets stop receiving clicks.

Add a 'desktop' layer modelled on Rainmeter's ZPOSITION_ONDESKTOP:
- desktop_layer.rs keeps a hidden sentinel window parked at HWND_BOTTOM;
  the icon host rising above it means the desktop is being shown. A
  foreground WinEvent hook plus a 250/100 ms timer drive the check.
- While shown, registered overlays are slotted under the backmost topmost
  window (above the icons, below the taskbar) with SWP_NOSENDCHANGING,
  which bypasses tao's always-on-bottom WM_WINDOWPOSCHANGING rewrite.
  On leaving they return to HWND_BOTTOM.
- Overlays stay ordinary top-level windows, so per-widget click-through
  keeps working.
- Studio Settings gains the "On desktop" window-layer option.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@gyng
gyng enabled auto-merge (squash) October 26, 2026 12:58
@gyng
gyng merged commit 02882d4 into gyng:main Oct 26, 2026
6 checks passed
@gyng

gyng commented Oct 26, 2026

Copy link
Copy Markdown
Owner

AI-generated review and release follow-up, posted by Codex at the repository owner's request.

Thanks @naessenskjell for contributing the On desktop layer. PR #78 is merged, and you are credited in README Contributors and the v0.0.71 release notes.

Follow-up fixes in #79:

  • Serialize frontend presentation changes so a delayed desktop enable cannot overwrite a newer layer selection.
  • Run native placement on the UI thread using current registrations and desktop state, with coalesced pending work that preserves the final return below windows.
  • Distinguish each running instance's sentinel, pause polling when no overlays use the layer, and avoid leaving registrations behind after watcher startup failure.
  • Add focused regression tests and document the PR review/release workflow in AGENTS.md.

Verification: 4,698 frontend tests with 100% coverage; 126 Playwright tests; 451 Rust tests, plus the explicitly invoked native smoke; typecheck, lint, build, rustfmt, and clippy passed. The native Win+D test passed on Windows 11 25H2 (26200.9445) across three connected monitors, checking placement above icons, native input hit testing, and restoration afterward. It uses temporary Win32 windows, so it does not establish every real WebView widget interaction; older Windows shells were not tested. No known medium-or-higher issues remain from this review.

Released in v0.0.71, with the Windows installer attached and build provenance verified.

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.

2 participants