4
4
-->
5
5
6
6
<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'
8
9
import IconCancel from ' @mdi/svg/svg/cancel.svg?raw'
9
10
import IconMonitorShare from ' @mdi/svg/svg/monitor-share.svg?raw'
10
11
import NcDialog from ' @nextcloud/vue/dist/Components/NcDialog.js'
11
12
import NcEmptyContent from ' @nextcloud/vue/dist/Components/NcEmptyContent.js'
12
13
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'
14
16
import DesktopMediaSourcePreview from ' ./DesktopMediaSourcePreview.vue'
15
- import type { ScreensharingSource , ScreensharingSourceId } from ' ./screensharing.types.ts'
16
17
17
18
const emit = defineEmits <{
18
19
(event : ' submit' , sourceId : ScreensharingSourceId ): void
19
20
(event : ' cancel' ): void
20
21
}>()
21
22
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
-
29
23
const selectedSourceId = ref <ScreensharingSourceId | null >(null )
30
24
const sources = ref <ScreensharingSource [] | null >(null )
31
25
32
- const handleSubmit = () => emit (' submit' , selectedSourceId .value ! )
33
- const handleCancel = () => emit (' cancel' )
34
-
35
26
const dialogButtons = computed (() => [
36
27
{
37
28
label: t (' talk_desktop' , ' Cancel' ),
@@ -47,7 +38,23 @@ const dialogButtons = computed(() => [
47
38
},
48
39
])
49
40
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() {
51
58
sources .value = await window .TALK_DESKTOP .getDesktopCapturerSources () as ScreensharingSource [] | null
52
59
53
60
// There is no source. Probably the user hasn't granted the permission.
@@ -81,6 +88,11 @@ const requestDesktopCapturerSources = async () => {
81
88
// On macOS the entire-desktop captures only the primary screen and capturing system audio crashes audio (microphone).
82
89
// TODO: use the system picker on macOS Sonoma and later
83
90
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
+ }
84
96
}
85
97
86
98
/**
@@ -94,36 +106,19 @@ function handleVideoSuspend(source: ScreensharingSource) {
94
106
}
95
107
}
96
108
97
- let reRequestTimeout: number | undefined
98
-
99
109
/**
100
- * Schedule a request for desktop capturer sources
110
+ * Handle the submit event of the dialog
101
111
*/
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 ! )
107
114
}
108
115
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
+ }
127
122
</script >
128
123
129
124
<template >
0 commit comments