TGViewer
C++ - Reddit C++ - Reddit @r_cpp · 230 subscribers
Post #25417 11
Spatial Canvas: a single-file C++/Win32/Direct3D 11 zoomable window manager that puts your live windows on an infinite canvas

I've been building a zoomable-UI (ZUI) window manager for Windows in C++ and

wanted to share the architecture, since the interesting part is how you keep

dozens of live windows rendering at once.



Each window is captured via Windows.Graphics.Capture (FreeThreaded frame pool,

poll-based, lock-free) into a persistent D3D11 texture, then drawn as a

1:1-pixel textured quad in world space on a borderless fullscreen swapchain.

Pan/zoom is just a camera transform. A D2D/DWrite overlay draws the rest:

title labels, a world-anchored dot grid, the minimap, docks.



The hard problem: if you move/hide windows off-screen to composite them, DWM

occlusion-throttles them and Windows.Graphics.Capture starts returning black

or stale frames. Your canvas fills with black tiles. So there is no input

simulation and no off-screen hiding. Instead, each window "parks" in a 2px

visible strip at the bottom of the primary monitor — 2px is enough that DWM

keeps compositing it, so the capture stays live, but it's hidden behind the

canvas. When you cross a zoom threshold (or double-click), the real HWND is

moved (SetWindowPos) onto its quad's screen rect and given focus; now you're

typing into the actual window, not a proxy. Pull back and it returns to the

strip. Two states per window: parked (live texture on the canvas) and

swapped-in (the real window).



Other bits:

\- Single translation unit (\~3300 lines, Canvas.cpp), entry RunCanvasApp().

\- Idle-throttled main loop (dirty flag + MsgWaitForMultipleObjectsEx) so it

doesn't burn the GPU when nothing changes.

\- Device-lost (TDR / sleep-wake) does a full D3D/D2D/WGC rebuild; an unhandled-

exception filter un-parks windows on crash so nothing is stranded in the strip.

\- Single 559 KB exe, statically linked — no .NET / VC redist.



A few things that bit me along the way:

\- IsBorderRequired(false) / the borderless-capture path black out capture on

some Windows builds — removed.

\- Content-sized CopySubresourceRegion + a drain-to-newest loop also produced

black tiles; a single TryGetNextFrame + full CopyResource is the proven path.

\- Added a cbuffer field the pixel shader reads, but bound the cbuffer only to

the vertex stage → every tile came out alpha=0 (invisible). If a stage reads

a cbuffer, bind it to that stage.



Repo + 30s demo: https://github.com/13auth/spatial-canvas



It's an early prototype and I'd genuinely appreciate critique on the capture/

compositing approach. (Heads-up: source-available but not OSS-licensed — happy

to explain the reasoning in the comments.)

https://redd.it/1u52eim
@r_cpp
GitHub GitHub - 13auth/spatial-canvas: Spatial Canvas - canli Windows pencerelerini sonsuz zoom'lanabilir tuvale yerlestiren pencere yoneticisi… Spatial Canvas - canli Windows pencerelerini sonsuz zoom'lanabilir tuvale yerlestiren pencere yoneticisi (WGC + park&swap, tek exe) - 13auth/spatial-canvas
More from @r_cpp
  1. Sep 29, 2026Boost.Graph 1.95 will be C++17 Dear Boost.Graph community, In two release cycles (Boost re…
  2. Sep 26, 2026Token Sequence Injection & Modern Macros: The Most Game-Changing Compile-Time Feature in C…
  3. Sep 25, 2026myStringStream.str("") Considered Harmful Under C++20 I was recently looking at some (rath…
  4. Sep 20, 2026A clever branch free optimization I'm the developer of memlz which is an extremely fast co…
  5. Sep 15, 2026Inside Boost.PolyCollection https://bannalia.blogspot.com/2026/09/inside-boostpolycollecti…
  6. Sep 11, 2026C++26: Standard Library Hardening Experiments https://www.cppstories.com/2026/hardening-ex…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →