77
88use crate :: shareable_content:: { SCDisplay , SCRunningApplication , SCWindow } ;
99use std:: ffi:: c_void;
10+ use std:: sync:: { Arc , Mutex , Condvar } ;
11+
12+ /// Shared state for synchronous picker
13+ struct SyncPickerState {
14+ result : Option < SCContentSharingPickerResult > ,
15+ }
16+
17+ /// Holder for state + condvar
18+ struct SyncPicker {
19+ state : Mutex < SyncPickerState > ,
20+ condvar : Condvar ,
21+ }
1022
1123extern "C" fn picker_callback (
1224 result_code : i32 ,
1325 stream_ptr : * const c_void ,
1426 user_data : * mut c_void ,
1527) {
16- let tx = unsafe {
17- Box :: from_raw (
18- user_data. cast :: < std:: sync:: mpsc:: Sender < SCContentSharingPickerResult > > ( ) ,
19- )
20- } ;
28+ let picker = unsafe { Arc :: from_raw ( user_data. cast :: < SyncPicker > ( ) ) } ;
2129
2230 let result = match result_code {
2331 0 => SCContentSharingPickerResult :: Cancelled ,
@@ -30,7 +38,14 @@ extern "C" fn picker_callback(
3038 _ => SCContentSharingPickerResult :: Cancelled ,
3139 } ;
3240
33- let _ = tx. send ( result) ;
41+ {
42+ let mut state = picker. state . lock ( ) . unwrap ( ) ;
43+ state. result = Some ( result) ;
44+ }
45+ picker. condvar . notify_one ( ) ;
46+
47+ // Release our reference - the caller still holds one
48+ drop ( picker) ;
3449}
3550
3651/// Picker style determines what content types can be selected
@@ -136,18 +151,26 @@ impl SCContentSharingPicker {
136151 pub fn show (
137152 config : & SCContentSharingPickerConfiguration ,
138153 ) -> SCContentSharingPickerResult {
139- let ( tx, rx) = std:: sync:: mpsc:: channel ( ) ;
154+ let picker = Arc :: new ( SyncPicker {
155+ state : Mutex :: new ( SyncPickerState { result : None } ) ,
156+ condvar : Condvar :: new ( ) ,
157+ } ) ;
140158
141- let user_data = Box :: into_raw ( Box :: new ( tx ) ) . cast :: < c_void > ( ) ;
159+ let user_data = Arc :: into_raw ( picker . clone ( ) ) . cast_mut ( ) . cast :: < c_void > ( ) ;
142160
143161 unsafe {
144162 crate :: ffi:: sc_content_sharing_picker_show ( config. as_ptr ( ) , picker_callback, user_data) ;
145163 }
146164
147- rx. recv ( )
148- . unwrap_or ( SCContentSharingPickerResult :: Error (
149- "Failed to receive result" . to_string ( ) ,
150- ) )
165+ // Wait for callback
166+ let mut state = picker. state . lock ( ) . unwrap ( ) ;
167+ while state. result . is_none ( ) {
168+ state = picker. condvar . wait ( state) . unwrap ( ) ;
169+ }
170+
171+ state. result . take ( ) . unwrap_or ( SCContentSharingPickerResult :: Error (
172+ "Failed to receive result" . to_string ( ) ,
173+ ) )
151174 }
152175}
153176
0 commit comments