diff --git a/src/main/cluster-manager.ts b/src/main/cluster-manager.ts index 1792fb953b..1a479e724e 100644 --- a/src/main/cluster-manager.ts +++ b/src/main/cluster-manager.ts @@ -6,9 +6,11 @@ import { clusterStore, getClusterIdFromHost } from "../common/cluster-store" import { Cluster } from "./cluster" import logger from "./logger"; import { apiKubePrefix } from "../common/vars"; +import { Singleton } from "../common/utils"; -export class ClusterManager { +export class ClusterManager extends Singleton { constructor(public readonly port: number) { + super() // auto-init clusters autorun(() => { clusterStore.enabledClustersList.forEach(cluster => { diff --git a/src/main/exit-app.ts b/src/main/exit-app.ts new file mode 100644 index 0000000000..bf73e022f3 --- /dev/null +++ b/src/main/exit-app.ts @@ -0,0 +1,18 @@ +import { app } from "electron"; +import { WindowManager } from "./window-manager"; +import { appEventBus } from "../common/event-bus"; +import { ClusterManager } from "./cluster-manager"; +import logger from "./logger"; + + +export function exitApp() { + const windowManager = WindowManager.getInstance() + const clusterManager = ClusterManager.getInstance() + appEventBus.emit({ name: "service", action: "close" }) + windowManager.hide(); + clusterManager.stop(); + logger.info('SERVICE:QUIT'); + setTimeout(() => { + app.exit() + }, 1000) +} \ No newline at end of file diff --git a/src/main/index.ts b/src/main/index.ts index 21acda801b..b25aed5bb2 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -67,7 +67,7 @@ app.on("ready", async () => { } // create cluster manager - clusterManager = new ClusterManager(proxyPort); + clusterManager = ClusterManager.getInstance(proxyPort); // run proxy try { @@ -82,7 +82,7 @@ app.on("ready", async () => { extensionLoader.init(await extensionManager.load()); // call after windowManager to see splash earlier setTimeout(() => { - appEventBus.emit({ name: "app", action: "start" }) + appEventBus.emit({ name: "service", action: "start" }) }, 1000) }); @@ -96,6 +96,7 @@ app.on("activate", (event, hasVisibleWindows) => { // Quit app on Cmd+Q (MacOS) app.on("will-quit", (event) => { logger.info('APP:QUIT'); + appEventBus.emit({name: "app", action: "close"}) event.preventDefault(); // prevent app's default shutdown (e.g. required for telemetry, etc.) clusterManager?.stop(); // close cluster connections return; // skip exit to make tray work, to quit go to app's global menu or tray's menu diff --git a/src/main/menu.ts b/src/main/menu.ts index fbd6af8d3c..08260d8e53 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -9,6 +9,7 @@ import { clusterSettingsURL } from "../renderer/components/+cluster-settings/clu import { extensionsURL } from "../renderer/components/+extensions/extensions.route"; import { menuRegistry } from "../extensions/registries/menu-registry"; import logger from "./logger"; +import { exitApp } from "./exit-app"; export type MenuTopId = "mac" | "file" | "edit" | "view" | "help" @@ -89,7 +90,7 @@ export function buildMenu(windowManager: WindowManager) { label: 'Quit', accelerator: 'Cmd+Q', click() { - app.exit(); // force quit since might be blocked within app.on("will-quit") + exitApp() } } ] @@ -135,7 +136,13 @@ export function buildMenu(windowManager: WindowManager) { } }, { type: 'separator' }, - { role: 'quit' } + { + label: 'Quit', + accelerator: 'Alt+F4', + click() { + exitApp() + } + } ]), { type: 'separator' }, { role: 'close' } // close current window @@ -259,7 +266,7 @@ export function buildMenu(windowManager: WindowManager) { } menu = menuItem.submenu; } - + const menuPath: string = parentLabels.join(" -> ") if (!menuItem) { logger.info(`[MENU:test-menu-item-click] Cannot find menu item ${menuPath}`); diff --git a/src/main/tray.ts b/src/main/tray.ts index 5bc6ce7091..f170517e62 100644 --- a/src/main/tray.ts +++ b/src/main/tray.ts @@ -1,6 +1,6 @@ import path from "path" import packageInfo from "../../package.json" -import { app, dialog, Menu, NativeImage, nativeTheme, Tray } from "electron" +import { dialog, Menu, NativeImage, nativeTheme, Tray } from "electron" import { autorun } from "mobx"; import { showAbout } from "./menu"; import { AppUpdater } from "./app-updater"; @@ -11,6 +11,7 @@ import { preferencesURL } from "../renderer/components/+preferences/preferences. import { clusterViewURL } from "../renderer/components/cluster-manager/cluster-view.route"; import logger from "./logger"; import { isDevelopment } from "../common/vars"; +import { exitApp } from "./exit-app"; // note: instance of Tray should be saved somewhere, otherwise it disappears export let tray: Tray; @@ -119,7 +120,7 @@ export function createTrayMenu(windowManager: WindowManager): Menu { { label: 'Quit App', click() { - app.exit(); + exitApp() } } ]); diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index fc61ca8345..034e14b61a 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -85,6 +85,7 @@ export class WindowManager extends Singleton { await this.mainWindow.loadURL(this.mainUrl); this.mainWindow.show(); this.splashWindow?.close(); + appEventBus.emit({ name: "app", action: "start" }) } catch (err) { dialog.showErrorBox("ERROR!", err.toString()) } @@ -156,6 +157,11 @@ export class WindowManager extends Singleton { this.splashWindow.show(); } + hide() { + if (!this.mainWindow?.isDestroyed()) this.mainWindow.hide(); + if (!this.splashWindow.isDestroyed()) this.splashWindow.hide(); + } + destroy() { this.mainWindow.destroy(); this.splashWindow.destroy();