Fix sign-in popups in the desktop browser (#2137)

* fix(desktop): keep sign-in popups connected

Turning every window-open request into a workspace tab severed the opener relationship required by popup authentication flows. Keep script-created and POST-backed opens as secured child windows while ordinary links continue to use workspace tabs.

* fix(desktop): keep Shift-click links in workspace tabs

Electron reports both popup windows and Shift-clicked links as new-window. Use popup features or a named target to preserve script popups without bypassing Paseo tab state for ordinary links.

* fix(desktop): tighten popup profile handling

* fix(desktop): preserve popup feature intent

* fix(desktop): match browser popup heuristics
This commit is contained in:
Mohamed Boudra
2026-07-16 18:45:32 +02:00
committed by GitHub
parent 0d3b717cf3
commit ccf29f4c50
7 changed files with 353 additions and 59 deletions
+79 -13
View File
@@ -49,9 +49,9 @@ import { registerEditorTargetHandlers } from "./features/editor-targets/ipc.js";
import { setupApplicationMenu } from "./features/menu.js";
import {
BROWSER_NEW_TAB_REQUEST_EVENT,
decideBrowserWindowOpenRequest,
getPaseoBrowserIdForWebContents,
getPaseoBrowserWebContents,
handleBrowserWindowOpenRequest,
listRegisteredPaseoBrowserIds,
isPaseoBrowserWebviewAttach,
preparePaseoBrowserWebContents,
@@ -64,6 +64,7 @@ import {
import {
clearPaseoBrowserProfile,
getLegacyPaseoBrowserProfileSession,
PASEO_BROWSER_PROFILE_PARTITION,
getPaseoBrowserProfileSession,
getPaseoBrowserProfileSessions,
listPaseoBrowserProfileGuests,
@@ -226,6 +227,79 @@ function showBrowserWebviewContextMenu(
menu.popup({ window: win });
}
function getBrowserPopupWindowOptions(
mainWindow: BrowserWindow,
): Electron.BrowserWindowConstructorOptions {
return {
parent: mainWindow,
show: true,
autoHideMenuBar: true,
webPreferences: {
partition: PASEO_BROWSER_PROFILE_PARTITION,
nodeIntegration: false,
nodeIntegrationInSubFrames: false,
nodeIntegrationInWorker: false,
contextIsolation: true,
sandbox: true,
webSecurity: true,
webviewTag: false,
allowRunningInsecureContent: false,
},
};
}
function installBrowserWindowOpenHandler(input: {
contents: Electron.WebContents;
sourceContents: Electron.WebContents;
mainWindow: BrowserWindow;
}): void {
const { contents, sourceContents, mainWindow } = input;
contents.setWindowOpenHandler(({ url, disposition, frameName, features, postBody }) => {
const decision = decideBrowserWindowOpenRequest({
url,
disposition,
frameName,
features,
hasPostBody: postBody !== undefined && postBody !== null,
});
if (decision.kind === "deny") {
return { action: "deny" };
}
if (decision.kind === "popup") {
return {
action: "allow",
overrideBrowserWindowOptions: getBrowserPopupWindowOptions(mainWindow),
};
}
const sourceBrowserId = getPaseoBrowserIdForWebContents(sourceContents);
if (sourceBrowserId) {
mainWindow.webContents.send(BROWSER_NEW_TAB_REQUEST_EVENT, {
sourceBrowserId,
url: decision.url,
});
} else {
pendingBrowserWindowOpenRequests.add(sourceContents.id, decision.url);
}
return { action: "deny" };
});
contents.on("did-create-window", (popupWindow) => {
const popupContents = popupWindow.webContents;
registerBrowserWebviewNavigationGuards(popupContents);
popupContents.on("context-menu", (_event, params) => {
showBrowserWebviewContextMenu(popupWindow, popupContents, params);
});
installBrowserWindowOpenHandler({
contents: popupContents,
sourceContents,
mainWindow,
});
});
}
// In dev mode, detect git worktrees and isolate each instance so multiple
// Electron windows can run side-by-side (separate userData = separate lock).
let devWorktreeName: string | null = null;
@@ -722,18 +796,10 @@ async function createWindow(
});
}
});
contents.setWindowOpenHandler(({ url }) => {
const sourceBrowserId = getPaseoBrowserIdForWebContents(contents);
if (!sourceBrowserId) {
pendingBrowserWindowOpenRequests.add(contents.id, url);
}
return handleBrowserWindowOpenRequest({
url,
sourceBrowserId,
requestNewTab: (payload) => {
mainWindow.webContents.send(BROWSER_NEW_TAB_REQUEST_EVENT, payload);
},
});
installBrowserWindowOpenHandler({
contents,
sourceContents: contents,
mainWindow,
});
contents.on("context-menu", (_contextMenuEvent, params) => {
showBrowserWebviewContextMenu(mainWindow, contents, params);