@@ -119,6 +119,7 @@ let backendLogSink: RotatingFileSink | null = null;
119119let restoreStdIoCapture : ( ( ) => void ) | null = null ;
120120const previewControllers = new WeakMap < BrowserWindow , DesktopPreviewController > ( ) ;
121121const popOutWindows = new Map < BrowserWindow , BrowserWindow > ( ) ;
122+ const popOutParents = new WeakMap < BrowserWindow , BrowserWindow > ( ) ;
122123
123124let destructiveMenuIconCache : Electron . NativeImage | null | undefined ;
124125const desktopRuntimeInfo = resolveDesktopRuntimeInfo ( {
@@ -787,6 +788,10 @@ function resolvePreviewWindow(sender: Electron.WebContents): BrowserWindow | nul
787788 ) ;
788789}
789790
791+ function resolvePreviewParentWindow ( window : BrowserWindow ) : BrowserWindow {
792+ return popOutParents . get ( window ) ?? window ;
793+ }
794+
790795function setUpdateState ( patch : Partial < DesktopUpdateState > ) : void {
791796 updateState = { ...updateState , ...patch } ;
792797 emitUpdateState ( ) ;
@@ -1409,8 +1414,9 @@ function registerIpcHandlers(): void {
14091414
14101415 ipcMain . removeHandler ( PREVIEW_POP_OUT_CHANNEL ) ;
14111416 ipcMain . handle ( PREVIEW_POP_OUT_CHANNEL , async ( event ) => {
1412- const parentWindow = resolvePreviewWindow ( event . sender ) ;
1413- if ( ! parentWindow ) return ;
1417+ const sourceWindow = resolvePreviewWindow ( event . sender ) ;
1418+ if ( ! sourceWindow ) return ;
1419+ const parentWindow = resolvePreviewParentWindow ( sourceWindow ) ;
14141420
14151421 // If there is already a pop-out window for this parent, focus it.
14161422 const existing = popOutWindows . get ( parentWindow ) ;
@@ -1445,6 +1451,7 @@ function registerIpcHandlers(): void {
14451451 } ) ;
14461452 previewControllers . set ( popOut , popOutController ) ;
14471453 popOutWindows . set ( parentWindow , popOut ) ;
1454+ popOutParents . set ( popOut , parentWindow ) ;
14481455
14491456 // Transfer tabs from parent to pop-out.
14501457 parentController . transferTo ( popOutController ) ;
@@ -1497,13 +1504,15 @@ function registerIpcHandlers(): void {
14971504 popOutController . transferTo ( parentController ) ;
14981505 emitPreviewState ( parentWindow , parentController . getState ( ) ) ;
14991506 }
1507+ popOutParents . delete ( popOut ) ;
15001508 previewControllers . delete ( popOut ) ;
15011509 } ) ;
15021510
1503- // Load the same app URL but with a query parameter so the renderer
1504- // can detect pop-out mode and render a simplified UI if needed .
1511+ // Preserve the active chat route so the pop-out window keeps the same
1512+ // thread-scoped preview chrome and actions as the attached renderer .
15051513 void popOut . loadURL (
15061514 resolveDesktopRendererUrl ( {
1515+ baseUrl : event . sender . getURL ( ) ,
15071516 isDevelopment,
15081517 devServerUrl : process . env . VITE_DEV_SERVER_URL ,
15091518 scheme : DESKTOP_SCHEME ,
@@ -1514,8 +1523,9 @@ function registerIpcHandlers(): void {
15141523
15151524 ipcMain . removeHandler ( PREVIEW_POP_IN_CHANNEL ) ;
15161525 ipcMain . handle ( PREVIEW_POP_IN_CHANNEL , async ( event ) => {
1517- const parentWindow = resolvePreviewWindow ( event . sender ) ;
1518- if ( ! parentWindow ) return ;
1526+ const sourceWindow = resolvePreviewWindow ( event . sender ) ;
1527+ if ( ! sourceWindow ) return ;
1528+ const parentWindow = resolvePreviewParentWindow ( sourceWindow ) ;
15191529
15201530 const popOut = popOutWindows . get ( parentWindow ) ;
15211531 if ( popOut && ! popOut . isDestroyed ( ) ) {
0 commit comments