From 54cc54272ef3cbaa5358758d8c2d09626d730701 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Fri, 6 Sep 2024 09:27:55 -0400 Subject: [PATCH 01/26] Passkey stuff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Anders Ã…berg --- apps/desktop/resources/passkeys.png | Bin 0 -> 51413 bytes apps/desktop/src/app/app-routing.module.ts | 5 + .../src/app/components/passkeys.component.ts | 22 +++ apps/desktop/src/main/tray.main.ts | 49 +++++++ apps/desktop/src/main/window.main.ts | 137 ++++++++++++------ 5 files changed, 167 insertions(+), 46 deletions(-) create mode 100644 apps/desktop/resources/passkeys.png create mode 100644 apps/desktop/src/app/components/passkeys.component.ts diff --git a/apps/desktop/resources/passkeys.png b/apps/desktop/resources/passkeys.png new file mode 100644 index 0000000000000000000000000000000000000000..ca6513e5ec38f376301210f3ffab2d5258eac5c0 GIT binary patch literal 51413 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 literal 0 HcmV?d00001 diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index f5023cb4249..3c25d5f9995 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -52,6 +52,7 @@ import { TwoFactorComponent } from "../auth/two-factor.component"; import { UpdateTempPasswordComponent } from "../auth/update-temp-password.component"; import { VaultComponent } from "../vault/app/vault/vault.component"; +import { PasskeysComponent } from "./components/passkeys.component"; import { SendComponent } from "./tools/send/send.component"; /** @@ -200,6 +201,10 @@ const routes: Routes = [ ], }, ), + { + path: "passkeys", + component: PasskeysComponent, + }, { path: "", component: AnonLayoutWrapperComponent, diff --git a/apps/desktop/src/app/components/passkeys.component.ts b/apps/desktop/src/app/components/passkeys.component.ts new file mode 100644 index 00000000000..dcfd2bd5a45 --- /dev/null +++ b/apps/desktop/src/app/components/passkeys.component.ts @@ -0,0 +1,22 @@ +import { Component } from "@angular/core"; + +import { JslibModule } from "@bitwarden/angular/jslib.module"; + +export type BrowserSyncVerificationDialogParams = { + fingerprint: string[]; +}; + +@Component({ + standalone: true, + template: ` + + `, + imports: [JslibModule], +}) +export class PasskeysComponent {} diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index 8450a653222..7656cd8922d 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -1,4 +1,5 @@ import * as path from "path"; +import * as url from "url"; import { app, BrowserWindow, Menu, MenuItemConstructorOptions, nativeImage, Tray } from "electron"; import { firstValueFrom } from "rxjs"; @@ -6,6 +7,7 @@ import { firstValueFrom } from "rxjs"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { DesktopSettingsService } from "../platform/services/desktop-settings.service"; +import { cleanUserAgent } from "../utils"; import { WindowMain } from "./window.main"; @@ -44,6 +46,10 @@ export class TrayMain { label: this.i18nService.t("showHide"), click: () => this.toggleWindow(), }, + { + label: "Fake Popup", + click: () => this.fakePopup(), + }, { type: "separator" }, { label: this.i18nService.t("exit"), @@ -195,4 +201,47 @@ export class TrayMain { this.windowMain.win.close(); } } + + private async fakePopup() { + if (this.windowMain.win == null || this.windowMain.win.isDestroyed()) { + await this.windowMain.createWindow("minimal-app"); + return; + } + + // Restyle existing + const existingWin = this.windowMain.win; + + existingWin.setBounds({ + width: 400, + height: 600, + }); + existingWin.setSize(400, 600, true); + existingWin.setWindowButtonVisibility(false); + existingWin.resizable = false; + await existingWin.loadURL( + url.format({ + protocol: "file:", + //pathname: `${__dirname}/index.html`, + pathname: path.join(__dirname, "/index.html"), + slashes: true, + hash: "/passkeys", + query: { + redirectUrl: "/passkeys", + }, + }), + { + userAgent: cleanUserAgent(existingWin.webContents.userAgent), + }, + ); + existingWin.center(); + existingWin.setAlwaysOnTop(true); + existingWin.show(); + // TODO: Do things + // ?? Enqueue the browser location + // Change browser location and styling to minimal + + // Show popup + // Change styling back to full + // ?? Dequeue browser location + } } diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 276a2bdc979..f12e9826515 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -168,39 +168,66 @@ export class WindowMain { }); } - async createWindow(): Promise { - this.windowStates[mainWindowSizeKey] = await this.getWindowState( - this.defaultWidth, - this.defaultHeight, - ); - this.enableAlwaysOnTop = await firstValueFrom(this.desktopSettingsService.alwaysOnTop$); - - this.session = session.fromPartition("persist:bitwarden", { cache: false }); - - // Create the browser window. - this.win = new BrowserWindow({ - width: this.windowStates[mainWindowSizeKey].width, - height: this.windowStates[mainWindowSizeKey].height, - minWidth: 680, - minHeight: 500, - x: this.windowStates[mainWindowSizeKey].x, - y: this.windowStates[mainWindowSizeKey].y, - title: app.name, - icon: isLinux() ? path.join(__dirname, "/images/icon.png") : undefined, - titleBarStyle: isMac() ? "hiddenInset" : undefined, - show: false, - backgroundColor: await this.getBackgroundColor(), - alwaysOnTop: this.enableAlwaysOnTop, - webPreferences: { - preload: path.join(__dirname, "preload.js"), - spellcheck: false, - nodeIntegration: false, - backgroundThrottling: false, - contextIsolation: true, - session: this.session, - devTools: isDev(), - }, - }); + async createWindow(template: "full-app" | "minimal-app" = "full-app"): Promise { + if (template === "full-app") { + this.windowStates[mainWindowSizeKey] = await this.getWindowState( + this.defaultWidth, + this.defaultHeight, + ); + this.enableAlwaysOnTop = await firstValueFrom(this.desktopSettingsService.alwaysOnTop$); + + this.session = session.fromPartition("persist:bitwarden", { cache: false }); + + // Create the browser window. + this.win = new BrowserWindow({ + width: this.windowStates[mainWindowSizeKey].width, + height: this.windowStates[mainWindowSizeKey].height, + minWidth: 680, + minHeight: 500, + x: this.windowStates[mainWindowSizeKey].x, + y: this.windowStates[mainWindowSizeKey].y, + title: app.name, + icon: isLinux() ? path.join(__dirname, "/images/icon.png") : undefined, + titleBarStyle: isMac() ? "hiddenInset" : undefined, + show: false, + backgroundColor: await this.getBackgroundColor(), + alwaysOnTop: this.enableAlwaysOnTop, + webPreferences: { + preload: path.join(__dirname, "preload.js"), + spellcheck: false, + nodeIntegration: false, + backgroundThrottling: false, + contextIsolation: true, + session: this.session, + devTools: isDev(), + }, + }); + } else { + // + this.win = new BrowserWindow({ + width: 400, + height: 600, + resizable: false, + icon: null, + center: true, + titleBarStyle: "hiddenInset", + frame: false, + alwaysOnTop: true, + backgroundColor: await this.getBackgroundColor(), + show: true, + webPreferences: { + preload: path.join(__dirname, "preload.js"), + spellcheck: false, + nodeIntegration: false, + backgroundThrottling: false, + contextIsolation: true, + session: this.session, + devTools: isDev(), + }, + }); + + this.win.setWindowButtonVisibility(false); + } this.win.webContents.on("dom-ready", () => { this.win.webContents.zoomFactor = this.windowStates[mainWindowSizeKey].zoomFactor ?? 1.0; @@ -213,19 +240,37 @@ export class WindowMain { // Show it later since it might need to be maximized. this.win.show(); - // and load the index.html of the app. - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.win.loadURL( - url.format({ - protocol: "file:", - pathname: path.join(__dirname, "/index.html"), - slashes: true, - }), - { - userAgent: cleanUserAgent(this.win.webContents.userAgent), - }, - ); + if (template === "full-app") { + // and load the index.html of the app. + // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. + // eslint-disable-next-line @typescript-eslint/no-floating-promises + this.win.loadURL( + url.format({ + protocol: "file:", + pathname: path.join(__dirname, "/index.html"), + slashes: true, + }), + { + userAgent: cleanUserAgent(this.win.webContents.userAgent), + }, + ); + } else { + await this.win.loadURL( + url.format({ + protocol: "file:", + //pathname: `${__dirname}/index.html`, + pathname: path.join(__dirname, "/index.html"), + slashes: true, + hash: "/passkeys", + query: { + redirectUrl: "/passkeys", + }, + }), + { + userAgent: cleanUserAgent(this.win.webContents.userAgent), + }, + ); + } // Open the DevTools. if (isDev()) { From e4ca8a21bf7789bc3b7d4fb1726370338e129c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 11 Sep 2024 19:11:31 +0200 Subject: [PATCH 02/26] Ugly hacks --- apps/desktop/resources/Frame2101.png | Bin 0 -> 29982 bytes apps/desktop/resources/Frame2101.svg | 36 ++++++++++++++++++ .../src/app/components/passkeys.component.ts | 16 ++++---- apps/desktop/src/main/tray.main.ts | 6 +-- apps/desktop/src/main/window.main.ts | 8 ++-- 5 files changed, 52 insertions(+), 14 deletions(-) create mode 100644 apps/desktop/resources/Frame2101.png create mode 100644 apps/desktop/resources/Frame2101.svg diff --git a/apps/desktop/resources/Frame2101.png b/apps/desktop/resources/Frame2101.png new file mode 100644 index 0000000000000000000000000000000000000000..84f3ad7c81080eaa0c975fbfcf677e7acedb7652 GIT binary patch literal 29982 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 C^$j@y literal 0 HcmV?d00001 diff --git a/apps/desktop/resources/Frame2101.svg b/apps/desktop/resources/Frame2101.svg new file mode 100644 index 00000000000..d36e4e6532d --- /dev/null +++ b/apps/desktop/resources/Frame2101.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/desktop/src/app/components/passkeys.component.ts b/apps/desktop/src/app/components/passkeys.component.ts index dcfd2bd5a45..f2cffd88934 100644 --- a/apps/desktop/src/app/components/passkeys.component.ts +++ b/apps/desktop/src/app/components/passkeys.component.ts @@ -9,13 +9,15 @@ export type BrowserSyncVerificationDialogParams = { @Component({ standalone: true, template: ` - +

+ +
`, imports: [JslibModule], }) diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index 7656cd8922d..d8d160adbca 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -212,10 +212,10 @@ export class TrayMain { const existingWin = this.windowMain.win; existingWin.setBounds({ - width: 400, - height: 600, + width: 500, + height: 400, }); - existingWin.setSize(400, 600, true); + existingWin.setSize(450, 450, true); existingWin.setWindowButtonVisibility(false); existingWin.resizable = false; await existingWin.loadURL( diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index f12e9826515..8e7cfdfc455 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -182,8 +182,8 @@ export class WindowMain { this.win = new BrowserWindow({ width: this.windowStates[mainWindowSizeKey].width, height: this.windowStates[mainWindowSizeKey].height, - minWidth: 680, - minHeight: 500, + minWidth: 400, + minHeight: 400, x: this.windowStates[mainWindowSizeKey].x, y: this.windowStates[mainWindowSizeKey].y, title: app.name, @@ -205,8 +205,8 @@ export class WindowMain { } else { // this.win = new BrowserWindow({ - width: 400, - height: 600, + width: 450, + height: 450, resizable: false, icon: null, center: true, From 7e4bfae55f4c2f8f8cc48a4c2f249c70a20b84d2 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Thu, 12 Sep 2024 10:07:12 -0400 Subject: [PATCH 03/26] Work On Modal State Management --- .../src/app/components/passkeys.component.ts | 17 ++++++++++-- apps/desktop/src/main/tray.main.ts | 2 ++ apps/desktop/src/main/window.main.ts | 27 ++++++++++++++++--- .../src/platform/popup-modal-styles.ts | 15 +++++++++++ .../services/desktop-settings.service.ts | 11 ++++++++ 5 files changed, 67 insertions(+), 5 deletions(-) create mode 100644 apps/desktop/src/platform/popup-modal-styles.ts diff --git a/apps/desktop/src/app/components/passkeys.component.ts b/apps/desktop/src/app/components/passkeys.component.ts index f2cffd88934..3ed675d44f8 100644 --- a/apps/desktop/src/app/components/passkeys.component.ts +++ b/apps/desktop/src/app/components/passkeys.component.ts @@ -2,6 +2,8 @@ import { Component } from "@angular/core"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; + export type BrowserSyncVerificationDialogParams = { fingerprint: string[]; }; @@ -9,7 +11,9 @@ export type BrowserSyncVerificationDialogParams = { @Component({ standalone: true, template: ` -
+
+
+
`, imports: [JslibModule], }) -export class PasskeysComponent {} +export class PasskeysComponent { + constructor(private readonly desktopSettingsService: DesktopSettingsService) {} + + async closeModal() { + console.log("closing modal"); + await this.desktopSettingsService.setInModalMode(false); + } +} diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index d8d160adbca..666a9370a05 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -211,6 +211,8 @@ export class TrayMain { // Restyle existing const existingWin = this.windowMain.win; + await this.desktopSettingsService.setInModalMode(true); + existingWin.setBounds({ width: 500, height: 400, diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 8e7cfdfc455..eb5441a0c07 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -3,7 +3,7 @@ import * as path from "path"; import * as url from "url"; import { app, BrowserWindow, ipcMain, nativeTheme, screen, session } from "electron"; -import { firstValueFrom } from "rxjs"; +import { concatMap, firstValueFrom, pairwise } from "rxjs"; import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; import { AbstractStorageService } from "@bitwarden/common/platform/abstractions/storage.service"; @@ -11,6 +11,7 @@ import { processisolations } from "@bitwarden/desktop-napi"; import { BiometricStateService } from "@bitwarden/key-management"; import { WindowState } from "../platform/models/domain/window-state"; +import { applyMainWindowStyles } from "../platform/popup-modal-styles"; import { DesktopSettingsService } from "../platform/services/desktop-settings.service"; import { cleanUserAgent, @@ -45,7 +46,7 @@ export class WindowMain { private desktopSettingsService: DesktopSettingsService, private argvCallback: (argv: string[]) => void = null, private createWindowCallback: (win: BrowserWindow) => void, - ) {} + ) { } init(): Promise { // Perform a hard reload of the render process by crashing it. This is suboptimal but ensures that all memory gets @@ -69,6 +70,18 @@ export class WindowMain { this.logService.info("Render process reloaded"); }); + this.desktopSettingsService.inModalMode$ + .pipe( + pairwise(), + concatMap(async ([lastValue, newValue]) => { + console.log("inModalMode updated", { lastValue, newValue }); + if (lastValue && !newValue) { + applyMainWindowStyles(this.win, this.windowStates[mainWindowSizeKey]); + } + }), + ) + .subscribe(); + return new Promise((resolve, reject) => { try { if (!isMacAppStore() && !isSnapStore()) { @@ -203,7 +216,6 @@ export class WindowMain { }, }); } else { - // this.win = new BrowserWindow({ width: 450, height: 450, @@ -353,7 +365,16 @@ export class WindowMain { } private async updateWindowState(configKey: string, win: BrowserWindow) { + console.log("updateWindowState"); if (win == null || win.isDestroyed()) { + console.log("no window/destroyed"); + return; + } + + const inModalMode = await firstValueFrom(this.desktopSettingsService.inModalMode$); + + if (inModalMode) { + console.log("in modal mode, ignore"); return; } diff --git a/apps/desktop/src/platform/popup-modal-styles.ts b/apps/desktop/src/platform/popup-modal-styles.ts new file mode 100644 index 00000000000..3bd3abf92e3 --- /dev/null +++ b/apps/desktop/src/platform/popup-modal-styles.ts @@ -0,0 +1,15 @@ +import { BrowserWindow } from "electron"; + +import { WindowState } from "./models/domain/window-state"; + +export function applyPopupModalStyles(window: BrowserWindow) { + // +} + +export function applyMainWindowStyles(window: BrowserWindow, existingWindowState: WindowState) { + window.setMinimumSize(400, 400); + window.setSize(existingWindowState.width, existingWindowState.height); + window.setPosition(existingWindowState.x, existingWindowState.y); + window.setWindowButtonVisibility(true); + window.setMenuBarVisibility(true); +} diff --git a/apps/desktop/src/platform/services/desktop-settings.service.ts b/apps/desktop/src/platform/services/desktop-settings.service.ts index ff29ce50a0f..13b3de5bebd 100644 --- a/apps/desktop/src/platform/services/desktop-settings.service.ts +++ b/apps/desktop/src/platform/services/desktop-settings.service.ts @@ -71,6 +71,10 @@ const MINIMIZE_ON_COPY = new UserKeyDefinition(DESKTOP_SETTINGS_DISK, " clearOn: [], // User setting, no need to clear }); +const IN_MODAL_MODE = new KeyDefinition(DESKTOP_SETTINGS_DISK, "inModalMode", { + deserializer: (b) => b, +}); + /** * Various settings for controlling application behavior specific to the desktop client. */ @@ -147,6 +151,10 @@ export class DesktopSettingsService { */ minimizeOnCopy$ = this.minimizeOnCopyState.state$.pipe(map(Boolean)); + private readonly inModalModeState = this.stateProvider.getGlobal(IN_MODAL_MODE); + + inModalMode$ = this.inModalModeState.state$.pipe(map(Boolean)); + constructor(private stateProvider: StateProvider) { this.window$ = this.windowState.state$.pipe( map((window) => @@ -255,4 +263,7 @@ export class DesktopSettingsService { async setMinimizeOnCopy(value: boolean, userId: UserId) { await this.stateProvider.getUser(userId, MINIMIZE_ON_COPY).update(() => value); } + async setInModalMode(value: boolean) { + await this.inModalModeState.update(() => value); + } } From 8469bb256290d541d7dcb7ccf228ed3dbdfddac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 18 Sep 2024 12:09:32 +0200 Subject: [PATCH 04/26] Applying modalStyles --- apps/desktop/src/app/components/passkeys.component.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/app/components/passkeys.component.ts b/apps/desktop/src/app/components/passkeys.component.ts index 3ed675d44f8..086640adde4 100644 --- a/apps/desktop/src/app/components/passkeys.component.ts +++ b/apps/desktop/src/app/components/passkeys.component.ts @@ -1,5 +1,5 @@ import { Component } from "@angular/core"; - +import { Router } from "@angular/router"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; @@ -28,10 +28,13 @@ export type BrowserSyncVerificationDialogParams = { imports: [JslibModule], }) export class PasskeysComponent { - constructor(private readonly desktopSettingsService: DesktopSettingsService) {} + constructor( + private readonly desktopSettingsService: DesktopSettingsService, + private readonly router: Router, + ) {} async closeModal() { - console.log("closing modal"); + this.router.navigate(["/"]); await this.desktopSettingsService.setInModalMode(false); } } From d26b61eed942852ba492e8e73b85a29118665cbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 18 Sep 2024 12:20:36 +0200 Subject: [PATCH 05/26] modal --- apps/desktop/src/main/tray.main.ts | 23 +--- apps/desktop/src/main/window.main.ts | 117 ++++++++---------- .../src/platform/popup-modal-styles.ts | 30 ++++- 3 files changed, 87 insertions(+), 83 deletions(-) diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index 666a9370a05..346ac175d69 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -188,7 +188,7 @@ export class TrayMain { this.hideDock(); } } else { - this.windowMain.win.show(); + this.windowMain.show(); if (this.isDarwin()) { this.showDock(); } @@ -212,14 +212,6 @@ export class TrayMain { const existingWin = this.windowMain.win; await this.desktopSettingsService.setInModalMode(true); - - existingWin.setBounds({ - width: 500, - height: 400, - }); - existingWin.setSize(450, 450, true); - existingWin.setWindowButtonVisibility(false); - existingWin.resizable = false; await existingWin.loadURL( url.format({ protocol: "file:", @@ -235,15 +227,8 @@ export class TrayMain { userAgent: cleanUserAgent(existingWin.webContents.userAgent), }, ); - existingWin.center(); - existingWin.setAlwaysOnTop(true); - existingWin.show(); - // TODO: Do things - // ?? Enqueue the browser location - // Change browser location and styling to minimal - - // Show popup - // Change styling back to full - // ?? Dequeue browser location + existingWin.once("ready-to-show", () => { + existingWin.show(); + }); } } diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index eb5441a0c07..bd57566c50e 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -11,7 +11,7 @@ import { processisolations } from "@bitwarden/desktop-napi"; import { BiometricStateService } from "@bitwarden/key-management"; import { WindowState } from "../platform/models/domain/window-state"; -import { applyMainWindowStyles } from "../platform/popup-modal-styles"; +import { applyMainWindowStyles, applyPopupModalStyles } from "../platform/popup-modal-styles"; import { DesktopSettingsService } from "../platform/services/desktop-settings.service"; import { cleanUserAgent, @@ -74,9 +74,11 @@ export class WindowMain { .pipe( pairwise(), concatMap(async ([lastValue, newValue]) => { - console.log("inModalMode updated", { lastValue, newValue }); if (lastValue && !newValue) { applyMainWindowStyles(this.win, this.windowStates[mainWindowSizeKey]); + this.win.hide(); + } else if (!lastValue && newValue) { + applyPopupModalStyles(this.win); } }), ) @@ -181,64 +183,52 @@ export class WindowMain { }); } + /// Show the window with main window styles + show() { + if (this.win != null) { + applyMainWindowStyles(this.win, this.windowStates[mainWindowSizeKey]); + this.win.show(); + } + } + async createWindow(template: "full-app" | "minimal-app" = "full-app"): Promise { - if (template === "full-app") { - this.windowStates[mainWindowSizeKey] = await this.getWindowState( - this.defaultWidth, - this.defaultHeight, - ); - this.enableAlwaysOnTop = await firstValueFrom(this.desktopSettingsService.alwaysOnTop$); - - this.session = session.fromPartition("persist:bitwarden", { cache: false }); - - // Create the browser window. - this.win = new BrowserWindow({ - width: this.windowStates[mainWindowSizeKey].width, - height: this.windowStates[mainWindowSizeKey].height, - minWidth: 400, - minHeight: 400, - x: this.windowStates[mainWindowSizeKey].x, - y: this.windowStates[mainWindowSizeKey].y, - title: app.name, - icon: isLinux() ? path.join(__dirname, "/images/icon.png") : undefined, - titleBarStyle: isMac() ? "hiddenInset" : undefined, - show: false, - backgroundColor: await this.getBackgroundColor(), - alwaysOnTop: this.enableAlwaysOnTop, - webPreferences: { - preload: path.join(__dirname, "preload.js"), - spellcheck: false, - nodeIntegration: false, - backgroundThrottling: false, - contextIsolation: true, - session: this.session, - devTools: isDev(), - }, - }); - } else { - this.win = new BrowserWindow({ - width: 450, - height: 450, - resizable: false, - icon: null, - center: true, - titleBarStyle: "hiddenInset", - frame: false, - alwaysOnTop: true, - backgroundColor: await this.getBackgroundColor(), - show: true, - webPreferences: { - preload: path.join(__dirname, "preload.js"), - spellcheck: false, - nodeIntegration: false, - backgroundThrottling: false, - contextIsolation: true, - session: this.session, - devTools: isDev(), - }, - }); + this.windowStates[mainWindowSizeKey] = await this.getWindowState( + this.defaultWidth, + this.defaultHeight, + ); + this.enableAlwaysOnTop = await firstValueFrom(this.desktopSettingsService.alwaysOnTop$); + + this.session = session.fromPartition("persist:bitwarden", { cache: false }); + + // Create the browser window. + this.win = new BrowserWindow({ + width: this.windowStates[mainWindowSizeKey].width, + height: this.windowStates[mainWindowSizeKey].height, + minWidth: 400, + minHeight: 400, + x: this.windowStates[mainWindowSizeKey].x, + y: this.windowStates[mainWindowSizeKey].y, + title: app.name, + icon: isLinux() ? path.join(__dirname, "/images/icon.png") : undefined, + titleBarStyle: isMac() ? "hiddenInset" : undefined, + show: false, + backgroundColor: await this.getBackgroundColor(), + alwaysOnTop: this.enableAlwaysOnTop, + webPreferences: { + preload: path.join(__dirname, "preload.js"), + spellcheck: false, + nodeIntegration: false, + backgroundThrottling: false, + contextIsolation: true, + session: this.session, + devTools: isDev(), + }, + }); - this.win.setWindowButtonVisibility(false); + if (template === "minimal-app") { + applyPopupModalStyles(this.win); + } else { + applyMainWindowStyles(this.win, this.windowStates[mainWindowSizeKey]); } this.win.webContents.on("dom-ready", () => { @@ -250,7 +240,10 @@ export class WindowMain { } // Show it later since it might need to be maximized. - this.win.show(); + // use once event to avoid flash on unstyled content. + this.win.once("ready-to-show", () => { + this.win.show(); + }); if (template === "full-app") { // and load the index.html of the app. @@ -365,16 +358,13 @@ export class WindowMain { } private async updateWindowState(configKey: string, win: BrowserWindow) { - console.log("updateWindowState"); if (win == null || win.isDestroyed()) { - console.log("no window/destroyed"); return; } const inModalMode = await firstValueFrom(this.desktopSettingsService.inModalMode$); if (inModalMode) { - console.log("in modal mode, ignore"); return; } @@ -388,7 +378,8 @@ export class WindowMain { } } - this.windowStates[configKey].isMaximized = win.isMaximized(); + // We're treating fullscreen as maximized + this.windowStates[configKey].isMaximized = win.isMaximized() || win.isFullScreen(); this.windowStates[configKey].displayBounds = screen.getDisplayMatching(bounds).bounds; if (!win.isMaximized() && !win.isMinimized() && !win.isFullScreen()) { diff --git a/apps/desktop/src/platform/popup-modal-styles.ts b/apps/desktop/src/platform/popup-modal-styles.ts index 3bd3abf92e3..aeccf418270 100644 --- a/apps/desktop/src/platform/popup-modal-styles.ts +++ b/apps/desktop/src/platform/popup-modal-styles.ts @@ -2,8 +2,26 @@ import { BrowserWindow } from "electron"; import { WindowState } from "./models/domain/window-state"; +const popupWidth = 450; +const popupHeight = 450; + export function applyPopupModalStyles(window: BrowserWindow) { - // + window.unmaximize(); + window.setSize(popupWidth, popupHeight); + window.center(); + window.setWindowButtonVisibility(false); + window.setMenuBarVisibility(false); + window.setResizable(false); + window.setAlwaysOnTop(true); + + // recover from full screen is a bit more hassle + if (window.isFullScreen()) { + window.setFullScreen(false); + window.once("leave-full-screen", () => { + window.setSize(popupWidth, popupHeight); + window.center(); + }); + } } export function applyMainWindowStyles(window: BrowserWindow, existingWindowState: WindowState) { @@ -12,4 +30,14 @@ export function applyMainWindowStyles(window: BrowserWindow, existingWindowState window.setPosition(existingWindowState.x, existingWindowState.y); window.setWindowButtonVisibility(true); window.setMenuBarVisibility(true); + window.setResizable(true); + window.setAlwaysOnTop(false); + // window.hide(); + + // console.log("is maximized", existingWindowState.isMaximized); + // window.setFullScreen(existingWindowState.isMaximized); + + // if (existingWindowState.isMaximized) { + // window.maximize(); + // } } From da6c9a2c18a6844a9cd57c3a1508145479567277 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Thu, 10 Oct 2024 13:24:49 +0200 Subject: [PATCH 06/26] Improved hide/show --- apps/desktop/src/main/window.main.ts | 10 ++++++++++ apps/desktop/src/platform/popup-modal-styles.ts | 5 ++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index bd57566c50e..5224dfc7c32 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -75,10 +75,16 @@ export class WindowMain { pairwise(), concatMap(async ([lastValue, newValue]) => { if (lastValue && !newValue) { + //console.log("Apply main window styles"); + // Reset the window state to the main window state applyMainWindowStyles(this.win, this.windowStates[mainWindowSizeKey]); + // Because modal is used in front of another app, UX wise it makes sense to hide the main window when leaving modal mode. this.win.hide(); } else if (!lastValue && newValue) { + // Apply the popup modal styles applyPopupModalStyles(this.win); + //console.log("show the modal"); + this.win.show(); } }), ) @@ -382,6 +388,10 @@ export class WindowMain { this.windowStates[configKey].isMaximized = win.isMaximized() || win.isFullScreen(); this.windowStates[configKey].displayBounds = screen.getDisplayMatching(bounds).bounds; + // Maybe store these as well? + //console.log("isFocused", win.isFocused()); + //console.log("isVisible", win.isVisible()); + if (!win.isMaximized() && !win.isMinimized() && !win.isFullScreen()) { this.windowStates[configKey].x = bounds.x; this.windowStates[configKey].y = bounds.y; diff --git a/apps/desktop/src/platform/popup-modal-styles.ts b/apps/desktop/src/platform/popup-modal-styles.ts index aeccf418270..629e7c84f4f 100644 --- a/apps/desktop/src/platform/popup-modal-styles.ts +++ b/apps/desktop/src/platform/popup-modal-styles.ts @@ -14,7 +14,7 @@ export function applyPopupModalStyles(window: BrowserWindow) { window.setResizable(false); window.setAlwaysOnTop(true); - // recover from full screen is a bit more hassle + // Adjusting from full screen is a bit more hassle if (window.isFullScreen()) { window.setFullScreen(false); window.once("leave-full-screen", () => { @@ -32,9 +32,8 @@ export function applyMainWindowStyles(window: BrowserWindow, existingWindowState window.setMenuBarVisibility(true); window.setResizable(true); window.setAlwaysOnTop(false); - // window.hide(); - // console.log("is maximized", existingWindowState.isMaximized); + // We're currently not recovering the maximized state, mostly due to conflicts with hiding the window. // window.setFullScreen(existingWindowState.isMaximized); // if (existingWindowState.isMaximized) { From e97c7a2810bd07a01bc1e5f75c9fb175fc7d8588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Thu, 10 Oct 2024 13:32:34 +0200 Subject: [PATCH 07/26] fixed promise --- apps/desktop/src/app/components/passkeys.component.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/app/components/passkeys.component.ts b/apps/desktop/src/app/components/passkeys.component.ts index 086640adde4..7d1e97a53cf 100644 --- a/apps/desktop/src/app/components/passkeys.component.ts +++ b/apps/desktop/src/app/components/passkeys.component.ts @@ -1,5 +1,6 @@ import { Component } from "@angular/core"; import { Router } from "@angular/router"; + import { JslibModule } from "@bitwarden/angular/jslib.module"; import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; @@ -15,7 +16,7 @@ export type BrowserSyncVerificationDialogParams = { style="background:white; display:flex; justify-content: center; align-items: center; flex-direction: column" > Date: Thu, 10 Oct 2024 13:34:49 +0200 Subject: [PATCH 08/26] File name --- apps/desktop/resources/Frame2101.png | Bin 29982 -> 0 bytes .../resources/{Frame2101.svg => frame2101.svg} | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/desktop/resources/Frame2101.png rename apps/desktop/resources/{Frame2101.svg => frame2101.svg} (100%) diff --git a/apps/desktop/resources/Frame2101.png b/apps/desktop/resources/Frame2101.png deleted file mode 100644 index 84f3ad7c81080eaa0c975fbfcf677e7acedb7652..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29982 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 C^$j@y diff --git a/apps/desktop/resources/Frame2101.svg b/apps/desktop/resources/frame2101.svg similarity index 100% rename from apps/desktop/resources/Frame2101.svg rename to apps/desktop/resources/frame2101.svg From 895607f8282488d34db5f9ad5207ff7bf3c50b9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Thu, 10 Oct 2024 13:44:32 +0200 Subject: [PATCH 09/26] fix prettier --- apps/desktop/src/main/window.main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 5224dfc7c32..b255068df21 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -46,7 +46,7 @@ export class WindowMain { private desktopSettingsService: DesktopSettingsService, private argvCallback: (argv: string[]) => void = null, private createWindowCallback: (win: BrowserWindow) => void, - ) { } + ) {} init(): Promise { // Perform a hard reload of the render process by crashing it. This is suboptimal but ensures that all memory gets From cf8d5b214668866ff20b94521e74792483899e8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Thu, 10 Oct 2024 14:48:44 +0200 Subject: [PATCH 10/26] Protecting against null API's and undefined data --- .../src/platform/popup-modal-styles.ts | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/desktop/src/platform/popup-modal-styles.ts b/apps/desktop/src/platform/popup-modal-styles.ts index 629e7c84f4f..ec1c58d11fe 100644 --- a/apps/desktop/src/platform/popup-modal-styles.ts +++ b/apps/desktop/src/platform/popup-modal-styles.ts @@ -9,8 +9,8 @@ export function applyPopupModalStyles(window: BrowserWindow) { window.unmaximize(); window.setSize(popupWidth, popupHeight); window.center(); - window.setWindowButtonVisibility(false); - window.setMenuBarVisibility(false); + window.setWindowButtonVisibility?.(false); + window.setMenuBarVisibility?.(false); window.setResizable(false); window.setAlwaysOnTop(true); @@ -26,10 +26,19 @@ export function applyPopupModalStyles(window: BrowserWindow) { export function applyMainWindowStyles(window: BrowserWindow, existingWindowState: WindowState) { window.setMinimumSize(400, 400); - window.setSize(existingWindowState.width, existingWindowState.height); - window.setPosition(existingWindowState.x, existingWindowState.y); - window.setWindowButtonVisibility(true); - window.setMenuBarVisibility(true); + + // need to guard against null/undefined values + if (existingWindowState) { + if (existingWindowState.width && existingWindowState.height) { + window.setSize(existingWindowState.width, existingWindowState.height); + } + + if (existingWindowState.x && existingWindowState.y) { + window.setPosition(existingWindowState.x, existingWindowState.y); + } + } + window.setWindowButtonVisibility?.(true); + window.setMenuBarVisibility?.(true); window.setResizable(true); window.setAlwaysOnTop(false); From a09a471d1e25d2e705006bd486bd881cdd14fb1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 28 Oct 2024 16:35:01 +0100 Subject: [PATCH 11/26] Only show fake popup to devs --- apps/desktop/src/main/tray.main.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index 346ac175d69..b3ccd022736 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -7,7 +7,7 @@ import { firstValueFrom } from "rxjs"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { DesktopSettingsService } from "../platform/services/desktop-settings.service"; -import { cleanUserAgent } from "../utils"; +import { cleanUserAgent, isDev } from "../utils"; import { WindowMain } from "./window.main"; @@ -47,6 +47,7 @@ export class TrayMain { click: () => this.toggleWindow(), }, { + visible: isDev(), label: "Fake Popup", click: () => this.fakePopup(), }, From 6a4c482b6503509a3d1110eff63ff3a47e80ecef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 28 Oct 2024 18:16:09 +0100 Subject: [PATCH 12/26] cleanup mock code --- apps/desktop/resources/frame2101.svg | 36 ------------------ apps/desktop/resources/passkeys.png | Bin 51413 -> 0 bytes .../src/app/components/passkeys.component.ts | 15 +------- 3 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 apps/desktop/resources/frame2101.svg delete mode 100644 apps/desktop/resources/passkeys.png diff --git a/apps/desktop/resources/frame2101.svg b/apps/desktop/resources/frame2101.svg deleted file mode 100644 index d36e4e6532d..00000000000 --- a/apps/desktop/resources/frame2101.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/apps/desktop/resources/passkeys.png b/apps/desktop/resources/passkeys.png deleted file mode 100644 index ca6513e5ec38f376301210f3ffab2d5258eac5c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51413 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 diff --git a/apps/desktop/src/app/components/passkeys.component.ts b/apps/desktop/src/app/components/passkeys.component.ts index 7d1e97a53cf..10b705523fd 100644 --- a/apps/desktop/src/app/components/passkeys.component.ts +++ b/apps/desktop/src/app/components/passkeys.component.ts @@ -1,32 +1,19 @@ import { Component } from "@angular/core"; import { Router } from "@angular/router"; -import { JslibModule } from "@bitwarden/angular/jslib.module"; - import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; -export type BrowserSyncVerificationDialogParams = { - fingerprint: string[]; -}; - @Component({ standalone: true, template: `

- +

Select your passkey


`, - imports: [JslibModule], }) export class PasskeysComponent { constructor( From 903cecba6f1cbaa6fa0d89ddfd7e7c4ba1b60f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 28 Oct 2024 18:16:57 +0100 Subject: [PATCH 13/26] rename minmimal-app to modal-app --- apps/desktop/src/main/tray.main.ts | 2 +- apps/desktop/src/main/window.main.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index b3ccd022736..7b2cb155385 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -205,7 +205,7 @@ export class TrayMain { private async fakePopup() { if (this.windowMain.win == null || this.windowMain.win.isDestroyed()) { - await this.windowMain.createWindow("minimal-app"); + await this.windowMain.createWindow("modal-app"); return; } diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index b255068df21..9973bbd088d 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -197,7 +197,7 @@ export class WindowMain { } } - async createWindow(template: "full-app" | "minimal-app" = "full-app"): Promise { + async createWindow(template: "full-app" | "modal-app" = "full-app"): Promise { this.windowStates[mainWindowSizeKey] = await this.getWindowState( this.defaultWidth, this.defaultHeight, @@ -231,7 +231,7 @@ export class WindowMain { }, }); - if (template === "minimal-app") { + if (template === "modal-app") { applyPopupModalStyles(this.win); } else { applyMainWindowStyles(this.win, this.windowStates[mainWindowSizeKey]); From ab7268f37125a5a9d2e8e15baf4ebc02fe8a2060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 28 Oct 2024 18:18:01 +0100 Subject: [PATCH 14/26] Added comment --- apps/desktop/src/main/tray.main.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/desktop/src/main/tray.main.ts b/apps/desktop/src/main/tray.main.ts index 7b2cb155385..eee864079bd 100644 --- a/apps/desktop/src/main/tray.main.ts +++ b/apps/desktop/src/main/tray.main.ts @@ -203,6 +203,10 @@ export class TrayMain { } } + /** + * This method is used to test modal behavior during development and could be removed in the future. + * @returns + */ private async fakePopup() { if (this.windowMain.win == null || this.windowMain.win.isDestroyed()) { await this.windowMain.createWindow("modal-app"); From 69e0f592462d0c9fc7574d16fc4e5a0ede8dfc3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 28 Oct 2024 18:19:06 +0100 Subject: [PATCH 15/26] Added comment --- .../src/platform/services/desktop-settings.service.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/desktop/src/platform/services/desktop-settings.service.ts b/apps/desktop/src/platform/services/desktop-settings.service.ts index 13b3de5bebd..332bcf87153 100644 --- a/apps/desktop/src/platform/services/desktop-settings.service.ts +++ b/apps/desktop/src/platform/services/desktop-settings.service.ts @@ -263,6 +263,11 @@ export class DesktopSettingsService { async setMinimizeOnCopy(value: boolean, userId: UserId) { await this.stateProvider.getUser(userId, MINIMIZE_ON_COPY).update(() => value); } + + /** + * Sets the modal mode of the application. Setting this changes the windows-size and other properties. + * @param value `true` if the application is in modal mode, `false` if it is not. + */ async setInModalMode(value: boolean) { await this.inModalModeState.update(() => value); } From b03615761ace44a8dd6492a3c73e6ab0c062ea86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 28 Oct 2024 18:19:42 +0100 Subject: [PATCH 16/26] removed old comment --- apps/desktop/src/main/window.main.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 9973bbd088d..aa85e076404 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -269,7 +269,6 @@ export class WindowMain { await this.win.loadURL( url.format({ protocol: "file:", - //pathname: `${__dirname}/index.html`, pathname: path.join(__dirname, "/index.html"), slashes: true, hash: "/passkeys", From fd5838253ffc890dd3cb669b7365262cdae7c728 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 28 Oct 2024 18:31:28 +0100 Subject: [PATCH 17/26] Avoided changing minimum size --- apps/desktop/src/main/window.main.ts | 4 ++-- apps/desktop/src/platform/popup-modal-styles.ts | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index aa85e076404..6784ebfaf8d 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -210,8 +210,8 @@ export class WindowMain { this.win = new BrowserWindow({ width: this.windowStates[mainWindowSizeKey].width, height: this.windowStates[mainWindowSizeKey].height, - minWidth: 400, - minHeight: 400, + minWidth: 680, + minHeight: 500, x: this.windowStates[mainWindowSizeKey].x, y: this.windowStates[mainWindowSizeKey].y, title: app.name, diff --git a/apps/desktop/src/platform/popup-modal-styles.ts b/apps/desktop/src/platform/popup-modal-styles.ts index ec1c58d11fe..a024ada9061 100644 --- a/apps/desktop/src/platform/popup-modal-styles.ts +++ b/apps/desktop/src/platform/popup-modal-styles.ts @@ -2,8 +2,9 @@ import { BrowserWindow } from "electron"; import { WindowState } from "./models/domain/window-state"; -const popupWidth = 450; -const popupHeight = 450; +// change as needed, however limited by mainwindow minimum size +const popupWidth = 680; +const popupHeight = 500; export function applyPopupModalStyles(window: BrowserWindow) { window.unmaximize(); @@ -25,7 +26,7 @@ export function applyPopupModalStyles(window: BrowserWindow) { } export function applyMainWindowStyles(window: BrowserWindow, existingWindowState: WindowState) { - window.setMinimumSize(400, 400); + window.setMinimumSize(680, 500); // need to guard against null/undefined values if (existingWindowState) { From 30cdc3990a972c4db7d78b5b8b5116a039a70344 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 28 Oct 2024 18:33:40 +0100 Subject: [PATCH 18/26] Add small comment --- apps/desktop/src/main/window.main.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 6784ebfaf8d..f67f79ebdbe 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -266,6 +266,7 @@ export class WindowMain { }, ); } else { + // we're in modal mode - load the passkeys page await this.win.loadURL( url.format({ protocol: "file:", From 4dfdc34f10a48944ac89be4067211effe63d84c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 30 Oct 2024 13:01:49 +0100 Subject: [PATCH 19/26] Rename component --- .../{passkeys.component.ts => Fido2PlaceholderComponent.ts} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename apps/desktop/src/app/components/{passkeys.component.ts => Fido2PlaceholderComponent.ts} (95%) diff --git a/apps/desktop/src/app/components/passkeys.component.ts b/apps/desktop/src/app/components/Fido2PlaceholderComponent.ts similarity index 95% rename from apps/desktop/src/app/components/passkeys.component.ts rename to apps/desktop/src/app/components/Fido2PlaceholderComponent.ts index 10b705523fd..0c1f9dd1113 100644 --- a/apps/desktop/src/app/components/passkeys.component.ts +++ b/apps/desktop/src/app/components/Fido2PlaceholderComponent.ts @@ -15,7 +15,7 @@ import { DesktopSettingsService } from "../../platform/services/desktop-settings
`, }) -export class PasskeysComponent { +export class Fido2PlaceholderComponent { constructor( private readonly desktopSettingsService: DesktopSettingsService, private readonly router: Router, From adf781743074e7d3bf4dfb9db56663476c51f4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 30 Oct 2024 13:11:27 +0100 Subject: [PATCH 20/26] adress feedback --- apps/desktop/src/main/window.main.ts | 6 ++---- apps/desktop/src/platform/popup-modal-styles.ts | 16 ++++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index f67f79ebdbe..76cc72df1c2 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -75,7 +75,6 @@ export class WindowMain { pairwise(), concatMap(async ([lastValue, newValue]) => { if (lastValue && !newValue) { - //console.log("Apply main window styles"); // Reset the window state to the main window state applyMainWindowStyles(this.win, this.windowStates[mainWindowSizeKey]); // Because modal is used in front of another app, UX wise it makes sense to hide the main window when leaving modal mode. @@ -83,7 +82,6 @@ export class WindowMain { } else if (!lastValue && newValue) { // Apply the popup modal styles applyPopupModalStyles(this.win); - //console.log("show the modal"); this.win.show(); } }), @@ -389,8 +387,8 @@ export class WindowMain { this.windowStates[configKey].displayBounds = screen.getDisplayMatching(bounds).bounds; // Maybe store these as well? - //console.log("isFocused", win.isFocused()); - //console.log("isVisible", win.isVisible()); + // win.isFocused(); + // win.isVisible(); if (!win.isMaximized() && !win.isMinimized() && !win.isFullScreen()) { this.windowStates[configKey].x = bounds.x; diff --git a/apps/desktop/src/platform/popup-modal-styles.ts b/apps/desktop/src/platform/popup-modal-styles.ts index a024ada9061..9c3f06b34bf 100644 --- a/apps/desktop/src/platform/popup-modal-styles.ts +++ b/apps/desktop/src/platform/popup-modal-styles.ts @@ -29,15 +29,15 @@ export function applyMainWindowStyles(window: BrowserWindow, existingWindowState window.setMinimumSize(680, 500); // need to guard against null/undefined values - if (existingWindowState) { - if (existingWindowState.width && existingWindowState.height) { - window.setSize(existingWindowState.width, existingWindowState.height); - } - - if (existingWindowState.x && existingWindowState.y) { - window.setPosition(existingWindowState.x, existingWindowState.y); - } + + if (existingWindowState?.width && existingWindowState?.height) { + window.setSize(existingWindowState.width, existingWindowState.height); + } + + if (existingWindowState?.x && existingWindowState?.y) { + window.setPosition(existingWindowState.x, existingWindowState.y); } + window.setWindowButtonVisibility?.(true); window.setMenuBarVisibility?.(true); window.setResizable(true); From b19e98719395fe8eaa1ad65da29fcdde65c1d510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 30 Oct 2024 13:13:51 +0100 Subject: [PATCH 21/26] Fixed uppercase file --- ...Fido2PlaceholderComponent.ts => fido2placeholder.component.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/desktop/src/app/components/{Fido2PlaceholderComponent.ts => fido2placeholder.component.ts} (100%) diff --git a/apps/desktop/src/app/components/Fido2PlaceholderComponent.ts b/apps/desktop/src/app/components/fido2placeholder.component.ts similarity index 100% rename from apps/desktop/src/app/components/Fido2PlaceholderComponent.ts rename to apps/desktop/src/app/components/fido2placeholder.component.ts From ae0e677457499b808e915349e09627cdbd036c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 30 Oct 2024 13:41:09 +0100 Subject: [PATCH 22/26] Fixed build --- apps/desktop/src/app/app-routing.module.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/desktop/src/app/app-routing.module.ts b/apps/desktop/src/app/app-routing.module.ts index 3c25d5f9995..427b00d0660 100644 --- a/apps/desktop/src/app/app-routing.module.ts +++ b/apps/desktop/src/app/app-routing.module.ts @@ -52,7 +52,7 @@ import { TwoFactorComponent } from "../auth/two-factor.component"; import { UpdateTempPasswordComponent } from "../auth/update-temp-password.component"; import { VaultComponent } from "../vault/app/vault/vault.component"; -import { PasskeysComponent } from "./components/passkeys.component"; +import { Fido2PlaceholderComponent } from "./components/fido2placeholder.component"; import { SendComponent } from "./tools/send/send.component"; /** @@ -203,7 +203,7 @@ const routes: Routes = [ ), { path: "passkeys", - component: PasskeysComponent, + component: Fido2PlaceholderComponent, }, { path: "", From 7ed1b67ac3a9d8790eb23f2cfe3863bdf0060dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 30 Oct 2024 14:48:10 +0100 Subject: [PATCH 23/26] Added codeowners --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5ba5885d725..ef2337d1bce 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -94,6 +94,7 @@ libs/common/src/autofill @bitwarden/team-autofill-dev # DuckDuckGo integration apps/desktop/native-messaging-test-runner @bitwarden/team-autofill-dev apps/desktop/src/services/native-message-handler.service.ts @bitwarden/team-autofill-dev +apps/desktop/src/app/components/fido2placeholder.component.ts @bitwarden/team-autofill-dev ## Component Library ## .storybook @bitwarden/team-design-system From ee939b34c5bb3fa5b2b441ad0eacac74102b22d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 30 Oct 2024 14:49:38 +0100 Subject: [PATCH 24/26] added void --- apps/desktop/src/main/window.main.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index 76cc72df1c2..fe8f1afebb2 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -252,8 +252,7 @@ export class WindowMain { if (template === "full-app") { // and load the index.html of the app. // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.win.loadURL( + void this.win.loadURL( url.format({ protocol: "file:", pathname: path.join(__dirname, "/index.html"), From 865236b1b549b324ab36810d8b379061b2a625ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Wed, 30 Oct 2024 14:54:56 +0100 Subject: [PATCH 25/26] commentary --- apps/desktop/src/main/window.main.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts index fe8f1afebb2..6488e854f5e 100644 --- a/apps/desktop/src/main/window.main.ts +++ b/apps/desktop/src/main/window.main.ts @@ -381,7 +381,7 @@ export class WindowMain { } } - // We're treating fullscreen as maximized + // We treat fullscreen as maximized (would be even better to store isFullscreen as its own flag). this.windowStates[configKey].isMaximized = win.isMaximized() || win.isFullScreen(); this.windowStates[configKey].displayBounds = screen.getDisplayMatching(bounds).bounds; From 8b30e71525289e79096a95840f4bb32ad6d690da Mon Sep 17 00:00:00 2001 From: Andreas Coroiu Date: Fri, 20 Dec 2024 13:53:27 +0100 Subject: [PATCH 26/26] feat: reset setting on app start --- apps/desktop/src/app/services/init.service.ts | 3 +++ .../src/platform/services/desktop-settings.service.ts | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/apps/desktop/src/app/services/init.service.ts b/apps/desktop/src/app/services/init.service.ts index de80f95593a..5d480508d13 100644 --- a/apps/desktop/src/app/services/init.service.ts +++ b/apps/desktop/src/app/services/init.service.ts @@ -21,6 +21,7 @@ import { UserId } from "@bitwarden/common/types/guid"; import { KeyService as KeyServiceAbstraction } from "@bitwarden/key-management"; import { DesktopAutofillService } from "../../autofill/services/desktop-autofill.service"; +import { DesktopSettingsService } from "../../platform/services/desktop-settings.service"; import { I18nRendererService } from "../../platform/services/i18n.renderer.service"; import { SshAgentService } from "../../platform/services/ssh-agent.service"; import { VersionService } from "../../platform/services/version.service"; @@ -47,6 +48,7 @@ export class InitService { private versionService: VersionService, private sshAgentService: SshAgentService, private autofillService: DesktopAutofillService, + private desktopSettingsService: DesktopSettingsService, @Inject(DOCUMENT) private document: Document, ) {} @@ -79,6 +81,7 @@ export class InitService { const htmlEl = this.win.document.documentElement; htmlEl.classList.add("os_" + this.platformUtilsService.getDeviceString()); this.themingService.applyThemeChangesTo(this.document); + await this.desktopSettingsService.resetInModalMode(); this.versionService.init(); diff --git a/apps/desktop/src/platform/services/desktop-settings.service.ts b/apps/desktop/src/platform/services/desktop-settings.service.ts index 9dab58f870a..77bd57cddb1 100644 --- a/apps/desktop/src/platform/services/desktop-settings.service.ts +++ b/apps/desktop/src/platform/services/desktop-settings.service.ts @@ -171,6 +171,14 @@ export class DesktopSettingsService { ); } + /** + * This is used to clear the setting on application start to make sure we don't end up + * stuck in modal mode if the application is force-closed in modal mode. + */ + async resetInModalMode() { + await this.inModalModeState.update(() => false); + } + async setHardwareAcceleration(enabled: boolean) { await this.hwState.update(() => enabled); }