feat(voice): give window shares their own audio scope (#2446)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-04 15:48:37 +02:00
1 parent 0d8116d73e
commit bc7f701e87
23 files changed
+1252 -611

No files matched your search

@@ -40,7 +40,6 @@ import {
} from '@app/features/user/components/modals/tabs/advanced_settings_tab/AdvancedDesktopControls';
import {UnreadBadgeCustomizationControl} from '@app/features/user/components/modals/tabs/advanced_settings_tab/AdvancedExperimentalControls';
import {
ManualScreenShareAudioSourcesControl,
OpenH264Control,
ScreenShareAv1OptInControl,
ScreenShareCodecControl,
@@ -88,7 +87,6 @@ export const DIRECT_CONTROL_ITEM_IDS = new Set([
'voice-video-screen-share-av1-opt-in',
'voice-video-screen-share-hevc-opt-in',
'voice-video-openh264-codec',
'voice-video-manual-screen-share-audio-sources',
'voice-video-screen-share-preview-behavior',
'voice-video-screen-share-encoder-controls',
'advanced-unread-badge-customization',
@@ -125,7 +123,6 @@ export const COMPACT_SWITCH_CONTROL_ITEM_IDS = new Set([
'voice-video-new-device-alerts',
'voice-video-connection-volume-controls',
'voice-video-openh264-codec',
'voice-video-manual-screen-share-audio-sources',
'voice-video-screen-share-av1-opt-in',
'voice-video-screen-share-hevc-opt-in',
'advanced-unread-badge-customization',
@@ -286,10 +283,6 @@ export const AdvancedSettingControl = observer(({item}: {item: SearchableSetting
return (
<OpenH264Control data-flx="user.advanced-setting-direct-controls.advanced-setting-control.open-h264-control" />
);
case 'voice-video-manual-screen-share-audio-sources':
return (
<ManualScreenShareAudioSourcesControl data-flx="user.advanced-setting-direct-controls.advanced-setting-control.manual-screen-share-audio-sources-control" />
);
case 'voice-video-screen-share-preview-behavior':
return (
<ScreenSharePreviewBehaviorControl data-flx="user.advanced-setting-direct-controls.advanced-setting-control.screen-share-preview-behavior-control" />
@@ -28,11 +28,8 @@ import {
selectAutomaticScreenShareCodec,
} from '@app/features/voice/utils/CodecCapabilityDetector';
import {getGpuEncoderReportSync, loadGpuEncoderReport} from '@app/features/voice/utils/GpuEncoderCapabilities';
import {getNativeAudioAvailabilitySnapshot} from '@app/features/voice/utils/NativeAudioCaptureBridge';
import {setOpenH264Enabled} from '@app/features/voice/utils/OpenH264Status';
import {CODEC_DISPLAY_LABEL} from '@app/features/voice/utils/ScreenShareCodecPolicy';
import {reapplyActiveScreenShareAudioSources} from '@app/features/voice/utils/ScreenShareStartFlow';
import {maySupportManualScreenShareAudioSourceSelection} from '@app/features/voice/utils/StreamSettingsUpdatePolicy';
import {msg} from '@lingui/core/macro';
import {useLingui} from '@lingui/react/macro';
import {GearIcon} from '@phosphor-icons/react';
@@ -192,11 +189,6 @@ const HEVC_SCREEN_SHARE_OPT_IN_DESCRIPTOR = msg({
comment:
'Switch label for the H.265/HEVC screen-share opt-in. H.265 and HEVC are codec names and should stay literal.',
});
const MANUAL_SCREEN_SHARE_AUDIO_SOURCES_DESCRIPTOR = msg({
message: 'Pick the apps to capture audio from',
comment:
'Switch label for the advanced opt-in that reveals a manual per-application audio source picker in the stream settings menu.',
});
const SCREEN_SHARE_CODEC_OPTION_ORDER = ['av1', 'h265', 'h264', 'vp9', 'vp8'] as const;
export const ScreenShareCodecControl = observer(() => {
@@ -269,31 +261,6 @@ export const ScreenShareHevcOptInControl = observer(() => {
);
});
export const ManualScreenShareAudioSourcesControl = observer(() => {
const {i18n} = useLingui();
if (!isDesktop()) return null;
if (
!maySupportManualScreenShareAudioSourceSelection({
platform: getElectronAPI()?.platform,
nativeAudioAvailability: getNativeAudioAvailabilitySnapshot(),
})
) {
return null;
}
return (
<Switch
ariaLabel={i18n._(MANUAL_SCREEN_SHARE_AUDIO_SOURCES_DESCRIPTOR)}
value={VoiceSettings.getScreenShareManualAudioSourcesOptIn()}
onChange={(value) => {
VoiceSettingsCommands.update({screenShareManualAudioSourcesOptIn: value});
void reapplyActiveScreenShareAudioSources();
}}
compact
data-flx="user.advanced-settings-tab.switch.manual-screen-share-audio-sources"
/>
);
});
export const OpenH264Control = observer(() => {
const {i18n} = useLingui();
const handleChange = useCallback((value: boolean) => {
@@ -3,8 +3,6 @@
import {PRODUCT_NAME} from '@app/features/app/config/I18nDisplayConstants';
import {getElectronAPI, isDesktop} from '@app/features/ui/utils/NativeUtils';
import type {SearchableSettingDescriptor} from '@app/features/user/components/settings_utils/search_index/SearchIndexTypes';
import {getNativeAudioAvailabilitySnapshot} from '@app/features/voice/utils/NativeAudioCaptureBridge';
import {maySupportManualScreenShareAudioSourceSelection} from '@app/features/voice/utils/StreamSettingsUpdatePolicy';
import {msg} from '@lingui/core/macro';
const SHOW_NEW_DEVICE_ALERTS_DESCRIPTOR = msg({
@@ -124,31 +122,6 @@ const ENABLE_OPENH264_SOFTWARE_ENCODING_AND_DECODING_ON_LINUX_DESCRIPTOR = msg({
message: 'OpenH264 software codec on Linux',
comment: 'Settings search entry description. One-line summary of what the settings search entry controls.',
});
const PICK_THE_APPS_TO_CAPTURE_AUDIO_FROM_DESCRIPTOR = msg({
message: 'Pick the apps to capture audio from',
comment: 'Settings search entry label. Names an advanced screen-share audio setting in the settings UI.',
});
const APPLICATION_AUDIO_DESCRIPTOR = msg({
message: 'Application audio',
comment: 'Settings search synonym. Used to match this term when the user types it in the settings search bar.',
});
const AUDIO_SOURCES_DESCRIPTOR = msg({
message: 'Audio sources',
comment: 'Settings search synonym. Used to match this term when the user types it in the settings search bar.',
});
const CAPTURE_CARD_DESCRIPTOR = msg({
message: 'Capture card',
comment: 'Settings search synonym. Used to match this term when the user types it in the settings search bar.',
});
const VIRTUAL_MICROPHONE_DESCRIPTOR = msg({
message: 'Virtual microphone',
comment: 'Settings search synonym. Used to match this term when the user types it in the settings search bar.',
});
const MANUAL_AUDIO_SOURCE_PICKER_NOTE_DESCRIPTOR = msg({
message:
'Adds a manual audio source picker to the stream settings menu. Without it, a shared window already captures that app and a shared screen captures your desktop.',
comment: 'Settings search entry description. One-line summary of what the settings search entry controls.',
});
const SCREEN_SHARE_PREVIEW_BEHAVIOR_DESCRIPTOR = msg({
message: 'Screen share preview behavior',
comment: 'Settings search entry label. Names the settings search entry in the settings UI.',
@@ -274,27 +247,6 @@ export const voiceVideoIndex: Array<SearchableSettingDescriptor> = [
tags: ['media', 'voice'],
isVisible: () => isDesktop() && getElectronAPI()?.platform === 'linux',
},
{
id: 'voice-video-manual-screen-share-audio-sources',
tabType: 'voice_video',
sectionId: 'video',
label: PICK_THE_APPS_TO_CAPTURE_AUDIO_FROM_DESCRIPTOR,
keywords: [
APPLICATION_AUDIO_DESCRIPTOR,
AUDIO_SOURCES_DESCRIPTOR,
CAPTURE_CARD_DESCRIPTOR,
VIRTUAL_MICROPHONE_DESCRIPTOR,
],
description: MANUAL_AUDIO_SOURCE_PICKER_NOTE_DESCRIPTOR,
audience: 'advanced',
tags: ['media', 'voice'],
isVisible: () =>
isDesktop() &&
maySupportManualScreenShareAudioSourceSelection({
platform: getElectronAPI()?.platform,
nativeAudioAvailability: getNativeAudioAvailabilitySnapshot(),
}),
},
{
id: 'voice-video-screen-share-preview-behavior',
tabType: 'voice_video',