diff --git a/ui/desktop/src/main.ts b/ui/desktop/src/main.ts index f33b6193..2384f258 100644 --- a/ui/desktop/src/main.ts +++ b/ui/desktop/src/main.ts @@ -266,6 +266,9 @@ const createChat = async ( return mainWindow; }; +// Track tray instance +let tray: Tray | null = null; + const createTray = () => { const isDev = process.env.NODE_ENV === 'development'; let iconPath: string; @@ -276,7 +279,7 @@ const createTray = () => { iconPath = path.join(process.resourcesPath, 'images', 'iconTemplate.png'); } - const tray = new Tray(iconPath); + tray = new Tray(iconPath); const contextMenu = Menu.buildFromTemplate([ { label: 'Show Window', click: showWindow }, @@ -286,6 +289,11 @@ const createTray = () => { tray.setToolTip('Goose'); tray.setContextMenu(contextMenu); + + // On Windows, clicking the tray icon should show the window + if (process.platform === 'win32') { + tray.on('click', showWindow); + } }; const showWindow = async () => { @@ -336,16 +344,18 @@ const buildRecentFilesMenu = () => { const openDirectoryDialog = async (replaceWindow: boolean = false) => { const result = await dialog.showOpenDialog({ - properties: ['openDirectory'], + properties: ['openFile', 'openDirectory'], }); if (!result.canceled && result.filePaths.length > 0) { addRecentDir(result.filePaths[0]); + const currentWindow = BrowserWindow.getFocusedWindow(); + const newWindow = await createChat(app, undefined, result.filePaths[0]); if (replaceWindow) { - BrowserWindow.getFocusedWindow().close(); + currentWindow.close(); } - createChat(app, undefined, result.filePaths[0]); } + return result; }; // Global error handler @@ -388,10 +398,15 @@ ipcMain.on('react-ready', (event) => { } }); +// Handle directory chooser +ipcMain.handle('directory-chooser', (_, replace: boolean = false) => { + return openDirectoryDialog(replace); +}); + // Add file/directory selection handler ipcMain.handle('select-file-or-directory', async () => { const result = await dialog.showOpenDialog({ - properties: ['openFile', 'openDirectory'], + properties: process.platform === 'darwin' ? ['openFile', 'openDirectory'] : ['openFile'], }); if (!result.canceled && result.filePaths.length > 0) { @@ -539,9 +554,7 @@ app.whenReady().then(async () => { new MenuItem({ label: 'Open Directory...', accelerator: 'CmdOrCtrl+O', - click() { - openDirectoryDialog(); - }, + click: () => openDirectoryDialog(), }) ); @@ -614,10 +627,6 @@ app.whenReady().then(async () => { createChat(app, query, dir, version, resumeSessionId, botConfig); }); - ipcMain.on('directory-chooser', (_, replace: boolean = false) => { - openDirectoryDialog(replace); - }); - ipcMain.on('notify', (event, data) => { console.log('NOTIFY', data); new Notification({ title: data.title, body: data.body }).show(); @@ -697,9 +706,10 @@ app.whenReady().then(async () => { }); }); -// Quit when all windows are closed, except on macOS. +// Quit when all windows are closed, except on macOS or if we have a tray icon. app.on('window-all-closed', () => { - if (process.platform !== 'darwin') { + // Only quit if we're not on macOS or don't have a tray icon + if (process.platform !== 'darwin' || !tray) { app.quit(); } }); diff --git a/ui/desktop/src/preload.ts b/ui/desktop/src/preload.ts index 8d91cca5..4809cb78 100644 --- a/ui/desktop/src/preload.ts +++ b/ui/desktop/src/preload.ts @@ -7,7 +7,7 @@ type ElectronAPI = { reactReady: () => void; getConfig: () => Record; hideWindow: () => void; - directoryChooser: (replace: string) => void; + directoryChooser: (replace?: boolean) => Promise; createChatWindow: ( query?: string, dir?: string, @@ -49,7 +49,7 @@ const electronAPI: ElectronAPI = { reactReady: () => ipcRenderer.send('react-ready'), getConfig: () => config, hideWindow: () => ipcRenderer.send('hide-window'), - directoryChooser: (replace: string) => ipcRenderer.send('directory-chooser', replace), + directoryChooser: (replace?: boolean) => ipcRenderer.invoke('directory-chooser', replace), createChatWindow: ( query?: string, dir?: string,