Skip to content

fix(engine): prevent page background bleed on system Chrome macOS#1700

Closed
miga-heygen wants to merge 3 commits into
mainfrom
fix/system-chrome-surface-height
Closed

fix(engine): prevent page background bleed on system Chrome macOS#1700
miga-heygen wants to merge 3 commits into
mainfrom
fix/system-chrome-surface-height

Conversation

@miga-heygen

Copy link
Copy Markdown
Contributor

Summary

Fixes #1699. On macOS, when the render falls back to system Google Chrome (no chrome-headless-shell installed), every frame gets a solid horizontal band of the page's <body> background color across the bottom ~85px. Preview is fine; the band only appears in the rendered video.

Root cause

System Chrome's "new headless" mode on macOS creates a virtual window whose --window-size sets the outer dimensions including title bar + tab strip (~85px). The compositor surface ends up shorter than the 1080px viewport set by page.setViewport(). When Page.captureScreenshot clips to the full 1080px, the gap between the surface and the clip fills with the page's canvas background color (propagated from body { background }), producing the band.

chrome-headless-shell has no window decorations, so the full --window-size is content area — which is why installing it fixes the issue.

Fix

Two-pronged:

  1. Root cause (browserManager.ts): Inflate --window-size height by 200px when not using chrome-headless-shell. The generous buffer accounts for varying OS/Chrome decoration heights across macOS, Windows, and future Chrome versions. page.setViewport() still constrains the layout viewport to the exact composition dimensions — the extra window height just ensures the compositor surface is never shorter.

  2. Defense-in-depth (screenshotService.ts + frameCapture.ts): Set Emulation.setDefaultBackgroundColorOverride to transparent on opaque capture sessions (not just PNG/alpha). This is set once at session init (zero per-frame overhead). If any future edge case produces a clip-vs-surface mismatch, the gap composites to white (JPEG) or transparent (PNG) instead of the page's arbitrary background color.

Test plan

  • 3 new unit tests for buildChromeArgs window-size height buffer (headless-shell exact, system Chrome inflated, default inflated)
  • 1 new unit test for initOpaqueBackgroundOverride (verifies CDP call)
  • All existing engine tests pass (24/24 browserManager, 13/13 screenshotService — 2 pre-existing failures unrelated to this change)
  • Build passes
  • Manual verification on macOS with system Chrome (I'm on Linux — cannot reproduce the macOS-specific surface height issue here)

Verification instructions (macOS)

  1. On a Mac with no chrome-headless-shell installed (hyperframes browser ensure reports Source: system)
  2. Create any 1920×1080 composition with a visible <body> background (e.g. body { background: #FAF9F5 })
  3. npx hyperframes render . on this branch
  4. Inspect any frame — the bottom band should be gone (gradient/content extends to the full 1080px edge)

— Miga (https://claude.com/claude-code)

miga-heygen and others added 3 commits June 24, 2026 13:23
)

System Chrome's "new headless" mode on macOS includes window decorations
(title bar + tab strip, ~85px) in the --window-size outer dimension,
making the compositor surface shorter than the viewport set by
page.setViewport(). The bottom gap fills with the page's canvas
background color, producing a visible band in every rendered frame.

Two-pronged fix:
1. Inflate --window-size height by 200px when not using chrome-headless-shell,
   ensuring the content area always exceeds the requested viewport.
2. Set Emulation.setDefaultBackgroundColorOverride to transparent on opaque
   capture sessions (defense-in-depth), so any residual clip-vs-surface
   mismatch produces transparent pixels instead of the page background.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…1699)

Minimal 1920×1080 composition with body { background: #FAF9F5 } and a
full-bleed gradient + a pink bar at the very bottom edge. On macOS with
system Chrome (no headless-shell), the before state shows a ~85px beige
band clipping the pink bar; the fix makes gradient + bar extend to the
full 1080px edge.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Render fills the bottom ~85px of every frame with the page background color when falling back to system Chrome (preview is fine)

2 participants