fix(desktop): preserve zoom across display moves (#65874)

Reassert the persisted webContents zoom after BrowserWindow moved, covering Windows monitor transitions where Chromium recalculates display scaling and drops the user-selected zoom.
This commit is contained in:
UnathiCodex 2026-07-16 21:21:43 +02:00 committed by GitHub
parent c387be08b9
commit bcf0d74572
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 9 additions and 6 deletions

View file

@ -6981,8 +6981,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))
}

View file

@ -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', () => {

View file

@ -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) {