From 29c12dc034fd01e2c3a5b3cbaa1166da637cdad0 Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Sat, 18 May 2024 00:41:36 +0300 Subject: [PATCH 1/9] Added ability to toggle voice using proc signals --- src/main/keybinds.ts | 19 +++++++++++++++++++ src/main/mainWindow.ts | 2 ++ src/preload/VesktopNative.ts | 8 ++++++++ src/renderer/index.ts | 8 ++++++++ src/shared/IpcEvents.ts | 4 +++- 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 src/main/keybinds.ts diff --git a/src/main/keybinds.ts b/src/main/keybinds.ts new file mode 100644 index 0000000..1a8b578 --- /dev/null +++ b/src/main/keybinds.ts @@ -0,0 +1,19 @@ +/* + * 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 { IpcEvents } from "shared/IpcEvents"; + +import { mainWin } from "./mainWindow"; + +export function initKeybinds() { + process.on("SIGPIPE", async () => { + mainWin.webContents.send(IpcEvents.TOGGLE_SELF_MUTE); + }); + + process.on("SIGUSR2", () => { + mainWin.webContents.send(IpcEvents.TOGGLE_SELF_DEAF); + }); +} diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 3ee1fd0..020b4f1 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -35,6 +35,7 @@ import { MIN_WIDTH, VENCORD_FILES_DIR } from "./constants"; +import { initKeybinds } from "./keybinds"; import { Settings, State, VencordSettings } from "./settings"; import { createSplashWindow } from "./splash"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; @@ -481,4 +482,5 @@ export async function createWindows() { }); initArRPC(); + initKeybinds(); } diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts index 184b095..119c193 100644 --- a/src/preload/VesktopNative.ts +++ b/src/preload/VesktopNative.ts @@ -78,5 +78,13 @@ export const VesktopNative = { clipboard: { copyImage: (imageBuffer: Uint8Array, imageSrc: string) => invoke(IpcEvents.CLIPBOARD_COPY_IMAGE, imageBuffer, imageSrc) + }, + voice: { + onToggleSelfMute: (listener: (...args: any[]) => void) => { + ipcRenderer.on(IpcEvents.TOGGLE_SELF_MUTE, listener); + }, + onToggleSelfDeaf: (listener: (...args: any[]) => void) => { + ipcRenderer.on(IpcEvents.TOGGLE_SELF_DEAF, listener); + } } }; diff --git a/src/renderer/index.ts b/src/renderer/index.ts index 1ccc2e4..485edd1 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -57,3 +57,11 @@ VesktopNative.arrpc.onActivity(data => { arRPC.handleEvent(new MessageEvent("message", { data })); }); + +VesktopNative.voice.onToggleSelfMute(() => { + findByPropsLazy("toggleSelfMute").toggleSelfMute(); +}); + +VesktopNative.voice.onToggleSelfDeaf(() => { + findByPropsLazy("toggleSelfDeaf").toggleSelfDeaf(); +}); diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts index df64403..5a53602 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", + TOGGLE_SELF_MUTE = "VCD_TOGGLE_SELF_MUTE", + TOGGLE_SELF_DEAF = "VCD_TOGGLE_SELF_DEAF" } From 67ae98fb185f73980f5f5016da4017abe3af61f6 Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Sat, 18 May 2024 01:08:56 +0300 Subject: [PATCH 2/9] added process title --- src/main/keybinds.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/keybinds.ts b/src/main/keybinds.ts index 1a8b578..242f098 100644 --- a/src/main/keybinds.ts +++ b/src/main/keybinds.ts @@ -9,6 +9,7 @@ import { IpcEvents } from "shared/IpcEvents"; import { mainWin } from "./mainWindow"; export function initKeybinds() { + process.title = "Vesktop"; process.on("SIGPIPE", async () => { mainWin.webContents.send(IpcEvents.TOGGLE_SELF_MUTE); }); From a3eea96bb1fe4388c70ee4d4fd1f323ae4d0b876 Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Fri, 24 May 2024 16:57:19 +0300 Subject: [PATCH 3/9] Refactored to use fifo pipe --- src/main/keybinds.ts | 35 ++++++++++++++++++++++++++++------- src/main/mainWindow.ts | 1 + src/renderer/index.ts | 6 ++++-- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/main/keybinds.ts b/src/main/keybinds.ts index 242f098..5289cae 100644 --- a/src/main/keybinds.ts +++ b/src/main/keybinds.ts @@ -4,17 +4,38 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ +import child_process from "node:child_process"; +import fs from "node:fs"; +import path from "node:path"; + +import net from "net"; import { IpcEvents } from "shared/IpcEvents"; import { mainWin } from "./mainWindow"; -export function initKeybinds() { - process.title = "Vesktop"; - process.on("SIGPIPE", async () => { - mainWin.webContents.send(IpcEvents.TOGGLE_SELF_MUTE); - }); +const xdgRuntimeDir = process.env.XDG_RUNTIME_DIR || process.env.TMP || "/tmp"; +const socketFile = path.join(xdgRuntimeDir, "vesktop-ipc"); - process.on("SIGUSR2", () => { - mainWin.webContents.send(IpcEvents.TOGGLE_SELF_DEAF); +export function initKeybinds() { + child_process.spawnSync("mkfifo", [socketFile]); + fs.open(socketFile, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK, (err, fd) => { + if (err) { + console.error("Error opening pipe:", err); + return; + } + + const pipe = new net.Socket({ fd }); + pipe.on("data", data => { + const Actions = new Set([IpcEvents.TOGGLE_SELF_DEAF, IpcEvents.TOGGLE_SELF_MUTE]); + const action = data.toString().trim(); + if (Actions.has(action as IpcEvents)) { + mainWin.webContents.send(action); + } + }); + + pipe.on("end", () => { + pipe.destroy(); + initKeybinds(); + }); }); } diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 65c3677..cdde947 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -468,6 +468,7 @@ const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDeskto export async function createWindows() { const startMinimized = process.argv.includes("--start-minimized"); const splash = createSplashWindow(startMinimized); + process.title = "Vesktop"; // SteamOS letterboxes and scales it terribly, so just full screen it if (isDeckGameMode) splash.setFullScreen(true); await ensureVencordFiles(); diff --git a/src/renderer/index.ts b/src/renderer/index.ts index 03f7397..a0b3c1f 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -60,10 +60,12 @@ VesktopNative.arrpc.onActivity(async data => { arRPC.handleEvent(new MessageEvent("message", { data })); }); +const VoiceActions = findByPropsLazy("toggleSelfMute"); + VesktopNative.voice.onToggleSelfMute(() => { - findByPropsLazy("toggleSelfMute").toggleSelfMute(); + VoiceActions.toggleSelfMute(); }); VesktopNative.voice.onToggleSelfDeaf(() => { - findByPropsLazy("toggleSelfDeaf").toggleSelfDeaf(); + VoiceActions.toggleSelfDeaf(); }); From dd6bd7442717e83f785d23d3613a4d047d05c6df Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Fri, 24 May 2024 17:13:05 +0300 Subject: [PATCH 4/9] use keybinds only on wayland --- src/main/mainWindow.ts | 3 ++- src/main/screenShare.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index cdde947..4ddb85c 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -37,6 +37,7 @@ import { VENCORD_FILES_DIR } from "./constants"; import { initKeybinds } from "./keybinds"; +import { isWayland } from "./screenShare"; import { Settings, State, VencordSettings } from "./settings"; import { createSplashWindow } from "./splash"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; @@ -499,5 +500,5 @@ export async function createWindows() { }); initArRPC(); - initKeybinds(); + if (isWayland) initKeybinds(); } diff --git a/src/main/screenShare.ts b/src/main/screenShare.ts index b63497b..004edc5 100644 --- a/src/main/screenShare.ts +++ b/src/main/screenShare.ts @@ -10,7 +10,7 @@ import { IpcEvents } from "shared/IpcEvents"; import { handle } from "./utils/ipcWrappers"; -const isWayland = +export const isWayland = process.platform === "linux" && (process.env.XDG_SESSION_TYPE === "wayland" || !!process.env.WAYLAND_DISPLAY); export function registerScreenShareHandler() { From d37f07cedb170aa754004a71dc890a04becda3ea Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Sun, 2 Jun 2024 00:23:07 +0300 Subject: [PATCH 5/9] moved isWayland to constants --- src/main/constants.ts | 3 +++ src/main/mainWindow.ts | 2 +- src/main/screenShare.ts | 4 +--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/constants.ts b/src/main/constants.ts index 1a02d5e..6e2cb2f 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -61,3 +61,6 @@ export const enum MessageBoxChoice { Default, Cancel } + +export const isWayland = + process.platform === "linux" && (process.env.XDG_SESSION_TYPE === "wayland" || !!process.env.WAYLAND_DISPLAY); diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 4ddb85c..583484c 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -31,13 +31,13 @@ import { DATA_DIR, DEFAULT_HEIGHT, DEFAULT_WIDTH, + isWayland, MessageBoxChoice, MIN_HEIGHT, MIN_WIDTH, VENCORD_FILES_DIR } from "./constants"; import { initKeybinds } from "./keybinds"; -import { isWayland } from "./screenShare"; import { Settings, State, VencordSettings } from "./settings"; import { createSplashWindow } from "./splash"; import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally"; diff --git a/src/main/screenShare.ts b/src/main/screenShare.ts index 004edc5..34d8e4a 100644 --- a/src/main/screenShare.ts +++ b/src/main/screenShare.ts @@ -8,11 +8,9 @@ import { desktopCapturer, session, Streams } from "electron"; import type { StreamPick } from "renderer/components/ScreenSharePicker"; import { IpcEvents } from "shared/IpcEvents"; +import { isWayland } from "./constants"; import { handle } from "./utils/ipcWrappers"; -export const isWayland = - process.platform === "linux" && (process.env.XDG_SESSION_TYPE === "wayland" || !!process.env.WAYLAND_DISPLAY); - export function registerScreenShareHandler() { handle(IpcEvents.CAPTURER_GET_LARGE_THUMBNAIL, async (_, id: string) => { const sources = await desktopCapturer.getSources({ From cdbc00b3e51691c11c2c1c34bb41e819dbe198fd Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Sun, 2 Jun 2024 00:26:51 +0300 Subject: [PATCH 6/9] removed proc title and prettified voice actions calls --- src/main/mainWindow.ts | 1 - src/renderer/index.ts | 8 ++------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts index 583484c..2626709 100644 --- a/src/main/mainWindow.ts +++ b/src/main/mainWindow.ts @@ -469,7 +469,6 @@ const runVencordMain = once(() => require(join(VENCORD_FILES_DIR, "vencordDeskto export async function createWindows() { const startMinimized = process.argv.includes("--start-minimized"); const splash = createSplashWindow(startMinimized); - process.title = "Vesktop"; // SteamOS letterboxes and scales it terribly, so just full screen it if (isDeckGameMode) splash.setFullScreen(true); await ensureVencordFiles(); diff --git a/src/renderer/index.ts b/src/renderer/index.ts index a0b3c1f..10cd7d6 100644 --- a/src/renderer/index.ts +++ b/src/renderer/index.ts @@ -62,10 +62,6 @@ VesktopNative.arrpc.onActivity(async data => { const VoiceActions = findByPropsLazy("toggleSelfMute"); -VesktopNative.voice.onToggleSelfMute(() => { - VoiceActions.toggleSelfMute(); -}); +VesktopNative.voice.onToggleSelfMute(() => VoiceActions.toggleSelfMute()); -VesktopNative.voice.onToggleSelfDeaf(() => { - VoiceActions.toggleSelfDeaf(); -}); +VesktopNative.voice.onToggleSelfDeaf(() => VoiceActions.toggleSelfDeaf()); From 0157b85ae161e01caeb2d3b11842640ef051a144 Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Sun, 2 Jun 2024 00:29:15 +0300 Subject: [PATCH 7/9] fixed imports --- src/main/keybinds.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/keybinds.ts b/src/main/keybinds.ts index 5289cae..d722bdf 100644 --- a/src/main/keybinds.ts +++ b/src/main/keybinds.ts @@ -4,27 +4,27 @@ * Copyright (c) 2023 Vendicated and Vencord contributors */ -import child_process from "node:child_process"; -import fs from "node:fs"; -import path from "node:path"; +import { spawnSync } from "node:child_process"; +import { constants, open } from "node:fs"; +import { join } from "node:path"; -import net from "net"; +import { Socket } from "net"; import { IpcEvents } from "shared/IpcEvents"; import { mainWin } from "./mainWindow"; const xdgRuntimeDir = process.env.XDG_RUNTIME_DIR || process.env.TMP || "/tmp"; -const socketFile = path.join(xdgRuntimeDir, "vesktop-ipc"); +const socketFile = join(xdgRuntimeDir, "vesktop-ipc"); export function initKeybinds() { - child_process.spawnSync("mkfifo", [socketFile]); - fs.open(socketFile, fs.constants.O_RDONLY | fs.constants.O_NONBLOCK, (err, fd) => { + spawnSync("mkfifo", [socketFile]); + open(socketFile, constants.O_RDONLY | constants.O_NONBLOCK, (err, fd) => { if (err) { console.error("Error opening pipe:", err); return; } - const pipe = new net.Socket({ fd }); + const pipe = new Socket({ fd }); pipe.on("data", data => { const Actions = new Set([IpcEvents.TOGGLE_SELF_DEAF, IpcEvents.TOGGLE_SELF_MUTE]); const action = data.toString().trim(); @@ -33,7 +33,7 @@ export function initKeybinds() { } }); - pipe.on("end", () => { + pipe.once("end", () => { pipe.destroy(); initKeybinds(); }); From 08a9b60803eb607c8e9b7b019adc9a617f02f055 Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Sun, 2 Jun 2024 00:42:21 +0300 Subject: [PATCH 8/9] add logging, move actions to top level --- src/main/keybinds.ts | 45 +++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/src/main/keybinds.ts b/src/main/keybinds.ts index d722bdf..3a15765 100644 --- a/src/main/keybinds.ts +++ b/src/main/keybinds.ts @@ -16,26 +16,37 @@ import { mainWin } from "./mainWindow"; const xdgRuntimeDir = process.env.XDG_RUNTIME_DIR || process.env.TMP || "/tmp"; const socketFile = join(xdgRuntimeDir, "vesktop-ipc"); +const Actions = new Set([IpcEvents.TOGGLE_SELF_DEAF, IpcEvents.TOGGLE_SELF_MUTE]); + export function initKeybinds() { - spawnSync("mkfifo", [socketFile]); - open(socketFile, constants.O_RDONLY | constants.O_NONBLOCK, (err, fd) => { - if (err) { - console.error("Error opening pipe:", err); - return; - } + try { + spawnSync("mkfifo", [socketFile]); + } catch (err) { + console.log("Failed to create mkfifo while initializing keybinds:", err); + return; + } - const pipe = new Socket({ fd }); - pipe.on("data", data => { - const Actions = new Set([IpcEvents.TOGGLE_SELF_DEAF, IpcEvents.TOGGLE_SELF_MUTE]); - const action = data.toString().trim(); - if (Actions.has(action as IpcEvents)) { - mainWin.webContents.send(action); + try { + open(socketFile, constants.O_RDONLY | constants.O_NONBLOCK, (err, fd) => { + if (err) { + console.error("Error opening pipe while initializing keybinds:", err); + return; } - }); - pipe.once("end", () => { - pipe.destroy(); - initKeybinds(); + const pipe = new Socket({ fd }); + pipe.on("data", data => { + const action = data.toString().trim(); + if (Actions.has(action as IpcEvents)) { + mainWin.webContents.send(action); + } + }); + + pipe.once("end", () => { + pipe.destroy(); + initKeybinds(); + }); }); - }); + } catch (err) { + console.log("Can't open socket file.", err); + } } From a55e79c38ede93f82a7abf1c6bf180f3468ab787 Mon Sep 17 00:00:00 2001 From: Oleh Polisan Date: Sun, 16 Jun 2024 20:24:04 +0300 Subject: [PATCH 9/9] fifo: refactor creating/removing logic --- src/main/keybinds.ts | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/src/main/keybinds.ts b/src/main/keybinds.ts index 3a15765..f773762 100644 --- a/src/main/keybinds.ts +++ b/src/main/keybinds.ts @@ -5,7 +5,7 @@ */ import { spawnSync } from "node:child_process"; -import { constants, open } from "node:fs"; +import { constants, existsSync, open, unlinkSync } from "node:fs"; import { join } from "node:path"; import { Socket } from "net"; @@ -18,14 +18,26 @@ const socketFile = join(xdgRuntimeDir, "vesktop-ipc"); const Actions = new Set([IpcEvents.TOGGLE_SELF_DEAF, IpcEvents.TOGGLE_SELF_MUTE]); -export function initKeybinds() { +function createFIFO() { + if (existsSync(socketFile)) { + try { + unlinkSync(socketFile); + } catch (err) { + console.error("Failed to remove existing mkfifo file:", err); + return false; + } + } + try { spawnSync("mkfifo", [socketFile]); } catch (err) { - console.log("Failed to create mkfifo while initializing keybinds:", err); - return; + console.error("Failed to create mkfifo while initializing keybinds:", err); + return false; } + return true; +} +function openFIFO() { try { open(socketFile, constants.O_RDONLY | constants.O_NONBLOCK, (err, fd) => { if (err) { @@ -41,12 +53,28 @@ export function initKeybinds() { } }); - pipe.once("end", () => { + pipe.on("end", () => { pipe.destroy(); - initKeybinds(); + openFIFO(); }); }); } catch (err) { - console.log("Can't open socket file.", err); + console.error("Can't open socket file.", err); + } +} + +function cleanup() { + try { + unlinkSync(socketFile); + } catch (err) { + console.error("Failed to remove mkfifo file:", err); + } +} + +process.on("exit", cleanup); + +export function initKeybinds() { + if (createFIFO()) { + openFIFO(); } }