Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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)
}
Expand Down
5 changes: 2 additions & 3 deletions src/main/ipc/notifications.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/main/windowRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
Loading