From e7a753113f0edf6ba87b771b8b38f8b483992d9c Mon Sep 17 00:00:00 2001 From: Tuxinal <24763016+tuxinal@users.noreply.github.com> Date: Fri, 7 Feb 2025 12:43:05 +0330 Subject: [PATCH] Add keyup keydown support update venbind --- package.json | 2 +- src/main/index.ts | 4 +-- src/main/venbind.ts | 6 ++-- src/preload/VesktopNative.ts | 3 +- src/renderer/index.ts | 19 +++++++++++- src/renderer/patches/keybinds.tsx | 49 +++++++++++++++++++++++-------- 6 files changed, 62 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index d9b20ff..b24b3e6 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "dependencies": { "arrpc": "github:OpenAsar/arrpc#5aadc307cb9bf4479f0a12364a253b07a77ace22", "electron-updater": "^6.3.9", - "venbind": "^0.0.2" + "venbind": "^0.0.3" }, "optionalDependencies": { "@vencord/venmic": "^6.1.0" diff --git a/src/main/index.ts b/src/main/index.ts index e8af42b..1003a64 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -76,10 +76,10 @@ function init() { if (keybindIndex !== -1) { if (cmdLine[keybindIndex + 2] === "keyup" || cmdLine[keybindIndex + 2] === "keydown") { mainWin.webContents.executeJavaScript( - `Vesktop.keybindCallbacks[${cmdLine[keybindIndex + 1]}](${cmdLine[keybindIndex + 2] === "keydown" ? "true" : "false"})` + `Vesktop.triggerKeybind(${cmdLine[keybindIndex + 1]}, ${cmdLine[keybindIndex + 2] === "keydown" ? "false" : "true"})` ); } else { - mainWin.webContents.executeJavaScript(`Vesktop.keybindCallbacks[${cmdLine[keybindIndex + 1]}](false)`); + mainWin.webContents.executeJavaScript(`Vesktop.triggerKeybind(${cmdLine[keybindIndex + 1]}, true)`); } } else if (data.IS_DEV) app.quit(); else if (mainWin) { diff --git a/src/main/venbind.ts b/src/main/venbind.ts index 0af7263..9a45627 100644 --- a/src/main/venbind.ts +++ b/src/main/venbind.ts @@ -50,12 +50,12 @@ export function obtainVenbind() { export function startVenbind() { const venbind = obtainVenbind(); - venbind?.startKeybinds(x => { - mainWin.webContents.executeJavaScript(`Vesktop.keybindCallbacks[${x}](false)`); + venbind?.startKeybinds((id, keyup) => { + mainWin.webContents.executeJavaScript(`Vesktop.triggerKeybind(${id}, ${keyup})`); }); } -handle(IpcEvents.KEYBIND_REGISTER, (_, id: number, shortcut: string, options: any) => { +handle(IpcEvents.KEYBIND_REGISTER, (_, id: number, shortcut: string) => { obtainVenbind()?.registerKeybind(shortcut, id); }); handle(IpcEvents.KEYBIND_UNREGISTER, (_, id: number) => { diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 1e49b9a..bc51261 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -80,8 +80,7 @@ export const VesktopNative = { invoke(IpcEvents.CLIPBOARD_COPY_IMAGE, imageBuffer, imageSrc) }, keybind: { - register: (id: number, shortcut: string, options: any) => - invoke(IpcEvents.KEYBIND_REGISTER, id, shortcut), + register: (id: number, shortcut: string) => invoke(IpcEvents.KEYBIND_REGISTER, id, shortcut), unregister: (id: number) => invoke(IpcEvents.KEYBIND_UNREGISTER, id), shouldPreRegister: () => sendSync(IpcEvents.KEYBIND_SHOULD_PREREGISTER), preRegister: (actions: { id: number; name: string }[]) => invoke(IpcEvents.KEYBIND_PREREGISTER, actions) diff --git a/src/renderer/index.ts b/src/renderer/index.ts index 01c80ce..d719688 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -21,7 +21,15 @@ export { Settings }; const InviteActions = findByPropsLazy("resolveInvite"); -export const keybindCallbacks: { [id: number]: Function } = {}; +export const keybindCallbacks: { + [id: number]: { + onTrigger: Function; + keyEvents: { + keyup: boolean; + keydown: boolean; + }; + }; +} = {}; export async function openInviteModal(code: string) { const { invite } = await InviteActions.resolveInvite(code, "Desktop Modal"); @@ -39,6 +47,15 @@ export async function openInviteModal(code: string) { return true; } +export async function triggerKeybind(id: number, keyup: boolean) { + var cb = keybindCallbacks[id]; + if (cb.keyEvents.keyup && keyup) { + cb.onTrigger(false); + } else if (cb.keyEvents.keydown && !keyup) { + cb.onTrigger(true); + } +} + const customSettingsSections = ( Vencord.Plugins.plugins.Settings as any as { customSections: ((ID: Record) => any)[] } ).customSections; diff --git a/src/renderer/patches/keybinds.tsx b/src/renderer/patches/keybinds.tsx index 8100cb5..a1bd3c5 100644 --- a/src/renderer/patches/keybinds.tsx +++ b/src/renderer/patches/keybinds.tsx @@ -22,6 +22,7 @@ const actionReadableNames: { [key: string]: string } = { NAVIGATE_FORWARD: "Navigate Forward", DISCONNECT_FROM_VOICE_CHANNEL: "Disconnect From Voice Channel" }; +const actions: { id: number; name: string }[] = []; addPatch({ patches: [ { @@ -72,12 +73,23 @@ addPatch({ } ], - registerKeybind: function (id, shortcut, callback, options) { + registerKeybind: function ( + id, + shortcut, + callback: Function, + options: { + keyup: boolean; + keydown: boolean; + } + ) { if (VesktopNative.keybind.shouldPreRegister()) { return; } - keybindCallbacks[id] = callback; - VesktopNative.keybind.register(id, toShortcutString(shortcut), options); + keybindCallbacks[id] = { + onTrigger: callback, + keyEvents: options + }; + VesktopNative.keybind.register(id, toShortcutString(shortcut)); }, unregisterKeybind: function (id) { if (VesktopNative.keybind.shouldPreRegister()) { @@ -90,9 +102,12 @@ addPatch({ preRegisterKeybinds: function (allActions: { [action: string]: { onTrigger: Function; + keyEvents: { + keyup: boolean; + keydown: boolean; + }; }; }) { - const actions: { id: number; name: string }[] = []; if (!VesktopNative.keybind.shouldPreRegister()) { return; } @@ -102,6 +117,7 @@ addPatch({ [ "UNASSIGNED", "SWITCH_TO_VOICE_CHANNEL", + "PUSH_TO_TALK", "TOGGLE_OVERLAY", "TOGGLE_OVERLAY_INPUT_LOCK", "TOGGLE_PRIORITY_SPEAKER", @@ -115,20 +131,21 @@ addPatch({ ) { return; } - // the second argument in onTrigger seems to hold some context in some specific actions - // as far as i can tell these are the only actions that use it: push to talk (except it doesn't seem to do anything there??) - // and switch to voice channel which requires a channel parameter which is provided through discord's ui - // except we can't really provide that with xdp so i'll just skip it for now - keybindCallbacks[id] = (keyState: boolean) => val.onTrigger(keyState, undefined); + keybindCallbacks[id] = { + // TODO: the "undefined" here is supposed to be a context. basically only used by push to talk to determine if you are in ptt mode or not + // (it's also used by switch to channel to determine the channel but you can't really define that through xdp) + onTrigger: (keyState: boolean) => val.onTrigger(keyState, undefined), + keyEvents: val.keyEvents + }; actions.push({ id, name: actionReadableNames[key] || key }); id++; }); - VesktopNative.keybind.preRegister(actions); }, xdpWarning: function (keybinds) { if (!VesktopNative.keybind.shouldPreRegister()) { return keybinds; } + VesktopNative.keybind.preRegister(actions); return (

@@ -136,9 +153,17 @@ addPatch({ You can configure keybinds using your desktop environment's built-in settings page.

- If your desktop environment does not support the GlobalShortcuts portal you have to manually bind - your desired keybinds to CLI triggers. + If your desktop environment does not support the GlobalShortcuts portal (which you would know if its + settings page didn't open just now) you have to manually bind your desired keybinds to CLI triggers.

+

List of valid keybind IDs to use with the CLI:

+
    + {actions.map(keybind => ( +
  • + {keybind.id}: {keybind.name} +
  • + ))} +
); }