diff --git a/src/main/cli.ts b/src/main/cli.ts index 83f77cb..fc0db35 100644 --- a/src/main/cli.ts +++ b/src/main/cli.ts @@ -6,6 +6,7 @@ import { app } from "electron"; import { basename } from "path"; +import { ShortcutAction } from "renderer/globalShortcuts/ShortcutSettings"; import { stripIndent } from "shared/utils/text"; import { parseArgs, ParseArgsOptionDescriptor } from "util"; @@ -42,6 +43,19 @@ const options = { type: "string", description: "Set User-Agent to a specific operating system. May trigger anti-spam or break voice chat", options: ["windows", "linux", "darwin"] + }, + "run-shortcut": { + type: "string", + description: + "Run a predefined shortcut action (for custom key binds). Vesktop has to be open for this to have any effect", + options: [ + "toggleMute", + "toggleDeafen", + "toggleStreamerMode", + "toggleCamera", + "toggleScreenShare", + "disconnectFromVoiceChannel" + ] satisfies Array } } satisfies Record; @@ -135,7 +149,7 @@ export function checkCommandLineForHelpOrVersion() { app.exit(1); } - if ("options" in def && !def.options?.includes(value as string)) { + if ("options" in def && !def.options?.includes(value as any)) { console.error(`Invalid value for --${name}: ${value}\nExpected one of: ${def.options.join(", ")}`); app.exit(1); } diff --git a/src/main/index.ts b/src/main/index.ts index 28a08e8..cae0fcc 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -11,9 +11,13 @@ import "./userAssets"; import "./vesktopProtocol"; import { app, BrowserWindow, nativeTheme } from "electron"; +import { IpcCommands } from "shared/IpcEvents"; +// eslint-disable-next-line no-duplicate-imports +import { CommandLine } from "./cli"; import { DATA_DIR } from "./constants"; import { createFirstLaunchTour } from "./firstLaunch"; +import { sendRendererCommand } from "./ipcCommands"; import { registerKeyBinds } from "./keyBinds"; import { createWindows, mainWin } from "./mainWindow"; import { registerMediaPermissionsHandler } from "./mediaPermissions"; @@ -129,7 +133,7 @@ function init() { }); } -if (!app.requestSingleInstanceLock({ IS_DEV })) { +if (!app.requestSingleInstanceLock({ IS_DEV, args: CommandLine })) { if (IS_DEV) { console.log("Vesktop is already running. Quitting previous instance..."); init(); @@ -158,3 +162,10 @@ app.on("open-url", (_, url) => { app.on("window-all-closed", () => { if (process.platform !== "darwin") app.quit(); }); + +app.on("second-instance", (_e, _argv, _cwd, data) => { + const { args } = data as { args: typeof CommandLine; IS_DEV: boolean }; + const { "run-shortcut": shortcut } = args.values; + + if (shortcut) sendRendererCommand(IpcCommands.HANDLE_KEY_BIND, shortcut); +}); diff --git a/src/main/keyBinds.ts b/src/main/keyBinds.ts index 77cd174..0624030 100644 --- a/src/main/keyBinds.ts +++ b/src/main/keyBinds.ts @@ -11,6 +11,8 @@ import { sendRendererCommand } from "./ipcCommands"; import { Settings } from "./settings"; function unregisterKeyBinds() { + if (!app.isReady()) return; + globalShortcut.unregisterAll(); } diff --git a/src/renderer/globalShortcuts/keybindHandler.ts b/src/renderer/globalShortcuts/keybindHandler.ts index c6cbe4b..a7ad191 100644 --- a/src/renderer/globalShortcuts/keybindHandler.ts +++ b/src/renderer/globalShortcuts/keybindHandler.ts @@ -5,29 +5,51 @@ */ import { Logger } from "@vencord/types/utils"; +import { findByPropsLazy } from "@vencord/types/webpack"; +import { FluxDispatcher, StreamerModeStore } from "@vencord/types/webpack/common"; import { ShortcutAction } from "./ShortcutSettings"; const logger = new Logger("VesktopKeyBindHandler"); +const { selectVoiceChannel } = findByPropsLazy("selectVoiceChannel"); + export function handleKeyBind(keyBind: ShortcutAction) { logger.debug(`Handling key bind action: ${keyBind}`); switch (keyBind) { case "toggleMute": + FluxDispatcher.dispatch({ + type: "AUDIO_TOGGLE_SELF_MUTE", + context: "default", + syncRemote: true, + playSoundEffect: true + }); break; + case "toggleDeafen": + FluxDispatcher.dispatch({ + type: "AUDIO_TOGGLE_SELF_DEAF", + context: "default", + syncRemote: true + }); break; + case "toggleStreamerMode": + FluxDispatcher.dispatch({ + type: "STREAMER_MODE_UPDATE", + key: "enabled", + value: !StreamerModeStore.enabled + }); break; - case "toggleCamera": - break; - case "toggleScreenShare": - break; + case "disconnectFromVoiceChannel": + selectVoiceChannel(null); break; + case "unassigned": break; + default: logger.warn(`Unknown key bind action: ${keyBind}`); }