Skip to content

Commit 343bea1

Browse files
committed
perf(screensharing): update sources on visibilitychange, not every 1s
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
1 parent e1d3fcf commit 343bea1

File tree

1 file changed

+35
-40
lines changed

1 file changed

+35
-40
lines changed

src/talk/renderer/screensharing/DesktopMediaSourceDialog.vue

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,25 @@
44
-->
55

66
<script setup lang="ts">
7-
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
7+
import type { ScreensharingSource, ScreensharingSourceId } from './screensharing.types.ts'
8+
import { computed, ref, watch } from 'vue'
89
import IconCancel from '@mdi/svg/svg/cancel.svg?raw'
910
import IconMonitorShare from '@mdi/svg/svg/monitor-share.svg?raw'
1011
import NcDialog from '@nextcloud/vue/dist/Components/NcDialog.js'
1112
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
1213
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
13-
import { translate as t } from '@nextcloud/l10n'
14+
import { t } from '@nextcloud/l10n'
15+
import { useDocumentVisibility } from '@vueuse/core'
1416
import DesktopMediaSourcePreview from './DesktopMediaSourcePreview.vue'
15-
import type { ScreensharingSource, ScreensharingSourceId } from './screensharing.types.ts'
1617
1718
const emit = defineEmits<{
1819
(event: 'submit', sourceId: ScreensharingSourceId): void
1920
(event: 'cancel'): void
2021
}>()
2122
22-
const RE_REQUEST_SOURCES_TIMEOUT = 1000
23-
24-
// On Wayland getting each stream for the live preview requests user to select the source via system dialog again
25-
// Instead - show static images.
26-
// See: https://github.com/electron/electron/issues/27732
27-
const previewType = window.systemInfo.isWayland ? 'thumbnail' : 'live'
28-
2923
const selectedSourceId = ref<ScreensharingSourceId | null>(null)
3024
const sources = ref<ScreensharingSource[] | null>(null)
3125
32-
const handleSubmit = () => emit('submit', selectedSourceId.value!)
33-
const handleCancel = () => emit('cancel')
34-
3526
const dialogButtons = computed(() => [
3627
{
3728
label: t('talk_desktop', 'Cancel'),
@@ -47,7 +38,23 @@ const dialogButtons = computed(() => [
4738
},
4839
])
4940
50-
const requestDesktopCapturerSources = async () => {
41+
// On Wayland instead of the list of all available sources,
42+
// the system picker is used to have a list of a single selected source.
43+
// Getting the stream for the selected source triggers the system picker again.
44+
// As a result:
45+
// - Live preview is not possible
46+
// - Sources list update is not possible
47+
// - There is no the entire-desktop option
48+
// See also: https://github.com/electron/electron/issues/27732
49+
if (!window.systemInfo.isWayland) {
50+
const visibilityState = useDocumentVisibility()
51+
watch(visibilityState, requestDesktopCapturerSources)
52+
}
53+
54+
/**
55+
* Request the desktop capturer sources
56+
*/
57+
async function requestDesktopCapturerSources() {
5158
sources.value = await window.TALK_DESKTOP.getDesktopCapturerSources() as ScreensharingSource[] | null
5259
5360
// There is no source. Probably the user hasn't granted the permission.
@@ -81,6 +88,11 @@ const requestDesktopCapturerSources = async () => {
8188
// On macOS the entire-desktop captures only the primary screen and capturing system audio crashes audio (microphone).
8289
// TODO: use the system picker on macOS Sonoma and later
8390
sources.value = window.systemInfo.isWayland || window.systemInfo.isMac ? [...screens, ...windows] : [...screens, entireDesktop, ...windows]
91+
92+
// Preselect the first media source if any
93+
if (!selectedSourceId.value) {
94+
selectedSourceId.value = sources.value?.[0]?.id ?? null
95+
}
8496
}
8597
8698
/**
@@ -94,36 +106,19 @@ function handleVideoSuspend(source: ScreensharingSource) {
94106
}
95107
}
96108
97-
let reRequestTimeout: number | undefined
98-
99109
/**
100-
* Schedule a request for desktop capturer sources
110+
* Handle the submit event of the dialog
101111
*/
102-
function scheduleRequestDesktopCaprutererSources() {
103-
reRequestTimeout = window.setTimeout(async () => {
104-
await requestDesktopCapturerSources()
105-
scheduleRequestDesktopCaprutererSources()
106-
}, RE_REQUEST_SOURCES_TIMEOUT)
112+
function handleSubmit() {
113+
emit('submit', selectedSourceId.value!)
107114
}
108115
109-
onMounted(async () => {
110-
await requestDesktopCapturerSources()
111-
112-
// Preselect the first media source if any
113-
if (!selectedSourceId.value) {
114-
selectedSourceId.value = sources.value?.[0]?.id ?? null
115-
}
116-
117-
if (previewType === 'live') {
118-
scheduleRequestDesktopCaprutererSources()
119-
}
120-
})
121-
122-
onBeforeUnmount(() => {
123-
if (reRequestTimeout) {
124-
clearTimeout(reRequestTimeout)
125-
}
126-
})
116+
/**
117+
* Handle the cancel event of the dialog
118+
*/
119+
function handleCancel() {
120+
emit('cancel')
121+
}
127122
</script>
128123

129124
<template>

0 commit comments

Comments
 (0)