Skip to content

fix(desktop): stabilize adopted browser-webview lifecycle #123

Description

@slashdevcorpse

Problem

The desktop browser replaces a temporary manager-owned runtime with a renderer-owned <webview>. Three lifecycle races can leave the browser blank, overwrite the active tab with stale load state, or keep an adopted guest alive during shutdown:

  • An adopted guest starts at about:blank. If it emits loading state before the managed destination commits, runtime sync can replace the intended tab URL with about:blank; the renderer then treats the tab as empty and detaches the guest, aborting navigation.
  • A replaced runtime's pending loadURL() can resolve or reject after takeover and update the active tab even though that runtime is no longer authoritative.
  • Full manager disposal drops renderer-owned runtime references without closing their guest WebContents, while normal detach correctly needs to leave renderer ownership intact.

This behavior was identified in the broad PR #48 branch but is independent of its superseded Windows provider architecture. Reimplement it as a focused fresh-main fix.

Required behavior

  • While an adopted guest is loading at about:blank and the tab still has a managed destination, preserve the managed URL and keep lastCommittedUrl unset until a real page commits.
  • After loadURL() settles, synchronize success or failure only if the runtime is still the current entry for that tab and its WebContents is alive.
  • On full DesktopBrowserManager.dispose(), close adopted renderer guests through the existing race-tolerant unmanaged close path and continue cleanup if one guest is destroyed concurrently.
  • Keep normal detachWebview() behavior non-destructive; renderer-owned guests must not be closed on an ordinary detach.

Likely scope

Acceptance

  • An adopted inert guest emitting did-start-loading preserves the managed target, keeps lastCommittedUrl null, and remains loading.
  • Late rejection or fulfillment from a replaced runtime cannot change the adopted runtime's URL, loading, error, history, or queued state sync.
  • Full disposal closes every adopted guest, clears manager runtime/state maps, and tolerates a concurrent destruction race.
  • Normal detach removes manager ownership/listeners without closing the renderer guest.
  • Existing committed-document rejection, cross-tab reassignment, local-preview guard, and manager-owned cleanup tests remain green.
  • Add the real installed browser-pane navigation/quit scenario to test(windows): qualify the installed NSIS release artifact end to end #11 rather than reviving PR test: harden cross-platform CI and packaged E2E #48's broad E2E harness.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions