fix: close and recreate macOS windows safely
This commit is contained in:
1 parent
f443f3bc66
commit
b5e6c663ef
19 files changed
+1079
-172
No files matched your search
+27
-23
@@ -2,10 +2,19 @@
|
||||
* System Tray Management
|
||||
* Creates and manages the system tray icon and menu
|
||||
*/
|
||||
import { Tray, Menu, BrowserWindow, app, nativeImage } from 'electron';
|
||||
import { Tray, Menu, app, nativeImage } from 'electron';
|
||||
import { join } from 'path';
|
||||
import {
|
||||
resolveMainWindow,
|
||||
sendWhenWindowReady,
|
||||
showMainWindow,
|
||||
type EnsureMainWindow,
|
||||
type MainWindowProvider,
|
||||
} from './window-provider';
|
||||
|
||||
let tray: Tray | null = null;
|
||||
let windowProvider: MainWindowProvider = () => null;
|
||||
let ensureWindow: EnsureMainWindow | undefined;
|
||||
|
||||
/**
|
||||
* Resolve the icons directory path (works in both dev and packaged mode)
|
||||
@@ -20,7 +29,10 @@ function getIconsDir(): string {
|
||||
/**
|
||||
* Create system tray icon and menu
|
||||
*/
|
||||
export function createTray(mainWindow: BrowserWindow): Tray {
|
||||
export function createTray(mainWindow: MainWindowProvider, ensureMainWindow?: EnsureMainWindow): Tray {
|
||||
windowProvider = mainWindow;
|
||||
ensureWindow = ensureMainWindow;
|
||||
if (tray && !tray.isDestroyed()) return tray;
|
||||
// Use platform-appropriate icon for system tray
|
||||
const iconsDir = getIconsDir();
|
||||
let iconPath: string;
|
||||
@@ -60,9 +72,9 @@ export function createTray(mainWindow: BrowserWindow): Tray {
|
||||
tray.setToolTip('Makelore - AI Assistant');
|
||||
|
||||
const showWindow = () => {
|
||||
if (mainWindow.isDestroyed()) return;
|
||||
mainWindow.show();
|
||||
mainWindow.focus();
|
||||
const window = resolveMainWindow(windowProvider) ?? ensureWindow?.() ?? null;
|
||||
showMainWindow(window);
|
||||
return window;
|
||||
};
|
||||
|
||||
// Create context menu
|
||||
@@ -93,17 +105,13 @@ export function createTray(mainWindow: BrowserWindow): Tray {
|
||||
{
|
||||
label: 'Open Chat',
|
||||
click: () => {
|
||||
if (mainWindow.isDestroyed()) return;
|
||||
mainWindow.show();
|
||||
mainWindow.webContents.send('navigate', '/');
|
||||
sendWhenWindowReady(showWindow(), 'navigate', '/');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: 'Open Settings',
|
||||
click: () => {
|
||||
if (mainWindow.isDestroyed()) return;
|
||||
mainWindow.show();
|
||||
mainWindow.webContents.send('navigate', '/settings');
|
||||
sendWhenWindowReady(showWindow(), 'navigate', '/settings');
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -114,8 +122,7 @@ export function createTray(mainWindow: BrowserWindow): Tray {
|
||||
{
|
||||
label: 'Check for Updates...',
|
||||
click: () => {
|
||||
if (mainWindow.isDestroyed()) return;
|
||||
mainWindow.webContents.send('update:check');
|
||||
sendWhenWindowReady(showWindow(), 'update:check');
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -133,21 +140,16 @@ export function createTray(mainWindow: BrowserWindow): Tray {
|
||||
|
||||
// Click to show window (Windows/Linux)
|
||||
tray.on('click', () => {
|
||||
if (mainWindow.isDestroyed()) return;
|
||||
if (mainWindow.isVisible()) {
|
||||
mainWindow.hide();
|
||||
const window = resolveMainWindow(windowProvider);
|
||||
if (window?.isVisible()) {
|
||||
window.hide();
|
||||
} else {
|
||||
mainWindow.show();
|
||||
mainWindow.focus();
|
||||
showWindow();
|
||||
}
|
||||
});
|
||||
|
||||
// Double-click to show window (Windows)
|
||||
tray.on('double-click', () => {
|
||||
if (mainWindow.isDestroyed()) return;
|
||||
mainWindow.show();
|
||||
mainWindow.focus();
|
||||
});
|
||||
tray.on('double-click', showWindow);
|
||||
|
||||
return tray;
|
||||
}
|
||||
@@ -168,5 +170,7 @@ export function destroyTray(): void {
|
||||
if (tray) {
|
||||
tray.destroy();
|
||||
tray = null;
|
||||
windowProvider = () => null;
|
||||
ensureWindow = undefined;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user