fix(web): harden the transparency injection to the OBS-standard element-wide !important wipe

The real-widget dumps (12:54/13:50) proved the OLD inline
element.style.background='transparent' injection holds only while the page has
nothing to paint: the capture was alpha-transparent, yet the recording showed a
black opaque box over the whole element rect (1231,679 705x396) once the widget
connected and repainted a container background-COLOR — CapturePreviewAsync always
honors page CSS (MicrosoftEdge/WebView2Feedback specs/BackgroundColor.md), so any
page-painted background wins over DefaultBackgroundColor.

This is the OBS-solved class (all web-uri resources paint their own background):
browser sources use a Custom CSS override, and the decade-validated formula for
arbitrary pages is a pre-parse <style> with 'background-color: transparent
!important' — https://obsproject.com/forum/threads/translucent-transparent-browser-source.59549/
('body { background-color: rgba(0,0,0,0) !important }') plus the div-level variant
for stubborn widgets (woahtech.com OBS custom-CSS guide).

Injection is now an idempotent pre-parse style element wiping background-color on
html,body,html * with !important (outranks every page rule, runs before page parse
via AddScriptToExecuteOnDocumentCreatedAsync). Only background-COLOR is targeted —
background images and widget art survive. Regression test asserts the element-wide
!important form and that the losing inline form is gone.

9/9 WebView2Manager tests, 0 warnings.
This commit is contained in:
2026-09-10 14:04:11 -07:00
parent ea347f211c
commit b4bba4bf68
4 changed files with 106 additions and 66 deletions
+15
View File
@@ -111,6 +111,21 @@ public sealed class WebView2ManagerTests
});
}
[Fact]
public void TransparentBackgroundScript_Is_A_Important_Element_Wide_Wipe()
{
// The regression the inline style lost to: a widget repainting a container (or
// html/body) opaque after connect re-backs the capture → "black box" in the
// recording while early frames stayed transparent. The OBS-validated formula is a
// pre-parse <style> with !important outranking every page rule (OBS Forums 2016).
var script = WebView2Manager.TransparentBackgroundScript;
Assert.Contains("background-color:transparent!important", script);
Assert.Contains("html,body,html *", script);
Assert.Contains("document.createElement('style')", script);
Assert.DoesNotContain(".style.background=", script);
}
[Fact]
public void FindContentBounds_Returns_Bounding_Box_Of_NonTransparent_Pixels()
{