From 54dd33dea5d17698a8a9cf9db3bea3d92b44ac29 Mon Sep 17 00:00:00 2001 From: Kaydax Date: Wed, 31 Jan 2024 16:00:55 -0500 Subject: [PATCH] Add zoom slider, match offical client zoom --- src/main/ipc.ts | 4 ++ src/main/mainWindow.ts | 72 +++++++++++++++++++++++++--- src/preload/VesktopNative.ts | 3 +- src/preload/index.ts | 4 ++ src/renderer/components/Settings.tsx | 47 +++++++++++++++++- src/shared/IpcEvents.ts | 1 + src/shared/settings.d.ts | 1 + 7 files changed, 123 insertions(+), 9 deletions(-) diff --git a/src/main/ipc.ts b/src/main/ipc.ts index e0bf131..9627d35 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -93,6 +93,10 @@ handle(IpcEvents.MAXIMIZE, e => { } }); +handle(IpcEvents.SET_ZOOM, (e, zoom: number) => { + mainWin.webContents.setZoomFactor(zoom); +}); + handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => { const ses = session.defaultSession; diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 62a2559..312c785 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -9,6 +9,7 @@ import { BrowserWindow, BrowserWindowConstructorOptions, dialog, + globalShortcut, Menu, MenuItemConstructorOptions, nativeTheme, @@ -229,14 +230,14 @@ function initMenuBar(win: BrowserWindow) { click() { app.quit(); } - }, - // See https://github.com/electron/electron/issues/14742 and https://github.com/electron/electron/issues/5256 - { - label: "Zoom in (hidden, hack for Qwertz and others)", - accelerator: "CmdOrCtrl+=", - role: "zoomIn", - visible: false } + // See https://github.com/electron/electron/issues/14742 and https://github.com/electron/electron/issues/5256 + // { + // label: "Zoom in (hidden, hack for Qwertz and others)", + // accelerator: "CmdOrCtrl+=", + // role: "zoomIn", + // visible: false + // } ] satisfies MenuItemList; const menu = Menu.buildFromTemplate([ @@ -440,6 +441,35 @@ function createMainWindow() { const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDesktopMain.js"))); +const allowedZoomFactors = [0.5, 0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2]; + +function handleZoomIn() { + const zoomFactor = Settings.store.zoomFactor ?? 1; + const currentIndex = allowedZoomFactors.indexOf(zoomFactor); + if (currentIndex < allowedZoomFactors.length - 1) { + const newZoomFactor = allowedZoomFactors[currentIndex + 1]; + Settings.setData({ zoomFactor: newZoomFactor }); + mainWin.webContents.setZoomFactor(newZoomFactor); + mainWin.webContents.send("zoomChanged", newZoomFactor); + } +} + +function handleZoomOut() { + const zoomFactor = Settings.store.zoomFactor ?? 1; + const currentIndex = allowedZoomFactors.indexOf(zoomFactor); + if (currentIndex > 0) { + const newZoomFactor = allowedZoomFactors[currentIndex - 1]; + Settings.setData({ zoomFactor: newZoomFactor }); + mainWin.webContents.setZoomFactor(newZoomFactor); + mainWin.webContents.send("zoomChanged", newZoomFactor); + } +} + +function resetZoom() { + Settings.setData({ zoomFactor: 1 }); + mainWin.webContents.setZoomFactor(1); +} + export async function createWindows() { const startMinimized = process.argv.includes("--start-minimized"); const splash = createSplashWindow(startMinimized); @@ -453,6 +483,8 @@ export async function createWindows() { mainWin.webContents.on("did-finish-load", () => { splash.destroy(); + mainWin.webContents.setZoomFactor(Settings.store.zoomFactor ?? 1); + if (!startMinimized) { mainWin!.show(); if (State.store.maximized && !isDeckGameMode) mainWin!.maximize(); @@ -470,6 +502,32 @@ export async function createWindows() { mainWin!.maximize(); } }); + + mainWin.on("focus", () => { + globalShortcut.register("CommandOrControl+0", () => { + resetZoom(); + }); + globalShortcut.register("CommandOrControl+plus", () => { + handleZoomIn(); + }); + globalShortcut.register("CommandOrControl+=", () => { + handleZoomIn(); + }); + globalShortcut.register("CommandOrControl+-", () => { + handleZoomOut(); + }); + globalShortcut.register("CommandOrControl+_", () => { + handleZoomOut(); + }); + }); + + mainWin.on("blur", () => { + globalShortcut.unregister("CommandOrControl+0"); + globalShortcut.unregister("CommandOrControl+plus"); + globalShortcut.unregister("CommandOrControl+="); + globalShortcut.unregister("CommandOrControl+-"); + globalShortcut.unregister("CommandOrControl+_"); + }); }); initArRPC(); diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 625b8c1..86557ee 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -54,7 +54,8 @@ export const VesktopNative = { focus: () => invoke(IpcEvents.FOCUS), close: (key?: string) => invoke(IpcEvents.CLOSE, key), minimize: () => invoke(IpcEvents.MINIMIZE), - maximize: () => invoke(IpcEvents.MAXIMIZE) + maximize: () => invoke(IpcEvents.MAXIMIZE), + zoom: (zoom: number) => invoke(IpcEvents.SET_ZOOM, zoom) }, capturer: { getLargeThumbnail: (id: string) => invoke(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, id) diff --git a/src/preload/index.ts b/src/preload/index.ts index 2cc0d11..edcd992 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -17,6 +17,10 @@ require(ipcRenderer.sendSync(IpcEvents.GET_VENCORD_PRELOAD_FILE)); webFrame.executeJavaScript(ipcRenderer.sendSync(IpcEvents.GET_VENCORD_RENDERER_SCRIPT)); webFrame.executeJavaScript(ipcRenderer.sendSync(IpcEvents.GET_RENDERER_SCRIPT)); +ipcRenderer.on("zoomChanged", (event, newZoomFactor) => { + window.dispatchEvent(new CustomEvent("zoomChanged", { detail: newZoomFactor })); +}); + // #region css const rendererCss = ipcRenderer.sendSync(IpcEvents.GET_RENDERER_CSS_FILE); diff --git a/src/renderer/components/Settings.tsx b/src/renderer/components/Settings.tsx index eb0387f..73235a4 100644 --- a/src/renderer/components/Settings.tsx +++ b/src/renderer/components/Settings.tsx @@ -7,7 +7,17 @@ import "./settings.css"; import { Margins } from "@vencord/types/utils"; -import { Button, Forms, Select, Switch, Text, Toasts, useState } from "@vencord/types/webpack/common"; +import { + Button, + Forms, + Select, + Slider, + Switch, + Text, + Toasts, + useEffect, + useState +} from "@vencord/types/webpack/common"; import { setBadge } from "renderer/appBadge"; import { useSettings } from "renderer/settings"; import { isMac } from "renderer/utils"; @@ -19,6 +29,20 @@ export default function SettingsUi() { const { autostart } = VesktopNative; const [autoStartEnabled, setAutoStartEnabled] = useState(autostart.isEnabled()); + const [zoomFactor, setZoomFactor] = useState(Settings.zoomFactor ?? 1); + + useEffect(() => { + const handleZoomChange = event => { + console.log("zoom changed", event.detail); + setZoomFactor(event.detail); + }; + + window.addEventListener("zoomChanged", handleZoomChange); + + return () => { + window.removeEventListener("zoomChanged", handleZoomChange); + }; + }, []); const allSwitches: Array boolean)?]> = [ [ @@ -153,6 +177,27 @@ export default function SettingsUi() { )} + <> + Zoom Level + { + Settings.zoomFactor = v; + VesktopNative.win.zoom(v); + setZoomFactor(v); + }} + minValue={0.5} + maxValue={2} + markers={[0.5, 0.67, 0.75, 0.8, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2]} + stickToMarkers={true} + onMarkerRender={v => (v === 1 ? "100" : `${Math.round(v * 100)}`)} + > + + + + Vencord Location Vencord files are loaded from{" "} diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index df64403..dfba9e5 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -18,6 +18,7 @@ export const enum IpcEvents { FOCUS = "VCD_FOCUS", MINIMIZE = "VCD_MINIMIZE", MAXIMIZE = "VCD_MAXIMIZE", + SET_ZOOM = "VCD_ZOOM", SHOW_ITEM_IN_FOLDER = "VCD_SHOW_ITEM_IN_FOLDER", GET_SETTINGS = "VCD_GET_SETTINGS", diff --git a/src/shared/settings.d.ts b/src/shared/settings.d.ts index d796e4b..6ff3edd 100644 --- a/src/shared/settings.d.ts +++ b/src/shared/settings.d.ts @@ -20,6 +20,7 @@ export interface Settings { arRPC?: boolean; appBadge?: boolean; disableMinSize?: boolean; + zoomFactor?: number; /** @deprecated use customTitleBar */ discordWindowsTitleBar?: boolean;