From aa91381efd65f399f57241d7f28ded3092a396f4 Mon Sep 17 00:00:00 2001 From: UnathiCodex Date: Thu, 16 Jul 2026 19:35:05 +0200 Subject: [PATCH] fix(desktop): preserve zoom across display moves Reassert the persisted webContents zoom after BrowserWindow moved, covering Windows monitor transitions where Chromium recalculates display scaling and drops the user-selected zoom. --- apps/desktop/electron/main.ts | 5 +++-- apps/desktop/electron/zoom.test.ts | 5 +++-- apps/desktop/electron/zoom.ts | 5 +++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/apps/desktop/electron/main.ts b/apps/desktop/electron/main.ts index fb8ecd5613e1..d3cc345fcf59 100644 --- a/apps/desktop/electron/main.ts +++ b/apps/desktop/electron/main.ts @@ -6951,8 +6951,9 @@ function wireCommonWindowHandlers(win, { zoom = true }: { zoom?: boolean } = {}) if (zoom) { installZoomShortcuts(win) - // Re-apply persisted zoom on show/restore (Windows drops webContents zoom on - // minimize/restore) and on first load (reloads / crash recovery). + // Re-apply persisted zoom on show/restore/cross-display move (Windows can + // drop webContents zoom after minimize or a monitor-scale change) and on + // first load (reloads / crash recovery). installZoomReassertOnWindowEvents(win, () => restorePersistedZoomLevel(win)) win.webContents.once('did-finish-load', () => restorePersistedZoomLevel(win)) } diff --git a/apps/desktop/electron/zoom.test.ts b/apps/desktop/electron/zoom.test.ts index d0a1517d38e5..7fb81299494e 100644 --- a/apps/desktop/electron/zoom.test.ts +++ b/apps/desktop/electron/zoom.test.ts @@ -64,7 +64,7 @@ test('extreme percentages clamp to the level bounds', () => { assert.equal(percentToZoomLevel(1_000_000), 9) }) -test('installZoomReassertOnWindowEvents wires show and restore', () => { +test('installZoomReassertOnWindowEvents wires show, restore, and cross-display moves', () => { const handlers = new Map() const win = { @@ -82,7 +82,8 @@ test('installZoomReassertOnWindowEvents wires show and restore', () => { assert.deepEqual([...handlers.keys()], [...ZOOM_REASSERT_WINDOW_EVENTS]) handlers.get('show')() handlers.get('restore')() - assert.equal(calls, 2) + handlers.get('moved')() + assert.equal(calls, 3) }) test('installZoomReassertOnWindowEvents skips destroyed windows', () => { diff --git a/apps/desktop/electron/zoom.ts b/apps/desktop/electron/zoom.ts index baf8ff48b70e..aa7f31bc240b 100644 --- a/apps/desktop/electron/zoom.ts +++ b/apps/desktop/electron/zoom.ts @@ -49,8 +49,9 @@ export function applyZoomLevel(webContents, level) { } // Chromium on Windows can drop webContents zoom when a BrowserWindow is minimized -// and restored. Re-apply the persisted level on these lifecycle transitions. -export const ZOOM_REASSERT_WINDOW_EVENTS = ['show', 'restore'] +// and restored or crosses onto a monitor with different display scaling. Re-apply +// the persisted level after each completed lifecycle transition. +export const ZOOM_REASSERT_WINDOW_EVENTS = ['show', 'restore', 'moved'] export function installZoomReassertOnWindowEvents(win, reassert) { if (!win?.on) {