From ad0ddfb15d2a3589fac70162a181cfbfffe49d97 Mon Sep 17 00:00:00 2001 From: liuhao1024 Date: Sat, 18 Jul 2026 10:05:30 -0700 Subject: [PATCH] feat(desktop): support Ctrl/Cmd + mouse wheel zoom (#40295) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ground-truth reapply of PR #40414 by @liuhao1024. The original branch predates the ts-ify migration and implemented the gesture by injecting a DOM wheel listener via executeJavaScript + a new IPC channel. Current Electron surfaces the modifier+wheel gesture natively as the main-process webContents 'zoom-changed' event, so the salvage uses that instead: no renderer injection, no new preload surface, no new IPC channel. The handler routes through setAndPersistZoomLevel — the same persist+notify funnel as the keyboard shortcuts — so wheel zoom uses the same 0.1 half-step, persists to zoom-state.json across restarts, and keeps the settings Scale control in sync. Session windows get the gesture automatically via wireCommonWindowHandlers; the pet overlay stays opted out via zoomWiringForWindowKind. --- apps/desktop/electron/main.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/apps/desktop/electron/main.ts b/apps/desktop/electron/main.ts index 5a14aedfce58..2c15234beda1 100644 --- a/apps/desktop/electron/main.ts +++ b/apps/desktop/electron/main.ts @@ -4984,6 +4984,18 @@ function installZoomShortcuts(window) { setAndPersistZoomLevel(window, window.webContents.getZoomLevel() - ZOOM_STEP) } }) + + // Ctrl/Cmd + mouse wheel — the standard desktop/browser zoom gesture + // (#40295). Chromium surfaces it as the main-process 'zoom-changed' event + // (wheel events are DOM-side, so before-input-event never sees them). + // Route through the same persist+notify funnel as the keyboard shortcuts + // so wheel zoom survives restarts and the settings Scale control stays in + // sync, and use the same half step for consistency. + window.webContents.on('zoom-changed', (event, zoomDirection) => { + event.preventDefault() + const delta = zoomDirection === 'in' ? ZOOM_STEP : -ZOOM_STEP + setAndPersistZoomLevel(window, window.webContents.getZoomLevel() + delta) + }) } function installContextMenu(window) {