diff --git a/src/main/index.ts b/src/main/index.ts index 718547c8..5cd8ce56 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -31,7 +31,7 @@ import { AgentManager } from '../agent/main/agentManager' // Shared singletons for pi agent + auth. const agentManager = new AgentManager(authManager) import { writeDragTempFile, cleanupDragTempFile, createDragGhostImage } from './ipc/drag' -import { registerWindow, getWindowType, sendToWindow, broadcastToAll, broadcastToAllExcept, setPanelWindowMeta, setPanelWindowTerminalPtyId, listPanelWindows, getWindow, setDockWindowState, listDockWindows } from './windowRegistry' +import { registerWindow, getWindowType, sendToWindow, broadcastToAll, broadcastToAllExcept, setPanelWindowMeta, setPanelWindowTerminalPtyId, listPanelWindows, getWindow, setDockWindowState, listDockWindows, focusWindow } from './windowRegistry' import { registerWorkspaceHandlers } from './workspaceManager' import { addAllowedRoot, clearFileGrantsForWindow, clearScopedWriteAllowancesForWindow, grantFileAccess, validatePath } from './ipc/pathValidation' import { listPersistentGrants, recordPersistentGrant } from './grantedPathStore' @@ -1210,8 +1210,8 @@ function deliverOpenPath(p: string): void { return } try { - if (win.isMinimized()) win.restore() - if (!IS_E2E) win.focus() + // Skip in e2e so opening a path never foregrounds the shared Electron bundle. + if (!IS_E2E) focusWindow(win) } catch { /* noop */ } win.webContents.send(APP_OPEN_PATH, p) } diff --git a/src/main/ipc/notifications.ts b/src/main/ipc/notifications.ts index bfc93c6e..57995b55 100644 --- a/src/main/ipc/notifications.ts +++ b/src/main/ipc/notifications.ts @@ -4,7 +4,7 @@ import { ipcMain, Notification, app } from 'electron' import { NOTIFY_OS, NOTIFY_ACTION } from '../../shared/ipc-channels' -import { sendToWindow, windowFromEvent } from '../windowRegistry' +import { sendToWindow, windowFromEvent, focusWindow } from '../windowRegistry' import type { NotificationAction } from '../../shared/types' export function registerHandlers(): void { @@ -26,8 +26,7 @@ export function registerHandlers(): void { notification.on('click', () => { // Focus the owning window if (win && !win.isDestroyed()) { - if (win.isMinimized()) win.restore() - win.focus() + focusWindow(win) } // Send the action back to the renderer so it can execute it diff --git a/src/main/windowRegistry.ts b/src/main/windowRegistry.ts index f49be303..6d4fcfab 100644 --- a/src/main/windowRegistry.ts +++ b/src/main/windowRegistry.ts @@ -95,6 +95,14 @@ export function getAllWindows(): BrowserWindow[] { return result } +/** Un-minimize (if needed) and bring a single window to the foreground. + * The shared "make this window the active one" idiom used wherever the app + * surfaces an existing window (open-path, notification click). */ +export function focusWindow(win: BrowserWindow): void { + if (win.isMinimized()) win.restore() + win.focus() +} + /** * Send an IPC message to a specific window by ID. No-op if window is gone. */