From b862a0fb0409ba6a42f9a6f42fec3071384dd21f Mon Sep 17 00:00:00 2001 From: gramps Date: Fri, 28 Aug 2026 11:35:30 -0700 Subject: [PATCH] =?UTF-8?q?Web=20source:=20revert=20crop=20measurement=20t?= =?UTF-8?q?o=20f39ebd9=20scrollWidth/Height=20(nailed=20right/bottom)=20?= =?UTF-8?q?=E2=80=94=20canvas-size=20render=20untouched?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ContentBoundsScript back to scrollWidth/scrollHeight extents, kept as a real JS object (the JSON.stringify double-encode bug that silently disabled the crop stays fixed). - Crop again from (0,0), no X/Y offset. The union-of-elements approach (582d1f4) created an all-sides gap by including invisible full-canvas wrappers; revert to the proven code. --- MyMistakes.md | 16 +++++++++--- Services/WebView2Manager.cs | 50 ++++++++++--------------------------- 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/MyMistakes.md b/MyMistakes.md index b500a8c..5de9841 100644 --- a/MyMistakes.md +++ b/MyMistakes.md @@ -30,7 +30,15 @@ Stream widget bounding box: hug the widget on all four sides, pinned to canvas ( wasn't 0,0. Same silent JSON bug — the crop still never executed — and the measure was scroll extents regardless. Lesson: verify declared mechanics actually execute; assume nothing ran. -## Current iteration (`582d1f4`) -Script returns a real object: the union of every visible `body *` `getBoundingClientRect` (the -widget's true rect including its top‑left offset). `CaptureFrame` crops AT that offset; Fill maps -the frame flush under the box. Committed, not pushed, visual verification pending. \ No newline at end of file +## Current iteration (web bounding box — committed, NOT pushed, verification pending) +- Render stays the confirmed-solid 1920×1080 canvas-size viewport + `Stretch="Fill"` (UNTOUCHED). +- Crop BEHAVIOR restored to f39ebd9 exactly: capture cropped from (0,0) to + `scrollWidth/scrollHeight` extents — the code that nailed right/bottom. Real-object return + keeps the crop actually executing (past cause: JSON.stringify double-encode silently disabled it). + +## Iteration that just failed (`582d1f4` — union of every `body *` element rect) +Gap moved to ALL sides. The union includes invisible full-canvas layout wrappers, so the crop rect +came out larger than the visible widget; the offset crop (+ Rewatched fills from a subset of the +canvas. Over-engineering: the fix that already worked was f39ebd9's simple scroll-extents crop. +Creator's instruction: go back to that code. DONE — do not re-introduce element-union measuring. +Lesson: when a prior iteration is declared good, REVERT TO IT; do not build a cleverer replacement. \ No newline at end of file diff --git a/Services/WebView2Manager.cs b/Services/WebView2Manager.cs index f8ff32f..9a60464 100644 --- a/Services/WebView2Manager.cs +++ b/Services/WebView2Manager.cs @@ -29,8 +29,6 @@ public sealed class WebView2Manager : IDisposable public VideoFrame? LatestFrame; public double ViewportCssW; public double ViewportCssH; - public double ContentCssX; - public double ContentCssY; public double ContentCssW; public double ContentCssH; public bool Disposed; @@ -165,33 +163,15 @@ public sealed class WebView2Manager : IDisposable // viewport for widgets that don't fill it — the leftover area is dead space // that must not stretch across the selection box. Crop the capture to the // content bounds (anchored at 0,0) so the box shows exactly the widget. - // The widget's ACTUAL visible content bounds — the union of every visible - // body rectangle (getBoundingClientRect). This is the real widget rect, - // excluding the page's own margins/dead space, with its top-left offset. - // A real object is returned (NOT JSON.stringify — ExecuteScriptAsync - // JSON-encodes the result, which would double-encode a string). + // This restores f39ebd9's measurement (scrollWidth/Height), which the + // creator confirmed nailed the right and bottom of the box. The result is + // returned as a real JS object, NOT JSON.stringify — ExecuteScriptAsync + // JSON-encodes the result, so stringifying would double-encode and the + // JSON parse would throw, silently disabling the crop. private const string ContentBoundsScript = - "(function(){" + - "var rs=[];var body=document.body;" + - "if(body){var br=body.getBoundingClientRect();if(br.width||br.height)rs.push(br);}" + - "var els=document.querySelectorAll('body *');" + - "for(var i=0;i= 1 && session.ViewportCssH >= 1 && session.ContentCssW >= 1 && session.ContentCssH >= 1) { var sx = pixW / session.ViewportCssW; var sy = pixH / session.ViewportCssH; - cropX = (int)Math.Clamp(Math.Round(session.ContentCssX * sx), 0, pixW - 1); - cropY = (int)Math.Clamp(Math.Round(session.ContentCssY * sy), 0, pixH - 1); - cropW = (int)Math.Clamp(Math.Round(session.ContentCssW * sx), 1, pixW - cropX); - cropH = (int)Math.Clamp(Math.Round(session.ContentCssH * sy), 1, pixH - cropY); + cropW = (int)Math.Clamp(Math.Round(session.ContentCssW * sx), 1, pixW); + cropH = (int)Math.Clamp(Math.Round(session.ContentCssH * sy), 1, pixH); } var outPixels = pixels; - if (cropW != pixW || cropH != pixH || cropX != 0 || cropY != 0) + if (cropW != pixW || cropH != pixH) { var dstStride = cropW * 4; outPixels = new byte[dstStride * cropH]; for (var r = 0; r < cropH; r++) - Buffer.BlockCopy(pixels, (cropY + r) * stride + cropX * 4, outPixels, r * dstStride, dstStride); + Buffer.BlockCopy(pixels, r * stride, outPixels, r * dstStride, dstStride); } var wb = new WriteableBitmap(cropW, cropH, 96, 96, PixelFormats.Bgra32, null);