@@ -33,24 +33,52 @@ macro_rules! run_dialog {
3333 } } ;
3434}
3535
36+ #[ cfg( not( target_os = "linux" ) ) ]
37+ macro_rules! run_file_dialog {
38+ ( $e: expr, $h: ident) => { {
39+ std:: thread:: spawn( move || {
40+ let response = crate :: async_runtime:: block_on( $e) ;
41+ $h( response) ;
42+ } ) ;
43+ } } ;
44+ }
45+
46+ #[ cfg( target_os = "linux" ) ]
47+ macro_rules! run_file_dialog {
48+ ( $e: expr, $h: ident) => { {
49+ std:: thread:: spawn( move || {
50+ let context = glib:: MainContext :: default ( ) ;
51+ context. invoke_with_priority( glib:: PRIORITY_HIGH , move || {
52+ let response = $e;
53+ $h( response) ;
54+ } ) ;
55+ } ) ;
56+ } } ;
57+ }
58+
3659macro_rules! run_dialog_sync {
3760 ( $e: expr) => { {
3861 let ( tx, rx) = sync_channel( 0 ) ;
3962 let cb = move |response| {
4063 tx. send( response) . unwrap( ) ;
4164 } ;
42- run_dialog !( $e, cb) ;
65+ run_file_dialog !( $e, cb) ;
4366 rx. recv( ) . unwrap( )
4467 } } ;
4568}
4669
4770macro_rules! file_dialog_builder {
4871 ( ) => {
72+ #[ cfg( target_os = "linux" ) ]
73+ type FileDialog = rfd:: FileDialog ;
74+ #[ cfg( not( target_os = "linux" ) ) ]
75+ type FileDialog = rfd:: AsyncFileDialog ;
76+
4977 /// The file dialog builder.
5078 ///
5179 /// Constructs file picker dialogs that can select single/multiple files or directories.
5280 #[ derive( Debug , Default ) ]
53- pub struct FileDialogBuilder ( rfd :: FileDialog ) ;
81+ pub struct FileDialogBuilder ( FileDialog ) ;
5482
5583 impl FileDialogBuilder {
5684 /// Gets the default file dialog builder.
@@ -127,7 +155,11 @@ pub mod blocking {
127155 /// }
128156 /// ```
129157 pub fn pick_file ( self ) -> Option < PathBuf > {
130- run_dialog_sync ! ( self . 0 . pick_file( ) )
158+ #[ allow( clippy:: let_and_return) ]
159+ let response = run_dialog_sync ! ( self . 0 . pick_file( ) ) ;
160+ #[ cfg( not( target_os = "linux" ) ) ]
161+ let response = response. map ( |p| p. path ( ) . to_path_buf ( ) ) ;
162+ response
131163 }
132164
133165 /// Shows the dialog to select multiple files.
@@ -146,7 +178,12 @@ pub mod blocking {
146178 /// }
147179 /// ```
148180 pub fn pick_files ( self ) -> Option < Vec < PathBuf > > {
149- run_dialog_sync ! ( self . 0 . pick_files( ) )
181+ #[ allow( clippy:: let_and_return) ]
182+ let response = run_dialog_sync ! ( self . 0 . pick_files( ) ) ;
183+ #[ cfg( not( target_os = "linux" ) ) ]
184+ let response =
185+ response. map ( |paths| paths. into_iter ( ) . map ( |p| p. path ( ) . to_path_buf ( ) ) . collect ( ) ) ;
186+ response
150187 }
151188
152189 /// Shows the dialog to select a single folder.
@@ -165,7 +202,11 @@ pub mod blocking {
165202 /// }
166203 /// ```
167204 pub fn pick_folder ( self ) -> Option < PathBuf > {
168- run_dialog_sync ! ( self . 0 . pick_folder( ) )
205+ #[ allow( clippy:: let_and_return) ]
206+ let response = run_dialog_sync ! ( self . 0 . pick_folder( ) ) ;
207+ #[ cfg( not( target_os = "linux" ) ) ]
208+ let response = response. map ( |p| p. path ( ) . to_path_buf ( ) ) ;
209+ response
169210 }
170211
171212 /// Shows the dialog to save a file.
@@ -184,7 +225,11 @@ pub mod blocking {
184225 /// }
185226 /// ```
186227 pub fn save_file ( self ) -> Option < PathBuf > {
187- run_dialog_sync ! ( self . 0 . save_file( ) )
228+ #[ allow( clippy:: let_and_return) ]
229+ let response = run_dialog_sync ! ( self . 0 . save_file( ) ) ;
230+ #[ cfg( not( target_os = "linux" ) ) ]
231+ let response = response. map ( |p| p. path ( ) . to_path_buf ( ) ) ;
232+ response
188233 }
189234 }
190235
@@ -305,7 +350,9 @@ mod nonblocking {
305350 /// })
306351 /// ```
307352 pub fn pick_file < F : FnOnce ( Option < PathBuf > ) + Send + ' static > ( self , f : F ) {
308- run_dialog ! ( self . 0 . pick_file( ) , f)
353+ #[ cfg( not( target_os = "linux" ) ) ]
354+ let f = |path : Option < rfd:: FileHandle > | f ( path. map ( |p| p. path ( ) . to_path_buf ( ) ) ) ;
355+ run_file_dialog ! ( self . 0 . pick_file( ) , f)
309356 }
310357
311358 /// Shows the dialog to select multiple files.
@@ -327,7 +374,11 @@ mod nonblocking {
327374 /// })
328375 /// ```
329376 pub fn pick_files < F : FnOnce ( Option < Vec < PathBuf > > ) + Send + ' static > ( self , f : F ) {
330- run_dialog ! ( self . 0 . pick_files( ) , f)
377+ #[ cfg( not( target_os = "linux" ) ) ]
378+ let f = |paths : Option < Vec < rfd:: FileHandle > > | {
379+ f ( paths. map ( |list| list. into_iter ( ) . map ( |p| p. path ( ) . to_path_buf ( ) ) . collect ( ) ) )
380+ } ;
381+ run_file_dialog ! ( self . 0 . pick_files( ) , f)
331382 }
332383
333384 /// Shows the dialog to select a single folder.
@@ -349,7 +400,9 @@ mod nonblocking {
349400 /// })
350401 /// ```
351402 pub fn pick_folder < F : FnOnce ( Option < PathBuf > ) + Send + ' static > ( self , f : F ) {
352- run_dialog ! ( self . 0 . pick_folder( ) , f)
403+ #[ cfg( not( target_os = "linux" ) ) ]
404+ let f = |path : Option < rfd:: FileHandle > | f ( path. map ( |p| p. path ( ) . to_path_buf ( ) ) ) ;
405+ run_file_dialog ! ( self . 0 . pick_folder( ) , f)
353406 }
354407
355408 /// Shows the dialog to save a file.
@@ -372,7 +425,9 @@ mod nonblocking {
372425 /// })
373426 /// ```
374427 pub fn save_file < F : FnOnce ( Option < PathBuf > ) + Send + ' static > ( self , f : F ) {
375- run_dialog ! ( self . 0 . save_file( ) , f)
428+ #[ cfg( not( target_os = "linux" ) ) ]
429+ let f = |path : Option < rfd:: FileHandle > | f ( path. map ( |p| p. path ( ) . to_path_buf ( ) ) ) ;
430+ run_file_dialog ! ( self . 0 . save_file( ) , f)
376431 }
377432 }
378433
0 commit comments