Skip to content

CEF (Chromium) multi-tab support — tab new/switch/close on chromium engine #73

Description

@rafiki270

Goal

Make tab management (tab new <url>, switch, close, list) work on the Chromium (CEF) engine. Today these return cefUnsupportedError and Tab is hardcoded to WKWebViewRenderer.

Why deferred

An adversarial design review (Claude + Codex, both NO-GO) on a per-tab-engine / multi-CEF-browser design found it multiplies the documented navigate-while-hidden CrBrowserMain crash. The single-CEF path only survives today because ServerState.switchRenderer carefully sequences deactivate → migrate → wait-for-attachment → activate (+ surface refresh). The tab addTab/activateTab path has none of that choreography. Additional verified blockers:

  • CEFRenderer has no public closeBrowser(); closing a CEF tab risks teardown-while-attached (RendererContainerView never removes CEF views).
  • New-tab-then-immediately-active = navigate-while-hidden GPU-surface transition.
  • switchRenderer cookie/auth migration assumes a single source→target pair.
  • Dropping the wkRenderer singleton breaks the load-bearing serverState.wkRenderer === tab.renderer active-tab state-sync guard and the startup non-nil-renderer invariant.
  • Codex root-cause: using global handlerContext.renderer as both API target and view source; multi-window can reparent a CEF view across containers.

Recommended approach (prototype-first)

  1. Prove the CEF lifecycle in isolation under ASan: two CEFRenderers, route activation through the existing willDeactivate/didActivate/scheduleSurfaceRefresh sequence, never load until onBoundsReady, switch 20× and close one. If unstable → fall back to single CEF browser navigating between tab URLs (descriptors), which removes the concurrency hazards entirely.
  2. Make renderer ownership single-source-of-truth (per-tab) before un-gating handlers.

Acceptance

  • tab new <url> opens and shows the URL on chromium; switch/close/list work; no CrBrowserMain crash across 50 rapid tab ops; WebKit multi-tab unregressed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions