PeekDesktop ๐Ÿ‘€

April 24, 2026 ยท View on GitHub

Click empty desktop wallpaper (or empty taskbar area) to reveal your desktop โ€” just like macOS Sonoma.

PeekDesktop brings macOS Sonoma's "click wallpaper to reveal desktop" feature to Windows 10 and 11. By default it uses Explorer's native Show Desktop behavior, and it also includes an optional Fly Away experimental style plus tray toggles for Require Double-Click and Peek on Taskbar Click. Click or drag desktop icons normally without accidentally triggering peek. When you're done, click any window, the taskbar, or the wallpaper again and everything comes right back where it was.

PeekDesktop demo showing windows minimizing when you click the wallpaper

Download

๐Ÿ“ฅ Download the latest release

FilePlatform
PeekDesktop-vX.Y-win-x64.zipIntel/AMD (most PCs)
PeekDesktop-vX.Y-win-arm64.zipARM64 (Surface Pro X, Snapdragon, etc.)

No installer needed. Download the zip, extract it, and run PeekDesktop.exe. Release builds are self-contained, so you do not need to install .NET separately. It lives in your system tray and updates itself automatically โ€” when a new version is available, it downloads, verifies the code signature, and restarts in place.

Documentation

  • Engineering Deep Dive - architecture, shell internals, experiments, debugging workflow, undocumented API notes, and release tradeoffs
  • Auto-Updater - how the in-place auto-update system works, security model, swap dance, testing

How It Works

  1. Click empty desktop wallpaper or empty taskbar area (not an icon or taskbar button) -> your desktop is revealed
  2. Stay on the desktop -> click or drag icons, right-click, and rearrange things while windows stay hidden
  3. Click any app, the taskbar, or empty wallpaper again -> all windows restore to exactly where they were

That's it. It just works.

Peek Styles

  • Show Desktop (Explorer) โ€” the default and recommended mode. Uses Explorer's native Show Desktop behavior.
  • Fly Away (Experimental) โ€” animates windows offscreen. Fun but has known quirks with external window management (Win+D, taskbar). Use for the visual flair, but know it can get confused if the shell changes window state behind its back.

Under the Hood

PeekDesktop uses lightweight Windows APIs:

  • SetWindowsHookEx(WH_MOUSE_LL) โ€” low-level mouse hook to detect desktop clicks
  • WindowFromPoint โ€” identifies the window under your cursor
  • MSAA hit-testing (AccessibleObjectFromPoint) โ€” distinguishes empty wallpaper from desktop icons
  • UI Automation hit-testing โ€” classifies empty taskbar space without firing on Start, pinned apps, or tray buttons
  • Taskbar Show Desktop button click โ€” primary path, immune to keyboard remapping (PowerToys, etc.)
  • Win+D SendInput โ€” fallback if taskbar button is unavailable
  • EnumWindows + WINDOWPLACEMENT โ€” captures exact position and state (including maximized) of every window
  • SetWinEventHook(EVENT_SYSTEM_FOREGROUND) โ€” watches for when you switch back to an app
  • SetWindowPlacement โ€” restores windows to their exact previous positions

No admin rights required. Uses < 5 MB RAM idle.

System Tray

Right-click the tray icon for options:

  • โœ… Enabled โ€” toggle the peek feature on/off
  • ๐Ÿ” Start with Windows โ€” launch automatically at login
  • ๐Ÿ–ฑ๏ธ Require Double-Click โ€” optionally require a double-click on the desktop to trigger peek
  • ๐ŸŽฎ Pause While Gaming / Full-Screen โ€” on by default for exclusive full-screen and known gaming fullscreen apps
  • ๐Ÿ“Œ Peek on Taskbar Click โ€” optionally trigger peek from empty taskbar space
  • ๐ŸชŸ Restore All Windows on App Switch โ€” on by default; in Explorer show desktop mode, taskbar/Alt+Tab app switches restore all hidden windows behind the selected app
  • ๐Ÿ‘€ Peek Style โ€” switch between Explorer and fly-away modes
  • โ„น๏ธ About โ€” version info
  • โฌ‡๏ธ Check for Updates โ€” download and install newer versions automatically
  • ๐Ÿ”„ Auto-Check for Updates โ€” on by default; silently checks for updates on startup
  • โŒ Exit โ€” quit PeekDesktop

When Windows is in dark mode, the tray menu also follows the system theme when supported by the OS.

What's New

  • Small Native AOT single-file builds for both x64 and ARM64
  • Peek on Taskbar Click โ€” optional trigger from empty taskbar space
  • Dark tray menu support โ€” follows Windows dark mode when available
  • Taskbar button Show Desktop โ€” bypasses keyboard remappers (PowerToys Keyboard Manager, etc.)
  • Pause While Gaming / Full-Screen โ€” avoids interference during gaming sessions
  • Require Double-Click โ€” optional double-click trigger for desktop peek
  • In-place auto-updater โ€” downloads, verifies Authenticode signature, swaps, and restarts automatically

macOS Sonoma vs PeekDesktop

FeaturemacOS SonomaPeekDesktop
Click wallpaper to peekโœ…โœ…
Restore on app clickโœ…โœ…
Restore on second wallpaper clickโœ…โœ…
Clicking/dragging icons does not trigger peekโœ…โœ…
Desktop icons accessibleโœ…โœ…
Exact window position restoreโœ…โœ…
System tray controlโŒโœ…
Multi-monitor supportโœ…โœ…
Start with OSLogin Itemsโœ… Registry
Smooth animationโœ…Fly Away mode

Build from Source

Requirements: .NET 10 SDK

git clone https://github.com/shanselman/PeekDesktop.git
cd PeekDesktop
dotnet build src/PeekDesktop/PeekDesktop.csproj

Run it

dotnet run --project src/PeekDesktop/PeekDesktop.csproj

# Run the P/Invoke safety harness (invalid handles + stress/leak checks)
dotnet run --project src/PeekDesktop.InteropHarness/PeekDesktop.InteropHarness.csproj -- 10000

# Windows-friendly wrapper script
.\test.ps1 -Iterations 10000

# Verbose mode (prints per-test timing + leak probe diagnostics)
.\test.ps1 -Iterations 10000 -VerboseOutput

Publish a self-contained single-file exe

# For Intel/AMD
dotnet publish src/PeekDesktop/PeekDesktop.csproj -c Release -r win-x64 --self-contained -p:PublishSingleFile=true

# For ARM64
dotnet publish src/PeekDesktop/PeekDesktop.csproj -c Release -r win-arm64 --self-contained -p:PublishSingleFile=true

Release packaging

Release builds use .NET Native AOT โ€” the exe is a fully native binary with no .NET runtime dependency. Current releases ship as self-contained single-file executables for both x64 and ARM64. Earlier experiments also used PublishAotCompressed (LZMA), but current builds favor compatibility and predictable startup behavior.

Architecture

src/PeekDesktop/
โ”œโ”€โ”€ Program.cs             # Entry point, single-instance mutex
โ”œโ”€โ”€ DesktopPeek.cs         # Core state machine (Idle โ†” Peeking)
โ”œโ”€โ”€ MouseHook.cs           # WH_MOUSE_LL global mouse hook
โ”œโ”€โ”€ FocusWatcher.cs        # EVENT_SYSTEM_FOREGROUND monitor
โ”œโ”€โ”€ WindowTracker.cs       # Enumerate, minimize, and restore windows
โ”œโ”€โ”€ DesktopDetector.cs     # Identify desktop windows, icons, taskbar
โ”œโ”€โ”€ Win32MessageLoop.cs    # Win32 message loop + TaskbarCreated recovery
โ”œโ”€โ”€ Win32TrayIcon.cs       # Shell_NotifyIcon wrapper
โ”œโ”€โ”€ Win32Menu.cs           # Win32 popup menu wrapper
โ”œโ”€โ”€ Win32Icon.cs           # Programmatic icon via CreateIconIndirect
โ”œโ”€โ”€ WinHttp.cs             # WinHTTP wrapper (replaces HttpClient)
โ”œโ”€โ”€ TrayIcon.cs            # Tray icon business logic + menu wiring
โ”œโ”€โ”€ AppUpdater.cs          # In-place auto-updater (download, verify, swap, restart)
โ”œโ”€โ”€ AppDiagnostics.cs      # Logging via Trace/DebugView
โ”œโ”€โ”€ Settings.cs            # Hand-written UTF-8 JSON persistence + autostart
โ””โ”€โ”€ NativeMethods.cs       # Win32 P/Invoke declarations

Contributing

PRs welcome! Current status and next ideas:

  • Click empty wallpaper to peek
  • Click empty taskbar area to peek (opt-in)
  • Restore on app click or taskbar click
  • Restore on a second wallpaper click
  • Clicking or dragging desktop icons does not start peek
  • Right-click desktop icons while peeking (context menus stay open)
  • Desktop icons remain usable while peeking
  • Exact window positions are restored
  • GitHub release-based update checks
  • Works with PowerToys Keyboard Manager (keyboard remapping)
  • Smooth minimize/restore animations (slide/fade)
  • Hotkey support (e.g., Ctrl+F12 to toggle peek)
  • Per-monitor peek (only minimize windows on the clicked monitor)
  • Exclude specific apps from being minimized

.NET Native AOT โ€” The Size Journey ๐Ÿ’พ

PeekDesktop is a showcase for how small a .NET Native AOT application can get. Starting from a standard WinForms app, we systematically eliminated every managed framework dependency until the binary was pure Win32 P/Invoke โ€” then compressed it to fit on a floppy disk.

VersionBinary SizeWhat Changed
v0.4.5~65 MBSelf-contained .NET (no AOT)
v0.5.017.5 MBEnabled Native AOT
v0.6.04.2 MBDropped WinForms โ€” pure Win32 P/Invoke for tray icon, menus, message loop
v0.6.12.3 MBReplaced HttpClient with OS-native WinHTTP (winhttp.dll)
v0.7.21.88 MBEliminated JSON source generator, System.Reflection, Process.Start
v0.7.2 + LZMA~564 KBLZMA compression via PublishAotCompressed

What's left in the 1.88 MB (pre-compression)?

  • ~1.2 MB โ€” .NET Native AOT runtime (GC, threading, exception handling, type system)
  • ~0.4 MB โ€” Utf8JsonReader/Utf8JsonWriter + async task machinery
  • ~0.2 MB โ€” App code, P/Invoke stubs, string literals
  • ~0.08 MB โ€” PE headers and metadata

Key techniques:

  • No WinForms, no System.Drawing โ€” Shell_NotifyIcon, CreatePopupMenu, TrackPopupMenuEx, MessageBoxW, CreateIconIndirect via P/Invoke
  • No HttpClient โ€” WinHttpOpen/WinHttpSendRequest uses the OS HTTP+TLS stack at zero binary cost
  • No JSON source generator โ€” hand-written Utf8JsonReader/Utf8JsonWriter for the two tiny JSON shapes we need
  • No System.Reflection โ€” PE version resources read via GetFileVersionInfoExW P/Invoke
  • No managed delegates for WndProc โ€” UnmanagedCallersOnly function pointers avoid marshaling overhead
  • OptimizationPreference=Size + InvariantGlobalization + stripped diagnostics

Special thanks to Michal Strehovskรฝ โ€” the architect of .NET Native AOT โ€” whose PR #5 inspired the final round of optimizations that eliminated the JSON source generator, reflection, and managed delegates. When the person who built the AOT compiler optimizes your app, you pay attention. ๐Ÿ™

License

MIT