diff --git a/src/common/user-store.ts b/src/common/user-store.ts index 1a81c981f7..8faacbf85a 100644 --- a/src/common/user-store.ts +++ b/src/common/user-store.ts @@ -28,6 +28,7 @@ export interface UserPreferences { downloadBinariesPath?: string; kubectlBinariesPath?: string; trayEnabled?: boolean; + openAtLogin?: boolean; } export class UserStore extends BaseStore { @@ -39,14 +40,7 @@ export class UserStore extends BaseStore { migrations: migrations, }); - // track telemetry availability - reaction(() => this.preferences.allowTelemetry, allowed => { - tracker.event("telemetry", allowed ? "enabled" : "disabled"); - }); - - // refresh new contexts - this.whenLoaded.then(this.refreshNewContexts); - reaction(() => this.kubeConfigPath, this.refreshNewContexts); + this.handleOnLoad(); } @observable lastSeenAppVersion = "0.0.0" @@ -61,8 +55,31 @@ export class UserStore extends BaseStore { downloadMirror: "default", downloadKubectlBinaries: true, // Download kubectl binaries matching cluster version trayEnabled: true, + openAtLogin: true, }; + protected async handleOnLoad() { + await this.whenLoaded; + + // refresh new contexts + this.refreshNewContexts(); + reaction(() => this.kubeConfigPath, this.refreshNewContexts); + + if (app) { + // track telemetry availability + reaction(() => this.preferences.allowTelemetry, allowed => { + tracker.event("telemetry", allowed ? "enabled" : "disabled"); + }); + + // open at system start-up + reaction(() => this.preferences.openAtLogin, open => { + app.setLoginItemSettings({ openAtLogin: open }); + }, { + fireImmediately: true, + }); + } + } + get isNewVersion() { return semver.gt(getAppVersion(), this.lastSeenAppVersion); } diff --git a/src/main/index.ts b/src/main/index.ts index 7e7595c7e3..15ebf6c139 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -87,12 +87,10 @@ app.on("activate", (event, hasVisibleWindows) => { app.on("will-quit", (event) => { logger.info('APP:QUIT'); event.preventDefault(); // prevent app's default shutdown (e.g. required for telemetry, etc.) - clusterManager?.stop(); + clusterManager?.stop(); // close cluster connections if (userStore.preferences.trayEnabled) { return; // with tray the app remains open } else { - windowManager?.destroy(); - proxyServer?.close(); app.exit(); // forced app.quit() } }) diff --git a/src/main/menu.ts b/src/main/menu.ts index a581fb02fb..6e3ddea7be 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -78,14 +78,12 @@ export function buildMenu(windowManager: WindowManager) { { role: 'unhide' }, { type: 'separator' }, { - label: 'Force Quit', - accelerator: 'Cmd+Shift+Q', + label: 'Quit', + accelerator: 'Cmd+Q', click() { - app.exit(0); // force quit since might be blocked within app.on("will-quit") + app.exit(); // force quit since might be blocked within app.on("will-quit") } - }, - { type: 'separator' }, - { role: 'quit' }, + } ] }; diff --git a/src/main/tray.ts b/src/main/tray.ts index f77d7dddd9..5a43aec50a 100644 --- a/src/main/tray.ts +++ b/src/main/tray.ts @@ -2,7 +2,7 @@ import path from "path" import sharp from "sharp"; import jsdom from "jsdom" import packageInfo from "../../package.json" -import { dialog, Menu, NativeImage, nativeImage, nativeTheme, Tray } from "electron" +import { app, dialog, Menu, NativeImage, nativeImage, nativeTheme, Tray } from "electron" import { isDevelopment, isMac } from "../common/vars"; import { autorun } from "mobx"; import { showAbout } from "./menu"; @@ -131,5 +131,12 @@ export function createTrayMenu(windowManager: WindowManager): Menu { } }, }, + { type: 'separator' }, + { + label: 'Quit App', + click() { + app.exit(); + } + } ]); } diff --git a/src/main/window-manager.ts b/src/main/window-manager.ts index f6a7466c49..b65978ab1d 100644 --- a/src/main/window-manager.ts +++ b/src/main/window-manager.ts @@ -2,7 +2,7 @@ import type { ClusterId } from "../common/cluster-store"; import { clusterStore } from "../common/cluster-store"; import { userStore } from "../common/user-store"; import { observable, reaction } from "mobx"; -import { BrowserWindow, dialog, ipcMain, shell, webContents } from "electron" +import { app, BrowserWindow, dialog, ipcMain, shell, webContents } from "electron" import windowStateKeeper from "electron-window-state" import { initMenu } from "./menu"; import { initTray } from "./tray"; @@ -35,6 +35,8 @@ export class WindowManager { }); } if (!this.mainWindow) { + app.dock?.show(); // show icon in dock (mac-os only) + const { width, height, x, y } = this.windowState; this.mainWindow = new BrowserWindow({ x, y, width, height, @@ -62,6 +64,7 @@ export class WindowManager { this.windowState.unmanage(); this.mainWindow = null; this.splashWindow = null; + app.dock?.hide(); // hide icon in dock (mac-os) }) } try { diff --git a/src/renderer/components/+preferences/preferences.scss b/src/renderer/components/+preferences/preferences.scss index 62bd307cd1..57054af5d4 100644 --- a/src/renderer/components/+preferences/preferences.scss +++ b/src/renderer/components/+preferences/preferences.scss @@ -57,4 +57,8 @@ box-shadow: 0 0 0 1px $borderFaintColor; } } + + .Checkbox { + align-self: start; // limit clickable area to checkbox + text + } } \ No newline at end of file diff --git a/src/renderer/components/+preferences/preferences.tsx b/src/renderer/components/+preferences/preferences.tsx index 8b98750dac..9c67bbd5a6 100644 --- a/src/renderer/components/+preferences/preferences.tsx +++ b/src/renderer/components/+preferences/preferences.tsx @@ -173,6 +173,26 @@ export class Preferences extends React.Component { })} +

Auto start-up

+ Open on start-up} + value={preferences.openAtLogin} + onChange={v => preferences.openAtLogin = v} + /> + + Opens Lens app on operation system login + + +

Tray icon

+ Enable tray icon} + value={preferences.trayEnabled} + onChange={v => preferences.trayEnabled = v} + /> + + Adds OS-level tray icon and menu to get quick access to Lens + +

Certificate Trust

Allow untrusted Certificate Authorities} @@ -194,16 +214,6 @@ export class Preferences extends React.Component { Telemetry & usage data is collected to continuously improve the Lens experience. - -

Tray icon

- Enable tray icon} - value={preferences.trayEnabled} - onChange={v => preferences.trayEnabled = v} - /> - - Adds OS-level tray icon and menu to get quick access to Lens - );