From 1065f2363658bdfb8f55043b5c603268a99736ba Mon Sep 17 00:00:00 2001 From: Jacob Schlecht Date: Mon, 13 Apr 2026 23:37:43 -0600 Subject: [PATCH] feat: Enable screen share request handler and add screen picker calls This commit was made without the use of generative AI. Signed-off-by: Jacob Schlecht --- src/native/window.ts | 39 +++++++++++++++++++++++++++++++++++++++ src/world/window.ts | 12 ++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/native/window.ts b/src/native/window.ts index b73698a..d5d2182 100644 --- a/src/native/window.ts +++ b/src/native/window.ts @@ -5,8 +5,10 @@ import { Menu, MenuItem, app, + desktopCapturer, ipcMain, nativeImage, + session, } from "electron"; import windowIconAsset from "../../assets/desktop/icon.png?asset"; @@ -187,6 +189,43 @@ export function createMainWindow() { } }); + // Create display media request handler + session.defaultSession.setDisplayMediaRequestHandler( + (request, callback) => { + desktopCapturer + .getSources({ types: ["screen", "window"] }) + .then((sources) => { + // Shortcut for linux wayland. + if (sources.length == 1) { + // TODO: Get audio to work with wayland + // See vencord for an implementation using a virtual microphone. + callback({ + video: sources[0], + audio: request.audioRequested ? "loopback" : undefined, + }); + return; + } + mainWindow.webContents.send( + "screenPicker", + sources.map((source, idx) => { + return { idx: idx, name: source.name }; + }), + (idx: number, audio: boolean) => { + if (idx < 0 || idx > sources.length) { + callback({}); + } else { + callback({ + video: sources[idx], + audio: audio ? "loopback" : undefined, + }); + } + }, + ); + }); + }, + { useSystemPicker: true }, + ); + // push world events to the window ipcMain.on("minimise", () => mainWindow.minimize()); ipcMain.on("maximise", () => diff --git a/src/world/window.ts b/src/world/window.ts index 2e9957b..187ffd7 100644 --- a/src/world/window.ts +++ b/src/world/window.ts @@ -15,4 +15,16 @@ contextBridge.exposeInMainWorld("native", { close: () => ipcRenderer.send("close"), setBadgeCount: (count: number) => ipcRenderer.send("setBadgeCount", count), + + // Wrapped in braces to return void + onceScreenPicker: ( + onScreenPick: ( + sources: { idx: number; name: string }[], + callback: (idx: number, audio: boolean) => void, + ) => void, + ) => { + ipcRenderer.once("screenPicker", (_, sources, callback) => + onScreenPick(sources, callback), + ); + }, });