Screensharing rework

Split Linux screensharing audio tracks, Rework screensharing functionality and layout
This will need some refactoring soon
This commit is contained in:
2026-03-08 06:33:27 +01:00
parent d20509566d
commit 7a4c4ede8c
42 changed files with 4998 additions and 475 deletions

View File

@@ -1,6 +1,37 @@
import { contextBridge, ipcRenderer } from 'electron';
import { Command, Query } from './cqrs/types';
const LINUX_SCREEN_SHARE_MONITOR_AUDIO_CHUNK_CHANNEL = 'linux-screen-share-monitor-audio-chunk';
const LINUX_SCREEN_SHARE_MONITOR_AUDIO_ENDED_CHANNEL = 'linux-screen-share-monitor-audio-ended';
export interface LinuxScreenShareAudioRoutingInfo {
available: boolean;
active: boolean;
monitorCaptureSupported: boolean;
screenShareSinkName: string;
screenShareMonitorSourceName: string;
voiceSinkName: string;
reason?: string;
}
export interface LinuxScreenShareMonitorCaptureInfo {
bitsPerSample: number;
captureId: string;
channelCount: number;
sampleRate: number;
sourceName: string;
}
export interface LinuxScreenShareMonitorAudioChunkPayload {
captureId: string;
chunk: Uint8Array;
}
export interface LinuxScreenShareMonitorAudioEndedPayload {
captureId: string;
reason?: string;
}
export interface ElectronAPI {
minimizeWindow: () => void;
maximizeWindow: () => void;
@@ -8,7 +39,25 @@ export interface ElectronAPI {
openExternal: (url: string) => Promise<boolean>;
getSources: () => Promise<{ id: string; name: string; thumbnail: string }[]>;
prepareLinuxScreenShareAudioRouting: () => Promise<LinuxScreenShareAudioRoutingInfo>;
activateLinuxScreenShareAudioRouting: () => Promise<LinuxScreenShareAudioRoutingInfo>;
deactivateLinuxScreenShareAudioRouting: () => Promise<boolean>;
startLinuxScreenShareMonitorCapture: () => Promise<LinuxScreenShareMonitorCaptureInfo>;
stopLinuxScreenShareMonitorCapture: (captureId?: string) => Promise<boolean>;
onLinuxScreenShareMonitorAudioChunk: (listener: (payload: LinuxScreenShareMonitorAudioChunkPayload) => void) => () => void;
onLinuxScreenShareMonitorAudioEnded: (listener: (payload: LinuxScreenShareMonitorAudioEndedPayload) => void) => () => void;
getAppDataPath: () => Promise<string>;
getDesktopSettings: () => Promise<{
hardwareAcceleration: boolean;
runtimeHardwareAcceleration: boolean;
restartRequired: boolean;
}>;
setDesktopSettings: (patch: { hardwareAcceleration?: boolean }) => Promise<{
hardwareAcceleration: boolean;
runtimeHardwareAcceleration: boolean;
restartRequired: boolean;
}>;
relaunchApp: () => Promise<boolean>;
readFile: (filePath: string) => Promise<string>;
writeFile: (filePath: string, data: string) => Promise<boolean>;
saveFileAs: (defaultFileName: string, data: string) => Promise<{ saved: boolean; cancelled: boolean }>;
@@ -26,7 +75,44 @@ const electronAPI: ElectronAPI = {
openExternal: (url) => ipcRenderer.invoke('open-external', url),
getSources: () => ipcRenderer.invoke('get-sources'),
prepareLinuxScreenShareAudioRouting: () => ipcRenderer.invoke('prepare-linux-screen-share-audio-routing'),
activateLinuxScreenShareAudioRouting: () => ipcRenderer.invoke('activate-linux-screen-share-audio-routing'),
deactivateLinuxScreenShareAudioRouting: () => ipcRenderer.invoke('deactivate-linux-screen-share-audio-routing'),
startLinuxScreenShareMonitorCapture: () => ipcRenderer.invoke('start-linux-screen-share-monitor-capture'),
stopLinuxScreenShareMonitorCapture: (captureId) => ipcRenderer.invoke('stop-linux-screen-share-monitor-capture', captureId),
onLinuxScreenShareMonitorAudioChunk: (listener) => {
const wrappedListener = (_event: Electron.IpcRendererEvent, payload: LinuxScreenShareMonitorAudioChunkPayload) => {
const chunk = payload.chunk instanceof Uint8Array
? payload.chunk
: Uint8Array.from((payload as { chunk?: Iterable<number> }).chunk || []);
listener({
...payload,
chunk
});
};
ipcRenderer.on(LINUX_SCREEN_SHARE_MONITOR_AUDIO_CHUNK_CHANNEL, wrappedListener);
return () => {
ipcRenderer.removeListener(LINUX_SCREEN_SHARE_MONITOR_AUDIO_CHUNK_CHANNEL, wrappedListener);
};
},
onLinuxScreenShareMonitorAudioEnded: (listener) => {
const wrappedListener = (_event: Electron.IpcRendererEvent, payload: LinuxScreenShareMonitorAudioEndedPayload) => {
listener(payload);
};
ipcRenderer.on(LINUX_SCREEN_SHARE_MONITOR_AUDIO_ENDED_CHANNEL, wrappedListener);
return () => {
ipcRenderer.removeListener(LINUX_SCREEN_SHARE_MONITOR_AUDIO_ENDED_CHANNEL, wrappedListener);
};
},
getAppDataPath: () => ipcRenderer.invoke('get-app-data-path'),
getDesktopSettings: () => ipcRenderer.invoke('get-desktop-settings'),
setDesktopSettings: (patch) => ipcRenderer.invoke('set-desktop-settings', patch),
relaunchApp: () => ipcRenderer.invoke('relaunch-app'),
readFile: (filePath) => ipcRenderer.invoke('read-file', filePath),
writeFile: (filePath, data) => ipcRenderer.invoke('write-file', filePath, data),
saveFileAs: (defaultFileName, data) => ipcRenderer.invoke('save-file-as', defaultFileName, data),