@@ -97,47 +97,39 @@ export class LinuxWaylandPortalCaptureProvider implements CaptureProvider {
9797 private async waitForPortalResponse ( requestPath : string ) : Promise < any > {
9898 logger . info ( `Request path = ${ requestPath } ` )
9999
100- const requestObj = await this . dbusConnection . getProxyObject (
101- "org.freedesktop.portal.Desktop" ,
102- requestPath ,
103- )
104-
105- logger . info (
106- `Interfaces = ${ Object . keys ( requestObj . nodes ?? { } ) . join ( ", " ) } ` ,
107- )
108-
109- logger . info (
110- JSON . stringify (
111- requestObj . interfaces . map ( ( i : any ) => i . $name ) ,
112- null ,
113- 2 ,
114- ) ,
115- )
116-
117- const requestIface = requestObj . getInterface (
118- "org.freedesktop.portal.Request" ,
119- )
120100 return Promise . race ( [
121101 new Promise ( ( resolve , reject ) => {
122- requestIface . on ( "Response" , ( responseCode : number , results : any ) => {
123- if ( responseCode === 0 ) {
124- resolve ( results )
125- } else if ( responseCode === 1 ) {
102+ const handler = ( msg : any ) => {
103+ if ( msg . path !== requestPath ) return
104+ if ( msg . interface !== "org.freedesktop.portal.Request" ) return
105+ if ( msg . member !== "Response" ) return
106+
107+ this . dbusConnection . removeListener ( "message" , handler )
108+
109+ const [ responseCode , results ] = msg . body
110+ if ( responseCode === 0 ) resolve ( results )
111+ else if ( responseCode === 1 )
126112 reject ( new Error ( "User cancelled the Wayland screen cast prompt" ) )
127- } else {
113+ else
128114 reject (
129115 new Error (
130116 `Portal request failed with response code: ${ responseCode } ` ,
131117 ) ,
132118 )
133- }
134- } )
119+ }
120+ this . dbusConnection . on ( "message" , handler )
135121 } ) ,
136122 new Promise ( ( _ , reject ) =>
137- setTimeout ( ( ) => reject ( new Error ( "Portal request timeout" ) ) , 10000 ) ,
123+ setTimeout ( ( ) => reject ( new Error ( "Portal request timeout" ) ) , 30000 ) ,
138124 ) ,
139125 ] )
140126 }
127+ private getDbusId ( ) : string {
128+ // dbus-next exposes the unique name as e.g. ":1.88"
129+ const uniqueName : string = this . dbusConnection . name ?? ""
130+ // ":1.88" -> "1_88"
131+ return uniqueName . replace ( ":" , "" ) . replace ( / \. / g, "_" )
132+ }
141133
142134 private async negotiateScreenCastPortal ( ) : Promise < void > {
143135 const portalDest = "org.freedesktop.portal.Desktop"
@@ -149,6 +141,9 @@ export class LinuxWaylandPortalCaptureProvider implements CaptureProvider {
149141 logger . info ( "Portal Step 2 - Get ScreenRequest" )
150142 // 1. Create Session
151143 const token = generateToken ( ) . replaceAll ( "-" , "_" )
144+ const sessionResponsePromise = this . waitForPortalResponse (
145+ `/org/freedesktop/portal/desktop/request/${ this . getDbusId ( ) } /rein_create_req_${ token } ` ,
146+ )
152147 const sessionRequestPath = await screenCast . CreateSession ( {
153148 // Use this.dbusModule.Variant instead of this.dbusConnection.Variant
154149 session_handle_token : new this . dbusModule . Variant (
@@ -162,7 +157,7 @@ export class LinuxWaylandPortalCaptureProvider implements CaptureProvider {
162157 } )
163158 logger . info ( "Portal Step 2 - Get ScreenCast Results" )
164159 logger . info ( `CreateSession returned: ${ JSON . stringify ( sessionRequestPath ) } ` )
165- const sessionResults = await this . waitForPortalResponse ( sessionRequestPath )
160+ const sessionResults = await sessionResponsePromise
166161 logger . info ( `CreateSession response: ${ JSON . stringify ( sessionResults ) } ` )
167162 this . sessionPath = sessionResults [ "session_handle" ] . value
168163
@@ -173,18 +168,27 @@ export class LinuxWaylandPortalCaptureProvider implements CaptureProvider {
173168 }
174169
175170 // 2. Select Sources
176- const selectRequestPath = await screenCast . SelectSources ( this . sessionPath , {
171+ const selectToken = "rein_select_req"
172+ const selectResponsePromise = this . waitForPortalResponse (
173+ `/org/freedesktop/portal/desktop/request/${ this . getDbusId ( ) } /${ selectToken } ` ,
174+ )
175+ await screenCast . SelectSources ( this . sessionPath , {
177176 multiple : new this . dbusModule . Variant ( "b" , false ) ,
178177 types : new this . dbusModule . Variant ( "u" , 1 ) ,
179- handle_token : new this . dbusModule . Variant ( "s" , "rein_select_req" ) ,
178+ handle_token : new this . dbusModule . Variant ( "s" , selectToken ) ,
180179 } )
181- await this . waitForPortalResponse ( selectRequestPath )
180+ await selectResponsePromise
182181
183182 // 3. Start Session
184- const startRequestPath = await screenCast . Start ( this . sessionPath , {
185- handle_token : new this . dbusModule . Variant ( "s" , "rein_start_req" ) ,
183+ const startToken = "rein_start_req"
184+ const startResponsePromise = this . waitForPortalResponse (
185+ `/org/freedesktop/portal/desktop/request/${ this . getDbusId ( ) } /${ startToken } ` ,
186+ )
187+ await screenCast . Start ( this . sessionPath , "" , {
188+ // <-- "" is the parent window handle
189+ handle_token : new this . dbusModule . Variant ( "s" , startToken ) ,
186190 } )
187- const startResults = await this . waitForPortalResponse ( startRequestPath )
191+ const startResults = await startResponsePromise
188192
189193 const streamsVariant = startResults [ "streams" ]
190194 if (
@@ -196,21 +200,21 @@ export class LinuxWaylandPortalCaptureProvider implements CaptureProvider {
196200 logger . info (
197201 `Successfully negotiated Wayland Portal. Target PipeWire Node: ${ this . pipewireNodeId } ` ,
198202 )
203+ logger . info (
204+ `Streams payload: ${ JSON . stringify ( streamsVariant . value , null , 2 ) } ` ,
205+ )
206+ //await new Promise(() => {})
199207 } else {
200208 throw new Error ( "No screen cast streams returned by the Wayland portal." )
201209 }
202210
203211 // 4. OpenPipeWireRemote
204- await screenCast . OpenPipeWireRemote ( this . sessionPath , { } )
212+ // await screenCast.OpenPipeWireRemote(this.sessionPath, {})
205213 }
206214
207215 public async getGStreamerSource ( ) : Promise < string [ ] > {
208216 if ( this . pipewireNodeId !== null && this . pipewireNodeId > 0 ) {
209- return [
210- "pipewiresrc" ,
211- `target-object=${ this . pipewireNodeId } ` ,
212- "do-timestamp=true" ,
213- ]
217+ return [ "pipewiresrc" , `path=${ this . pipewireNodeId } ` , "do-timestamp=true" ]
214218 }
215219
216220 throw new Error ( "PipeWire node ID was not successfully extracted." )
0 commit comments