feat(cef): open OAuth popups as native windows (fixes Google/Firebase sign-in)#22
Merged
Merged
Conversation
… sign-in) The OSR host cancels ordinary popups and loads their URL in-place. That's fine for target=_blank links, but it BREAKS popup-based sign-in (Google Identity / Firebase signInWithPopup): those open a real popup that authenticates, then postMessages the credential back to window.opener and closes. An in-place navigation has no opener and destroys the page waiting for the message — the flow hangs (e.g. stuck at accounts.google.com/gsi/transform). For a SIZED popup (WOD_NEW_POPUP — the shape OAuth uses), let CEF create a REAL popup browser hosted windowed in a transient NSWindow (SetAsChild). window.opener / postMessage / window.close all work natively, and it shares the parent's request context (cookie jar), so an existing Google session is recognized. Plain target=_blank / new-tab dispositions keep the in-place behavior. - PopupClient: dedicated client (no OSR render handler → CEF renders natively), owns the NSWindow lifecycle. NOT the parent's HostClient — sharing it would run OnBeforeClose against the parent's slot on popup close and unroute the tile. - FCPopupWindowDelegate: routes a user window-close through CloseBrowser; an `alive` gate (cleared in DoClose, before CEF destroys the browser) keeps a synthesized close-button press from dereferencing a dangling browser. - OnBeforeClose defers the window close/release off CEF's teardown stack. Validated (example app + CDP, synthetic user gesture): a popup-disposition window.open now opens a native window (was: window.open()===null, diverted in-place); window.opener is present + postMessage-capable; window.close() tears the window down cleanly with cef_host surviving. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Signing into a site with Google inside a CEF webview hangs — e.g. stuck at
https://accounts.google.com/gsi/transform. Logging into google.com/YouTube directly works.Root cause: the OSR host's
OnBeforePopupcancels every popup (return true) and forwards the URL to the host to load in the same view. That's fine fortarget=_blanklinks, but popup-based OAuth (Google Identity / FirebasesignInWithPopup) opens a real popup that authenticates, thenpostMessages the credential back towindow.openerand closes. Loaded in-place, there's no opener and the original page is gone → the transform/handler page has nothing to message → hang.Confirmed via CDP with a synthetic user gesture:
window.open(...)returnednull(popup cancelled), the URL was diverted to the host, and no popup window was ever created.Fix
For a sized popup (
WOD_NEW_POPUP— the shape OAuth uses), let CEF create a real popup browser hosted windowed in a transientNSWindow(SetAsChild).window.opener/postMessage/window.closeall work natively, and it shares the parent's request context (cookie jar) so an existing Google session is recognized. Plaintarget=_blank/ new-tab dispositions keep the existing in-place behavior.PopupClient— dedicated client (no OSR render handler → CEF renders natively), owns theNSWindowlifecycle. Deliberately not the parent'sHostClient: sharing it would runOnBeforeCloseagainst the parent's slot on popup close and unroute the tile.FCPopupWindowDelegate— routes a user window-close throughCloseBrowser; analivegate (cleared inDoClose, before CEF destroys the browser) prevents a synthesized close-button press from dereferencing a dangling browser.OnBeforeClosedefers the window close/release off CEF's teardown stack.Native-only; no wire-protocol change.
Validation (example app + CDP)
window.open(popup)returnsnull(cancelled)Windowwindow.openeron popuppostMessage-capablewindow.close()🤖 Generated with Claude Code