diff --git a/src/main/ipc.ts b/src/main/ipc.ts index e0bf131..0c7b11c 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -7,7 +7,17 @@ if (process.platform === "linux") import("./venmic"); import { execFile } from "child_process"; -import { app, BrowserWindow, clipboard, dialog, nativeImage, RelaunchOptions, session, shell } from "electron"; +import { + app, + BrowserWindow, + clipboard, + dialog, + globalShortcut, + nativeImage, + RelaunchOptions, + session, + shell +} from "electron"; import { mkdirSync, readFileSync, watch } from "fs"; import { open, readFile } from "fs/promises"; import { release } from "os"; @@ -130,6 +140,20 @@ handle(IpcEvents.CLIPBOARD_COPY_IMAGE, async (_, buf: ArrayBuffer, src: string) }); }); +const registered_keybinds = {}; + +handle(IpcEvents.KEYBIND_REGISTER, (_, id: string, shortcut: string) => { + globalShortcut.register(shortcut, () => { + // false here implies `keyup` + // electron's global shortcut system doesn't really register keyup or down as far as i can tell + mainWin.webContents.executeJavaScript(`Vesktop.keybindCallbacks["${id}"](false)`); + }); + registered_keybinds[id] = shortcut; +}); +handle(IpcEvents.KEYBIND_UNREGISTER, (_, id: string) => { + globalShortcut.unregister(registered_keybinds[id]); +}); + function readCss() { return readFile(VENCORD_QUICKCSS_FILE, "utf-8").catch(() => ""); } diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 625b8c1..a755ae5 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -75,5 +75,9 @@ export const VesktopNative = { clipboard: { copyImage: (imageBuffer: Uint8Array, imageSrc: string) => invoke(IpcEvents.CLIPBOARD_COPY_IMAGE, imageBuffer, imageSrc) + }, + keybind: { + register: (id: string, shortcut: string) => invoke(IpcEvents.KEYBIND_REGISTER, id, shortcut), + uregister: (id: string) => invoke(IpcEvents.KEYBIND_UNREGISTER, id) } }; diff --git a/src/renderer/index.ts b/src/renderer/index.ts index 1ccc2e4..a1c3de9 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -21,6 +21,8 @@ export { Settings }; const InviteActions = findByPropsLazy("resolveInvite"); +export const keybindCallbacks: { [id: string]: Function } = {}; + export async function openInviteModal(code: string) { const { invite } = await InviteActions.resolveInvite(code, "Desktop Modal"); if (!invite) return false; diff --git a/src/renderer/patches/index.ts b/src/renderer/patches/index.ts index 7d4c4b3..e09ff23 100644 --- a/src/renderer/patches/index.ts +++ b/src/renderer/patches/index.ts @@ -10,3 +10,4 @@ import "./platformClass"; import "./screenShareAudio"; import "./spellCheck"; import "./windowsTitleBar"; +import "./keybinds"; diff --git a/src/renderer/patches/keybinds.ts b/src/renderer/patches/keybinds.ts new file mode 100644 index 0000000..209b579 --- /dev/null +++ b/src/renderer/patches/keybinds.ts @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * Vesktop, a desktop app aiming to give you a snappier Discord Experience + * Copyright (c) 2023 Vendicated and Vencord contributors + */ + +import { keybindCallbacks } from "renderer"; + +import { addPatch } from "./shared"; + +addPatch({ + patches: [ + { + find: ".default.Messages.KEYBINDS,children:", + replacement: { + match: /.\.isPlatformEmbedded/, + replace: "true" + } + }, + { + find: "[kb store] KeybindStore", + replacement: { + match: /(inputEventRegister\(parseInt\((.{1,2})\),(.{1,2}),(.{1,2}),(.{1,2})\);else\{)([^;]*;[^;]*;.{1,2}\.keyup&&.{1,2}\.bindGlobal\(\(0,(.{1,2}\.toString)\))/, + replace: "$1$self.registerKeybind($2,$3,$4,$7);return;$6" + } + }, + { + find: "[kb store] KeybindStore", + replacement: { + // WHY IS THE RADIX SPEICIFIED + match: /(inputEventUnregister\(parseInt\((.{1,2}),10\)\);else\{)/, + replace: "$1$self.unregisterKeybind($2);return;" + } + } + ], + + registerKeybind: function (id, shortcut, callback, toString) { + keybindCallbacks[id] = callback; + VesktopNative.keybind.register(id, toString(shortcut)); + }, + unregisterKeybind: function (id) { + delete keybindCallbacks[id]; + VesktopNative.keybind.uregister(id); + } +}); diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index df64403..05cbcc8 100644 --- a/src/shared/IpcEvents.ts +++ b/src/shared/IpcEvents.ts @@ -49,5 +49,7 @@ export const enum IpcEvents { ARRPC_ACTIVITY = "VCD_ARRPC_ACTIVITY", - CLIPBOARD_COPY_IMAGE = "VCD_CLIPBOARD_COPY_IMAGE" + CLIPBOARD_COPY_IMAGE = "VCD_CLIPBOARD_COPY_IMAGE", + KEYBIND_REGISTER = "VCD_KEYBIND_REGISTER", + KEYBIND_UNREGISTER = "VCD_KEYBIND_UNREGISTER" }