Skip to content

Commit

Permalink
fix(core): dialog parent window on macOS, closes #3312 (#3753)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Mar 23, 2022
1 parent 4e807a5 commit bf89a05
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 75 deletions.
5 changes: 5 additions & 0 deletions .changes/dialog-parent-macos.md
@@ -0,0 +1,5 @@
---
"tauri": patch
---

Use asynchronous file dialog on macOS and Windows to properly set the parent window.
75 changes: 65 additions & 10 deletions core/tauri/src/api/dialog.rs
Expand Up @@ -33,24 +33,52 @@ macro_rules! run_dialog {
}};
}

#[cfg(not(target_os = "linux"))]
macro_rules! run_file_dialog {
($e:expr, $h: ident) => {{
std::thread::spawn(move || {
let response = crate::async_runtime::block_on($e);
$h(response);
});
}};
}

#[cfg(target_os = "linux")]
macro_rules! run_file_dialog {
($e:expr, $h: ident) => {{
std::thread::spawn(move || {
let context = glib::MainContext::default();
context.invoke_with_priority(glib::PRIORITY_HIGH, move || {
let response = $e;
$h(response);
});
});
}};
}

macro_rules! run_dialog_sync {
($e:expr) => {{
let (tx, rx) = sync_channel(0);
let cb = move |response| {
tx.send(response).unwrap();
};
run_dialog!($e, cb);
run_file_dialog!($e, cb);
rx.recv().unwrap()
}};
}

macro_rules! file_dialog_builder {
() => {
#[cfg(target_os = "linux")]
type FileDialog = rfd::FileDialog;
#[cfg(not(target_os = "linux"))]
type FileDialog = rfd::AsyncFileDialog;

/// The file dialog builder.
///
/// Constructs file picker dialogs that can select single/multiple files or directories.
#[derive(Debug, Default)]
pub struct FileDialogBuilder(rfd::FileDialog);
pub struct FileDialogBuilder(FileDialog);

impl FileDialogBuilder {
/// Gets the default file dialog builder.
Expand Down Expand Up @@ -127,7 +155,11 @@ pub mod blocking {
/// }
/// ```
pub fn pick_file(self) -> Option<PathBuf> {
run_dialog_sync!(self.0.pick_file())
#[allow(clippy::let_and_return)]
let response = run_dialog_sync!(self.0.pick_file());
#[cfg(not(target_os = "linux"))]
let response = response.map(|p| p.path().to_path_buf());
response
}

/// Shows the dialog to select multiple files.
Expand All @@ -146,7 +178,12 @@ pub mod blocking {
/// }
/// ```
pub fn pick_files(self) -> Option<Vec<PathBuf>> {
run_dialog_sync!(self.0.pick_files())
#[allow(clippy::let_and_return)]
let response = run_dialog_sync!(self.0.pick_files());
#[cfg(not(target_os = "linux"))]
let response =
response.map(|paths| paths.into_iter().map(|p| p.path().to_path_buf()).collect());
response
}

/// Shows the dialog to select a single folder.
Expand All @@ -165,7 +202,11 @@ pub mod blocking {
/// }
/// ```
pub fn pick_folder(self) -> Option<PathBuf> {
run_dialog_sync!(self.0.pick_folder())
#[allow(clippy::let_and_return)]
let response = run_dialog_sync!(self.0.pick_folder());
#[cfg(not(target_os = "linux"))]
let response = response.map(|p| p.path().to_path_buf());
response
}

/// Shows the dialog to save a file.
Expand All @@ -184,7 +225,11 @@ pub mod blocking {
/// }
/// ```
pub fn save_file(self) -> Option<PathBuf> {
run_dialog_sync!(self.0.save_file())
#[allow(clippy::let_and_return)]
let response = run_dialog_sync!(self.0.save_file());
#[cfg(not(target_os = "linux"))]
let response = response.map(|p| p.path().to_path_buf());
response
}
}

Expand Down Expand Up @@ -305,7 +350,9 @@ mod nonblocking {
/// })
/// ```
pub fn pick_file<F: FnOnce(Option<PathBuf>) + Send + 'static>(self, f: F) {
run_dialog!(self.0.pick_file(), f)
#[cfg(not(target_os = "linux"))]
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf()));
run_file_dialog!(self.0.pick_file(), f)
}

/// Shows the dialog to select multiple files.
Expand All @@ -327,7 +374,11 @@ mod nonblocking {
/// })
/// ```
pub fn pick_files<F: FnOnce(Option<Vec<PathBuf>>) + Send + 'static>(self, f: F) {
run_dialog!(self.0.pick_files(), f)
#[cfg(not(target_os = "linux"))]
let f = |paths: Option<Vec<rfd::FileHandle>>| {
f(paths.map(|list| list.into_iter().map(|p| p.path().to_path_buf()).collect()))
};
run_file_dialog!(self.0.pick_files(), f)
}

/// Shows the dialog to select a single folder.
Expand All @@ -349,7 +400,9 @@ mod nonblocking {
/// })
/// ```
pub fn pick_folder<F: FnOnce(Option<PathBuf>) + Send + 'static>(self, f: F) {
run_dialog!(self.0.pick_folder(), f)
#[cfg(not(target_os = "linux"))]
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf()));
run_file_dialog!(self.0.pick_folder(), f)
}

/// Shows the dialog to save a file.
Expand All @@ -372,7 +425,9 @@ mod nonblocking {
/// })
/// ```
pub fn save_file<F: FnOnce(Option<PathBuf>) + Send + 'static>(self, f: F) {
run_dialog!(self.0.save_file(), f)
#[cfg(not(target_os = "linux"))]
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf()));
run_file_dialog!(self.0.save_file(), f)
}
}

Expand Down

0 comments on commit bf89a05

Please sign in to comment.