TASKS.md is now the index (status table, open items, research pointer). 33 files: 32 task files + 1 research facts file. The full take-saga narrative and all design decisions are preserved verbatim; the catalog makes the queue readable without opening every task body. Schema and AGENTS.md updated to reflect the new layout.
3.2 KiB
TASK 17 — Web source rendering (WebView2)
Catalog:
TASKS.md— status and requirements live here.
Goal: make the web source actually render URLs into the preview and stream output.
Status: ✅ Done — required for v1 (2026-08-28)
- ✅ Add
Microsoft.Web.WebView2NuGet package - ✅ Schema v10:
WebUri TEXTcolumn onSourcetable + migration inLayoutStore.cs - ✅ Persist
Source.WebUrion save/load (currently in-memory only — lost on restart) - ✅ Hidden off-screen
WebView2control per web source — navigates toWebUri, renders in-app - ✅ Frame capture from WebView2 (
CoreWebView2.CapturePreviewAsync) →WriteableBitmap(BGRA8) - ✅ Wire into
FramePumpresolver —Source { Type: WebSource }→ latest WebView2 frame - ✅ Wire into
SceneCompositor— render web source as an image element at its position/size - ✅ Preview shows live web content (not just a blank rectangle)
- ☐ Handle navigation errors, invalid URIs, timeout gracefully
Rendering model (2026-08-28, canvas-size viewport + ALPHA-BBOX crop — DONE, creator-verified):
the page renders at the MASTER CANVAS size (1920×1080), stable, never tracked (no reflow/truncation;
scrollbars suppressed via overflow:hidden). FindContentBounds scans the Bgra32 capture and crops
to the bounding box of non-transparent pixels — the widget's true rendered extent, measured from the
frame itself (NO DOM query, immune to layout timing; can never truncate content; full-canvas widgets
fall through to the full frame = prior verified-good image). Stretch="Fill" maps the cropped frame
flush under the selection box → box hugs the widget on all four sides. QueryContentBoundsAsync +
the JS content-bounds script are DELETED. RESULT: bounding verified PERFECT by the creator with
two widgets. Root-cause note on the earlier "remaining defect/gap": that was a WIDGET GLOW EFFECT
(the widget's own CSS glow pushes out its perceived borders), not a code bug — the alpha-bbox was
already hugging the glow halo. Lesson: test with a second, plain widget before changing code.
⚠️ Lesson bank: never return JSON.stringify from ExecuteScriptAsync (double-encodes); never
measure DOM stuff on NavigationCompleted (unsettled layout broke the image — a5b9952); avoid
sizing the container to the crop (ab29ec8 reverted — made it worse); a widget glow effect can
fake a gap — verify with a plain widget first; measure rendered pixels instead.
Properties panel (2026-08-28): web URI ✓/✕ icon buttons are IsTabStop="False" so Tab flows
X→Y→W→H→URI; the ✕ button now clears the URI textbox (was reverting to the pre-accept snapshot).
Slider style gained IsMoveToPointEnabled="True" — click-anywhere-on-bar jumps the thumb to the
click (volume sliders keep their manual SetSliderValueFromClick, harmless duplication).
Design decisions
- WebView2 is the only option for Windows — it's pre-installed on Windows 10 20H2+ and Windows 11
- The web source is a standard element — positioned/sized/opacitied like any image source
- Frame capture rate can be lower than video FPS (5-10 fps for web content is fine)
- This enables Streamlabs/StreamElements overlays via web URLs