Fix stale Chromium composer page during pane holds

Merged
TE
7d ago
+240-9

Summary

Leo (2026-10-29): “Dude, I hate how the fing composer acts like this... Number one: the fing rendering is stupid as hell.”

The stale second composer came from a native Chromium page window surviving a paint hold. PanePaintHold hid the app view with alphaValue, but Chromium renders in a separate child window and AppKit does not propagate ancestor alpha to that window. The old page therefore stayed composited over the live chat. Launch images also remained valid across a pane resize even though their captured width was stale.

This PR synchronizes Chromium visibility with ancestor alpha during paint holds, release, and page attach/hide/unhide; queues host visibility when a CEF tab is concealed; and clears launch images when the pane content size changes or the live page paints. Focused regressions cover Chromium visibility, CEF conceal ordering, and launch-image resize invalidation.

Validation

  • python3 scripts/cmux-next/prepush-gate.py --base origin/feat-cmux-next --head HEAD — no new violations (existing warnings only).
  • Linux Swift package checks passed for portable packages; CmuxNext is macOS-only.
  • Focused CmuxNext suites are dispatched through the fleet route: PageWebViewChromiumTests, CEFDeferredTabShowTests, and LaunchFirstFrameRevealTests.

Proof

Before: the native hold made the app view transparent while its separate Chromium child window stayed visible, allowing an idle stale chat to cover the live composer.

After: hold transitions explicitly hide the Chromium page window, release re-shows only the incoming page, conceal queues the host hide, and a resize drops the old-size launch snapshot.

No capture: the native Chromium child-window lifecycle requires a fleet macOS build; the focused fleet tests provide the regression evidence.

Agent session: agent session

Agent session: agent session