Prevent Electron modifier wheel zoom (#1016)

This commit is contained in:
ZacharyZcR
2026-07-10 08:03:03 +08:00
committed by GitHub
parent aef34fd966
commit 37560fa133
3 changed files with 62 additions and 0 deletions
+3
View File
@@ -10,6 +10,7 @@ import { Toaster } from "@/components/sonner";
import { Auth, getStoredAuth, clearStoredAuth } from "@/auth/Auth";
import { getUserInfo, getCurrentToken, appReadyPromise } from "@/main-axios";
import { applyAccentColor, applyFontSize } from "@/lib/theme";
import { installElectronWheelZoomGuard } from "@/lib/electron-wheel-zoom";
import type { FontSizeId } from "@/types/ui-types";
import { useServiceWorker } from "@/hooks/use-service-worker";
import { useTranslation } from "react-i18next";
@@ -340,6 +341,8 @@ function RootApp() {
return <App />;
}
installElectronWheelZoomGuard();
prepareClientCacheVersion().finally(() => {
createRoot(document.getElementById("root")!).render(
<StrictMode>
+39
View File
@@ -0,0 +1,39 @@
import { afterEach, describe, expect, it } from "vitest";
import { installElectronWheelZoomGuard } from "./electron-wheel-zoom";
const win = window as unknown as Record<string, unknown>;
let cleanup: (() => void) | undefined;
afterEach(() => {
cleanup?.();
cleanup = undefined;
delete win.IS_ELECTRON;
delete win.electronAPI;
});
function dispatchWheel(init?: WheelEventInit): WheelEvent {
const event = new WheelEvent("wheel", {
bubbles: true,
cancelable: true,
...init,
});
window.dispatchEvent(event);
return event;
}
describe("installElectronWheelZoomGuard", () => {
it("does not block ordinary browser wheel events", () => {
cleanup = installElectronWheelZoomGuard();
expect(dispatchWheel({ ctrlKey: true }).defaultPrevented).toBe(false);
});
it("blocks modifier wheel zoom in Electron", () => {
win.electronAPI = { isElectron: true };
cleanup = installElectronWheelZoomGuard();
expect(dispatchWheel({ metaKey: true }).defaultPrevented).toBe(true);
expect(dispatchWheel({ ctrlKey: true }).defaultPrevented).toBe(true);
expect(dispatchWheel().defaultPrevented).toBe(false);
});
});
+20
View File
@@ -0,0 +1,20 @@
import { isElectron } from "./electron";
export function installElectronWheelZoomGuard(): () => void {
if (!isElectron()) return () => {};
const preventModifierWheelZoom = (event: WheelEvent) => {
if (!event.metaKey && !event.ctrlKey) return;
event.preventDefault();
};
window.addEventListener("wheel", preventModifierWheelZoom, {
capture: true,
passive: false,
});
return () =>
window.removeEventListener("wheel", preventModifierWheelZoom, {
capture: true,
});
}