+
+
+
diff --git a/src/app/accounts/settings.component.ts b/src/app/accounts/settings.component.ts
index 9064b3724b..5a949b7611 100644
--- a/src/app/accounts/settings.component.ts
+++ b/src/app/accounts/settings.component.ts
@@ -47,21 +47,45 @@ export class SettingsComponent implements OnInit {
themeOptions: any[];
clearClipboard: number;
clearClipboardOptions: any[];
- enableTrayText: string;
- enableTrayDescText: string;
supportsBiometric: boolean;
biometric: boolean;
biometricText: string;
+ alwaysShowDock: boolean;
+ showAlwaysShowDock: boolean = false;
+ openAtLogin: boolean;
+
+ enableTrayText: string;
+ enableTrayDescText: string;
+ enableMinToTrayText: string;
+ enableMinToTrayDescText: string;
+ enableCloseToTrayText: string;
+ enableCloseToTrayDescText: string;
+ startToTrayText: string;
+ startToTrayDescText: string;
constructor(private analytics: Angulartics2, private toasterService: ToasterService,
private i18nService: I18nService, private platformUtilsService: PlatformUtilsService,
private storageService: StorageService, private vaultTimeoutService: VaultTimeoutService,
private stateService: StateService, private messagingService: MessagingService,
private userService: UserService, private cryptoService: CryptoService) {
- const trayKey = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop ?
- 'enableMenuBar' : 'enableTray';
+ const isMac = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
+
+ const trayKey = isMac ? 'enableMenuBar' : 'enableTray';
this.enableTrayText = this.i18nService.t(trayKey);
this.enableTrayDescText = this.i18nService.t(trayKey + 'Desc');
+
+ const minToTrayKey = isMac ? 'enableMinToMenuBar' : 'enableMinToTray';
+ this.enableMinToTrayText = this.i18nService.t(minToTrayKey)
+ this.enableMinToTrayDescText = this.i18nService.t(minToTrayKey + 'Desc');
+
+ const closeToTrayKey = isMac ? 'enableCloseToMenuBar' : 'enableCloseToTray';
+ this.enableCloseToTrayText = this.i18nService.t(closeToTrayKey)
+ this.enableCloseToTrayDescText = this.i18nService.t(closeToTrayKey + 'Desc');
+
+ const startToTrayKey = isMac ? 'startToMenuBar' : 'startToTray';
+ this.startToTrayText = this.i18nService.t(startToTrayKey)
+ this.startToTrayDescText = this.i18nService.t(startToTrayKey + 'Desc');
+
this.vaultTimeouts = [
// { name: i18nService.t('immediately'), value: 0 },
{ name: i18nService.t('oneMinute'), value: 1 },
@@ -114,7 +138,7 @@ export class SettingsComponent implements OnInit {
}
async ngOnInit() {
- this.showMinToTray = this.platformUtilsService.getDevice() === DeviceType.WindowsDesktop;
+ this.showMinToTray = this.platformUtilsService.getDevice() !== DeviceType.LinuxDesktop;
this.vaultTimeout = await this.storageService.get(ConstantsService.vaultTimeoutKey);
this.vaultTimeoutAction = await this.storageService.get(ConstantsService.vaultTimeoutActionKey);
const pinSet = await this.vaultTimeoutService.isPinLockSet();
@@ -133,6 +157,9 @@ export class SettingsComponent implements OnInit {
this.supportsBiometric = await this.platformUtilsService.supportsBiometric();
this.biometric = await this.vaultTimeoutService.isBiometricLockSet();
this.biometricText = await this.storageService.get(ConstantsService.biometricText);
+ this.alwaysShowDock = await this.storageService.get(ElectronConstants.alwaysShowDock);
+ this.showAlwaysShowDock = this.platformUtilsService.getDevice() === DeviceType.MacOsDesktop;
+ this.openAtLogin = await this.storageService.get(ElectronConstants.openAtLogin);
}
async saveVaultTimeoutOptions() {
@@ -279,6 +306,15 @@ export class SettingsComponent implements OnInit {
});
}
+ async saveAlwaysShowDock() {
+ await this.storageService.save(ElectronConstants.alwaysShowDock, this.alwaysShowDock);
+ }
+
+ async saveOpenAtLogin() {
+ this.storageService.save(ElectronConstants.openAtLogin, this.openAtLogin);
+ this.messagingService.send(this.openAtLogin ? 'addOpenAtLogin' : 'removeOpenAtLogin');
+ }
+
async saveBrowserIntegration() {
await this.storageService.save(ElectronConstants.enableBrowserIntegration, this.enableBrowserIntegration);
this.messagingService.send(this.enableBrowserIntegration ? 'enableBrowserIntegration' : 'disableBrowserIntegration');
diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json
index ef069d0348..525e9da141 100644
--- a/src/locales/en/messages.json
+++ b/src/locales/en/messages.json
@@ -852,12 +852,24 @@
"enableMinToTrayDesc": {
"message": "When minimizing the window, show an icon in the system tray instead."
},
+ "enableMinToMenuBar": {
+ "message": "Minimize to menu bar"
+ },
+ "enableMinToMenuBarDesc": {
+ "message": "When minimizing the window, show an icon in the menu bar instead."
+ },
"enableCloseToTray": {
"message": "Close to Tray Icon"
},
"enableCloseToTrayDesc": {
"message": "When closing the window, show an icon in the system tray instead."
},
+ "enableCloseToMenuBar": {
+ "message": "Close to menu bar"
+ },
+ "enableCloseToMenuBarDesc": {
+ "message": "When closing the window, show an icon in the menu bar instead."
+ },
"enableTray": {
"message": "Enable Tray Icon"
},
@@ -870,6 +882,24 @@
"startToTrayDesc": {
"message": "When the application is first started, only show an icon in the system tray."
},
+ "startToMenuBar": {
+ "message": "Start to menu bar"
+ },
+ "startToMenuBarDesc": {
+ "message": "When the application is first started, only show an icon in the menu bar."
+ },
+ "openAtLogin": {
+ "message": "Start automatically on login"
+ },
+ "openAtLoginDesc": {
+ "message": "Start the Bitwarden Desktop application automatically on login."
+ },
+ "alwaysShowDock": {
+ "message": "Always show in the Dock"
+ },
+ "alwaysShowDockDesc": {
+ "message": "Show the Bitwarden icon in the Dock even when minimized to the menu bar."
+ },
"language": {
"message": "Language"
},
diff --git a/src/main/messaging.main.ts b/src/main/messaging.main.ts
index 5cfe87f6c8..02981422f4 100644
--- a/src/main/messaging.main.ts
+++ b/src/main/messaging.main.ts
@@ -1,4 +1,6 @@
-import { ipcMain } from 'electron';
+import { app, ipcMain } from 'electron';
+import * as fs from 'fs';
+import * as path from 'path';
import { Main } from '../main';
@@ -15,6 +17,12 @@ export class MessagingMain {
init() {
this.scheduleNextSync();
+ if (process.platform === 'linux') {
+ this.storageService.save(ElectronConstants.openAtLogin, fs.existsSync(this.linuxStartupFile()));
+ } else {
+ const loginSettings = app.getLoginItemSettings();
+ this.storageService.save(ElectronConstants.openAtLogin, loginSettings.openAtLogin);
+ }
ipcMain.on('messagingService', async (event: any, message: any) => this.onMessage(message));
}
@@ -44,6 +52,11 @@ export class MessagingMain {
case 'hideToTray':
this.main.trayMain.hideToTray();
break;
+ case 'addOpenAtLogin':
+ this.addOpenAtLogin();
+ break;
+ case 'removeOpenAtLogin':
+ this.removeOpenAtLogin();
case 'setFocus':
this.setFocus();
break;
@@ -86,6 +99,41 @@ export class MessagingMain {
}
}
+ private addOpenAtLogin() {
+ if (process.platform === 'linux') {
+ const data = `[Desktop Entry]
+ Type=Application
+ Version=${app.getVersion()}
+ Name=Bitwarden
+ Comment=Bitwarden startup script
+ Exec=${app.getPath('exe')}
+ StartupNotify=false
+ Terminal=false`;
+
+ const dir = path.dirname(this.linuxStartupFile());
+ if (!fs.existsSync(dir)) {
+ fs.mkdirSync(dir);
+ }
+ fs.writeFileSync(this.linuxStartupFile(), data);
+ } else {
+ app.setLoginItemSettings({openAtLogin: true});
+ }
+ }
+
+ private removeOpenAtLogin() {
+ if (process.platform === 'linux') {
+ if (fs.existsSync(this.linuxStartupFile())) {
+ fs.unlinkSync(this.linuxStartupFile());
+ }
+ } else {
+ app.setLoginItemSettings({openAtLogin: false});
+ }
+ }
+
+ private linuxStartupFile(): string {
+ return path.join(app.getPath('home'), '.config', 'autostart', 'bitwarden.desktop');
+ }
+
private setFocus() {
this.main.trayMain.restoreFromTray();
this.main.windowMain.win.focusOnWebView();