Add zoom slider, match offical client zoom

This commit is contained in:
Kaydax 2024-01-31 16:00:55 -05:00
parent 6993b2a7d4
commit 54dd33dea5
No known key found for this signature in database
GPG key ID: 6D32EED87DE7F090
7 changed files with 123 additions and 9 deletions

View file

@ -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[]) => { handle(IpcEvents.SPELLCHECK_SET_LANGUAGES, (_, languages: string[]) => {
const ses = session.defaultSession; const ses = session.defaultSession;

View file

@ -9,6 +9,7 @@ import {
BrowserWindow, BrowserWindow,
BrowserWindowConstructorOptions, BrowserWindowConstructorOptions,
dialog, dialog,
globalShortcut,
Menu, Menu,
MenuItemConstructorOptions, MenuItemConstructorOptions,
nativeTheme, nativeTheme,
@ -229,14 +230,14 @@ function initMenuBar(win: BrowserWindow) {
click() { click() {
app.quit(); 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; ] satisfies MenuItemList;
const menu = Menu.buildFromTemplate([ const menu = Menu.buildFromTemplate([
@ -440,6 +441,35 @@ function createMainWindow() {
const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDesktopMain.js"))); 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() { export async function createWindows() {
const startMinimized = process.argv.includes("--start-minimized"); const startMinimized = process.argv.includes("--start-minimized");
const splash = createSplashWindow(startMinimized); const splash = createSplashWindow(startMinimized);
@ -453,6 +483,8 @@ export async function createWindows() {
mainWin.webContents.on("did-finish-load", () => { mainWin.webContents.on("did-finish-load", () => {
splash.destroy(); splash.destroy();
mainWin.webContents.setZoomFactor(Settings.store.zoomFactor ?? 1);
if (!startMinimized) { if (!startMinimized) {
mainWin!.show(); mainWin!.show();
if (State.store.maximized && !isDeckGameMode) mainWin!.maximize(); if (State.store.maximized && !isDeckGameMode) mainWin!.maximize();
@ -470,6 +502,32 @@ export async function createWindows() {
mainWin!.maximize(); 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(); initArRPC();

View file

@ -54,7 +54,8 @@ export const VesktopNative = {
focus: () => invoke<void>(IpcEvents.FOCUS), focus: () => invoke<void>(IpcEvents.FOCUS),
close: (key?: string) => invoke<void>(IpcEvents.CLOSE, key), close: (key?: string) => invoke<void>(IpcEvents.CLOSE, key),
minimize: () => invoke<void>(IpcEvents.MINIMIZE), minimize: () => invoke<void>(IpcEvents.MINIMIZE),
maximize: () => invoke<void>(IpcEvents.MAXIMIZE) maximize: () => invoke<void>(IpcEvents.MAXIMIZE),
zoom: (zoom: number) => invoke<void>(IpcEvents.SET_ZOOM, zoom)
}, },
capturer: { capturer: {
getLargeThumbnail: (id: string) => invoke<string>(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, id) getLargeThumbnail: (id: string) => invoke<string>(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, id)

View file

@ -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_VENCORD_RENDERER_SCRIPT));
webFrame.executeJavaScript(ipcRenderer.sendSync(IpcEvents.GET_RENDERER_SCRIPT)); webFrame.executeJavaScript(ipcRenderer.sendSync(IpcEvents.GET_RENDERER_SCRIPT));
ipcRenderer.on("zoomChanged", (event, newZoomFactor) => {
window.dispatchEvent(new CustomEvent("zoomChanged", { detail: newZoomFactor }));
});
// #region css // #region css
const rendererCss = ipcRenderer.sendSync(IpcEvents.GET_RENDERER_CSS_FILE); const rendererCss = ipcRenderer.sendSync(IpcEvents.GET_RENDERER_CSS_FILE);

View file

@ -7,7 +7,17 @@
import "./settings.css"; import "./settings.css";
import { Margins } from "@vencord/types/utils"; 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 { setBadge } from "renderer/appBadge";
import { useSettings } from "renderer/settings"; import { useSettings } from "renderer/settings";
import { isMac } from "renderer/utils"; import { isMac } from "renderer/utils";
@ -19,6 +29,20 @@ export default function SettingsUi() {
const { autostart } = VesktopNative; const { autostart } = VesktopNative;
const [autoStartEnabled, setAutoStartEnabled] = useState(autostart.isEnabled()); 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<false | [keyof typeof Settings, string, string, boolean?, (() => boolean)?]> = [ const allSwitches: Array<false | [keyof typeof Settings, string, string, boolean?, (() => boolean)?]> = [
[ [
@ -153,6 +177,27 @@ export default function SettingsUi() {
</> </>
)} )}
<>
<Forms.FormTitle className={Margins.top16 + " " + Margins.bottom8}>Zoom Level</Forms.FormTitle>
<Slider
className={Margins.top20}
initialValue={zoomFactor}
defaultValue={1}
onValueChange={v => {
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)}`)}
></Slider>
</>
<Forms.FormDivider className={Margins.top16 + " " + Margins.bottom16} />
<Forms.FormTitle>Vencord Location</Forms.FormTitle> <Forms.FormTitle>Vencord Location</Forms.FormTitle>
<Forms.FormText> <Forms.FormText>
Vencord files are loaded from{" "} Vencord files are loaded from{" "}

View file

@ -18,6 +18,7 @@ export const enum IpcEvents {
FOCUS = "VCD_FOCUS", FOCUS = "VCD_FOCUS",
MINIMIZE = "VCD_MINIMIZE", MINIMIZE = "VCD_MINIMIZE",
MAXIMIZE = "VCD_MAXIMIZE", MAXIMIZE = "VCD_MAXIMIZE",
SET_ZOOM = "VCD_ZOOM",
SHOW_ITEM_IN_FOLDER = "VCD_SHOW_ITEM_IN_FOLDER", SHOW_ITEM_IN_FOLDER = "VCD_SHOW_ITEM_IN_FOLDER",
GET_SETTINGS = "VCD_GET_SETTINGS", GET_SETTINGS = "VCD_GET_SETTINGS",

View file

@ -20,6 +20,7 @@ export interface Settings {
arRPC?: boolean; arRPC?: boolean;
appBadge?: boolean; appBadge?: boolean;
disableMinSize?: boolean; disableMinSize?: boolean;
zoomFactor?: number;
/** @deprecated use customTitleBar */ /** @deprecated use customTitleBar */
discordWindowsTitleBar?: boolean; discordWindowsTitleBar?: boolean;