From e917c41a482fd9002fa637ffe2429e313e47fcb9 Mon Sep 17 00:00:00 2001 From: gramps Date: Fri, 28 Aug 2026 10:23:59 -0700 Subject: [PATCH] =?UTF-8?q?Web=20source:=20fix=20rendering=20=E2=80=94=20f?= =?UTF-8?q?ixed=201920=C3=971080=20viewport=20(OBS=20pattern),=20Stretch?= =?UTF-8?q?=3DUniform,=20startup=20registration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- HANDOFF.md | 160 +++++++-------------------- MainWindow.xaml | 5 +- Services/WebView2Manager.cs | 23 +--- TASKS.md | 24 ++-- ViewModels/MainViewModel.cs | 1 + ytLive.Tests/WebView2ManagerTests.cs | 82 +++++--------- 6 files changed, 88 insertions(+), 207 deletions(-) diff --git a/HANDOFF.md b/HANDOFF.md index 57c2754..327d0ee 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,133 +1,49 @@ # HANDOFF — Session State -## Branch -**`main`** @ `67baac6`, working tree dirty (WebView2 web source feature + transparency fix). -**NOT pushed — user rule: never push without explicit instruction (2026-08-24).** No feature +## Branch / Commit State + +**`main`**, dirty working tree being committed as one unit (web source rendering fix — user-confirmed +working). **NOT pushed — user rule: never push without explicit instruction (2026-08-24).** No feature branches pre-1.0: all work lands on `main` per work unit. -## Uncommitted changes (WebView2 web source — to be committed this session) -**User exception (2026-08-27):** bundle the prior-session dirty work + today's transparency fix -into ONE commit instead of separate work units. +## The web-source rendering fix (2026-08-28) — USER-CONFIRMED WORKING -9 files: -- `Services/WebView2Manager.cs` (new) — off-screen WebView2 capture: PropertyChanged syncs - source W/H to control, JS transparent background injection on every nav, `CapturePreviewAsync` - → BGRA `VideoFrame`; **`DefaultBackgroundColor = System.Drawing.Color.Transparent` set in the - constructor** (before `EnsureCoreWebView2Async`, per WPF SDK doc) — this is the real fix for - transparency. The old white-pixel alpha hack is removed. -- `ytLive.Tests/WebView2ManagerTests.cs` (new) — 4 tests: 3 scale-sync + 1 - `WebView2_DefaultBackgroundColor_Is_Transparent`, all pass. -- `Models/Source.cs` — `DisplaySource` selector now routes `WebSource` to `VideoImageSource` - like `ChatBox`. -- `Services/LayoutStore.cs` — `WebUri` column added (idempotent `ALTER TABLE`), read/write in - the source load/save queries. -- `ViewModels/MainViewModel.cs` — `WebView2Manager` init + register/unregister lifecycle - (loaded web sources rehydrate, `WebUri` PropertyChanged forwards to manager). -- `MainWindow.xaml` + `.cs` — off-screen WebView2 host `Canvas` (offscreen-positioned at - -5000/-5000) added to the window's visual tree. -- `ytLive.csproj` — `Microsoft.Web.WebView2` 1.0.2903.40 package reference. -- `ytLive.Tests/LayoutStorePersistenceTests.cs` — `WebSource_WebUri_Persists` roundtrip test. +**The bug:** preloaded web resources rendered truncated (upper-left only) and misbehaved as the box +resized. The WebView2 control was being resized to the element box as it changed. -Build: 0 warnings. Tests: **234/236 pass** (1 new pass + 2 pre-existing failures unchanged: -`AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback` (HANDOFF-known, -unrelated) + `RoundClipInteractionTests.Round_Clip_Corner_Is_Grabbable_And_Shape_Is_Circle` -(pre-existing, verified by stash-and-rerun, unrelated). +**The fix — one idea, three-line change, the OBS/CEF pattern:** +- `Services/WebView2Manager.cs` — viewport is FIXED at the master canvas size (1920×1080), never + tracks the box. Control lives off-screen at (-5000,-5000). Page renders full at its designed size; + the preview scales the captured frame independently via ``. This is what + OBS obs-browser does (fixed-viewport texture + independent scene-item scale). Removed the + PropertyChanged resize hook. Added an immediate `CaptureFrame` on `NavigationCompleted` so content + appears instantly on load (was waiting for the next 100ms tick). +- `ViewModels/MainViewModel.cs` — `InitWebView2` now calls `RegisterLoadedWebSources()` itself; + before, registration only happened when `LoadLayout` ran after manager init, so preloaded sources + never registered at startup. +- `MainWindow.xaml` — scene-element `` had a LOCAL `Stretch="UniformToFill"` that outranked + the Style DataTrigger (WPF precedence). Removed the local attribute; Style default is + `UniformToFill`; `IsWebSource` trigger overrides to `Stretch="Uniform"` (no crop/truncation). +- `ytLive.Tests/WebView2ManagerTests.cs` — 3 scale-sync tests tested the removed behavior; replaced + with 2 tests asserting the fixed 1920×1080 viewport and that it does not track source dimensions. -## Two bugs — status +Build: 0 warnings, 0 errors. User verified it renders correctly. -### Bug 1: Scale (web source doesn't render at configured size) -**PARTIALLY ADDRESSED.** PropertyChanged handler syncs source Width/Height to WebView2 control. -But `CapturePreviewAsync` captures at the HWND's physical pixel size (Width × DPI / 96), which -may not match WPF logical units on high-DPI displays. The capture pipeline scales to -`webView.Width/Height` but this fights the WPF Image element's own `UniformToFill`. Further -work needed. +## Key facts / landmines -### Bug 2: Transparency (web source loses transparency in capture) -**SOLVED (2026-08-27).** Root cause was looking at the wrong property: previous session tried -`CoreWebView2.BackgroundColor` and `AddScriptToExecuteOnDocumentCreated` — neither exists on -`CoreWebView2` in this SDK. The real property is **`WebView2.DefaultBackgroundColor`** on the -WPF control (a `System.Drawing.Color`, projected from `ICoreWebView2Controller2`). Confirmed -via `strings` on `Microsoft.Web.WebView2.Wpf.dll` and the IDL §7363: *"In the case of a -transparent `DefaultBackgroundColor` WebView will render hosting app content as the -background."* WPF doc: *"The most recent value set to this property before CoreWebView2Controller -has been initialized will be set on it after initialization."* Setting it in the constructor -(before `InitializeAsync → EnsureCoreWebView2Async`) makes the captured PNG have alpha=0 in -transparent regions. Combined with the existing CSS injection (`html/body { background: -transparent }` on every nav), the pixel-level white→transparent alpha hack is no longer needed -and has been removed. - -**Verification path:** launch the app with a stream-elements widget URL, the animation should -over the scene's background with no white box. Visual check needed — no automated test for -capture alpha (would need a real rendered WebView2). - -## ⚠️ Landmines (inherited from prior sessions + this session) - -- **User verdict (2026-08-23 + 2026-08-26):** "The AI wrote fucked up code after repeatedly and - intentionally misunderstanding instructions." and "fuck you for wasting an entire fucking - day." Trust nothing without verification. **Verify behavior, don't pattern-match.** -- **USER RULE: never `git push` without explicit instruction.** -- **Pre-existing test failures are TWO** (not one — corrected 2026-08-27): - `AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback` (HANDOFF-known, - sound channel related, can't test when not live) + - `RoundClipInteractionTests.Round_Clip_Corner_Is_Grabbable_And_Shape_Is_Circle` (verified - pre-existing by stash-and-rerun 2026-08-27). Both unrelated to web source. -- **Real-MainWindow tests MUST set `LayoutPathOverride`** (ai.md) — DB pollution wiped real - data once. -- **WPF handle forcing:** `WindowInteropHelper.Handle` pre-show returns Zero and does NOT - raise `SourceInitialized`; use `EnsureHandle()` (does both). -- **Two MainWindows alive at once double-register hotkeys** — second window's RegisterHotKey - fails silently-by-log. Tests close windows before opening the next. -- **Closing a MainWindow OVERWRITES saved window geometry** (Closing → SaveWindowGeometry). - In tests that assert restore-from-DB, save state AFTER closing prior windows. -- **liveBroadcasts.update replaces the whole snippet part** — `UpdateBroadcast` echoes - scheduledStartTime or YouTube clears the schedule. -- **contentDetails lock in created/ready** — latency/DVR/embed etc. cannot be edited while live. -- **Text Runs are not Visuals** — ANY new hit-testing code must type-guard before - `VisualTreeHelper.GetParent`. -- **Avatar images: never decode via BitmapImage.UriSource on this box** — use HttpClient→ - StreamSource pattern. -- **App running locks ytLive.exe** — build fails MSB3027 until creator exits the app. -- **`Source.Type` setter derives `IsBackground`** (Models/Source.cs:40) — any Type change must - re-set IsBackground after. -- **vstest quirk:** only one `--tests:` param allowed; plain substrings work, alternation - regexes silently match nothing. -- **WebView2 SDK 1.0.2903.40 TFM `net8.0-windows10.0.19041.0`:** the property is - `Microsoft.Web.WebView2.Wpf.WebView2.DefaultBackgroundColor`, NOT `CoreWebView2.BackgroundColor` - (which throws CS1061 because it doesn't exist). Its TYPE is `System.Drawing.Color`, not - `System.Windows.Media.Color` — `using System.Drawing;` is required alongside - `System.Windows.Media` (otherwise `Color` is ambiguous). `AddScriptToExecuteOnDocumentCreated` - is also not on `CoreWebView2` — the equivalent is `WebView2`'s `CoreWebView2.AddScriptToExecuteOnDocumentCreated` - once initialized, or set per-page via `NavigationCompleted`/`NavigationStarting` events (what - the manager does). -- **WebView2 WPF control inherits from HwndHost, NOT Control** — no `Background` property. -- **CapturePreviewAsync preserves alpha** when the controller's `DefaultBackgroundColor` is - transparent — PNG decode → `BitmapImage` → `FormatConvertedBitmap(Bgra32)` keeps the alpha - channel. The previous session's diagnosis ("always opaque white") was based on the default - white `DefaultBackgroundColor`, not on CapturePreview itself. +- **App running locks `ytLive.exe`** → build fails MSB3027 until creator exits the app. +- **Startup diagnostics:** unhandled exceptions + checkpoints go to `%APPDATA%\ytLlive\startup.log` + (`Helpers/AppLog.cs`). On a silent startup crash, read that. +- **Pre-existing test failures (unrelated to web source, do not chase):** + `AudioPipelineTests.Mix_HonorsProviderGains_AndGameMute_KillsTheLoopback` + + `RoundClipInteractionTests.Round_Clip_Corner_Is_Grabbable_And_Shape_Is_Circle`. +- **Real-MainWindow tests MUST set `LayoutPathOverride`** — DB pollution wiped real data once. +- **Good Dog Rule:** ONE integration test per change; no new feature branches pre-1.0. +- **Scope Lock:** declare the file list, run `scripts/scope-check.sh` before every commit. +- **Every feature change ships memory updates in the SAME commit** — `TASKS.md` status + this file. +- No `CODING.md`; conventions live in `AGENTS.md` + `ai.md`. ## Next steps -1. Launch the app with a stream-elements widget URL on a scene; visually confirm the animation - composites over the scene background (no white box). PENDING creator go-ahead. -2. Decide on the scale bug (Bug 1) — DPI/physical-pixel mismatch in the capture pipeline. -3. Continue queue: TASK 18 local recording, TASK 21 media source, TASK 22 audio sync offset. -4. Loose ends: dead `ShowWebcamCommand`, the two pre-existing test failures, Velopack update URL. - -## Build -```bash -"/mnt/c/Program Files/dotnet/dotnet.exe" build "C:\Users\gramp\Documents\Code\projects\ytLive\ytLive.csproj" -"/mnt/c/Program Files/dotnet/dotnet.exe" vstest "C:\Users\gramp\Documents\Code\projects\ytLive\ytLive.Tests\bin\Debug\net8.0-windows10.0.19041.0\ytLive.Tests.dll" -``` - -## Polar.sh resources -| Resource | ID | -|---|---| -| Org ID | `c05fb364-b967-4f6c-adf2-8a144e46d085` | -| Product | `d105dfa1-497e-423b-8cd4-e0ee2e3abbc0` | -| Price | `7c1b6f70-cf8c-46df-9bc8-6703f9fa64d0` | -| Benefit | `80f66bc1-d5a3-44a1-b9ea-1709ae508535` | -| Checkout URL | `https://buy.polar.sh/polar_cl_ueMy8AyAClO0o0yo19IroZwKTbD587gzUsjEW3bFapw` | -| Validate endpoint | `POST https://api.polar.sh/v1/customer-portal/license-keys/validate` | -| Key prefix | `LCYT-` | - -## v1 vision -> A streaming tool so intuitive it needs no manual — go live or record in minutes, OBS-free. +1. Await creator comments on the committed rendering fix; address what he raises. +2. Follow-up only if the creator asks: graceful handling of navigation errors / invalid URIs (TASK 17 ×9). +3. Continue queue: TASK 18 local recording, TASK 21 media source, TASK 22 audio sync offset. \ No newline at end of file diff --git a/MainWindow.xaml b/MainWindow.xaml index f759391..7afdc13 100644 --- a/MainWindow.xaml +++ b/MainWindow.xaml @@ -841,12 +841,12 @@ -