feat: support window.open() popup windows (#1150)

* feat: support window.open() popup windows (#742)

Return a live WKWebView from createWebViewWith using WebKit's supplied
configuration, preserving popup browsing-context semantics (window.opener,
postMessage). This fixes OAuth/OIDC flows and any site relying on standard
popup patterns.

- Add BrowserPopupWindowController: NSPanel-based popup with self-retention,
  KVO title/URL, read-only URL label, nested popup depth limit (3),
  insecure-HTTP prompt parity, auth challenge parity, download delegate
- Classifier: scripted requests (window.open) create popups; user-initiated
  actions (Cmd+click, middle-click, context menu) open tabs
- Retarget context menu "Open Link in New Tab" to bypass createWebViewWith,
  wired in both main browser and popup web views
- Cmd+W fast path in AppDelegate for popup windows
- Opener panel owns popup lifecycle; close() tears down all child popups

* fix: Cmd+W closes only the popup, not the parent tab

Add BrowserPopupPanel (NSPanel subclass) that intercepts Cmd+W in
performKeyEquivalent before the swizzled cmux_performKeyEquivalent
can dispatch it to the main menu's "Close Tab" action.

Also refine the popup classifier to reuse browserNavigationShouldOpenInNewTab
for Cmd+click/middle-click detection, add download delegate wiring, and
wire onContextMenuOpenLinkInNewTab for popup web views.

* fix: tighten popup routing and window behavior

* test: cover oversized popup frame clamping

* test: cover plain link-activated popup routing

---------

Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
This commit is contained in:
Manfred Neustifter 2026-03-16 10:48:05 +10:00 committed by GitHub
parent 1460c97e85
commit 6b138f7d9d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 864 additions and 23 deletions

View file

@ -8350,7 +8350,18 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
event: event,
shortcut: StoredShortcut(key: "w", command: true, shift: false, option: false, control: false)
) {
if let targetWindow = event.window ?? NSApp.keyWindow ?? NSApp.mainWindow,
// Browser popup windows primarily intercept Cmd+W in BrowserPopupPanel.
// This AppDelegate path is a fallback for cases where AppKit routes the
// event through the global shortcut handler first.
if let targetWindow = [NSApp.keyWindow, event.window]
.compactMap({ $0 })
.first(where: { $0.identifier?.rawValue == "cmux.browser-popup" }) {
#if DEBUG
dlog("shortcut.cmdW route=browserPopup")
#endif
targetWindow.performClose(nil)
return true
} else if let targetWindow = event.window ?? NSApp.keyWindow ?? NSApp.mainWindow,
cmuxWindowShouldOwnCloseShortcut(targetWindow) {
targetWindow.performClose(nil)
} else {