feat(backdrop): Capture Window… in-app window pin (TASK 38, Good Dog ONE test)

Click-to-pin an open window as the full-bleed Live backdrop, via the existing
window:<hwnd> capture path (same render layer as game/desktop). Session-scoped:
window:/picker: keys heal to auto on reload (HWND-recycle hazard); pin wins
while the window enumerates, then auto-fallbacks (game → desktop → static); a
dead window's capture session heals to auto, no dead ends.

Fix: ScreenCaptureSourceFactory.Resolve hex-parsed "window:0x<Hwnd>" WITHOUT
stripping the 0x prefix — NumberStyles.HexNumber rejects it, so every pin
resolved null ("No capture target for this key") and the heal silently rolled
back. Same flaw in IsAliveWindowPin (pin-wins guard was dead). Both fixed.

Commit also carries an out-of-scope prerequisite: PillRadioTests.cs:105 had a
committed stray token ("...PrimaryStartButtonLabel soil;", CS1003) blocking the
whole test-project compile — token removed.

Plus the previous session's uncommitted pricing docs (one-time $29/$49) that
share TASKS.md/ai.md/HANDOFF.md.
This commit is contained in:
2026-09-22 07:00:47 -07:00
parent 523c17b7da
commit 4e0915a36e
19 changed files with 665 additions and 67 deletions
+5 -1
View File
@@ -38,7 +38,11 @@ public sealed class ScreenCaptureSourceFactory
if (key.StartsWith("window:", StringComparison.OrdinalIgnoreCase))
{
var hexText = key.AsSpan("window:".Length);
// Keys are written as "window:0x<Hwnd:X>" (CaptureInterop/WindowInfo),
// but NumberStyles.HexNumber does not accept the "0x" prefix — strip it.
var hexText = key.AsSpan("window:".Length).TrimStart();
if (hexText.Length >= 2 && hexText[0] == '0' && (hexText[1] == 'x' || hexText[1] == 'X'))
hexText = hexText[2..];
if (long.TryParse(hexText, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var hwnd))
return ScreenCaptureFrameSource.CreateForWindow(new IntPtr(hwnd));
return null;