fix(dialog): Create dialogs on main thread (#1073)

fixes https://github.com/tauri-apps/tauri/issues/6301
pull/1082/head
Fabian-Lars 1 year ago committed by GitHub
parent 14c858391d
commit 35ea5956d0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
dialog: patch
---
Fixed an issue where the dialog apis panicked when they were called with no application windows open.

@ -2362,7 +2362,7 @@
"type": "object",
"required": [
"args",
"command",
"cmd",
"name",
"sidecar"
],
@ -2375,7 +2375,7 @@
}
]
},
"command": {
"cmd": {
"description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
"type": "string"
},
@ -2397,7 +2397,7 @@
"type": "object",
"required": [
"args",
"command",
"cmd",
"name",
"sidecar"
],
@ -2410,7 +2410,7 @@
}
]
},
"command": {
"cmd": {
"description": "The command name. It can start with a variable that resolves to a system base directory. The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`, `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`, `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$APP`, `$LOG`, `$TEMP`, `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.",
"type": "string"
},

@ -42,18 +42,6 @@ impl<R: Runtime> Dialog<R> {
}
}
macro_rules! run_dialog {
($e:expr, $h: expr) => {{
std::thread::spawn(move || $h(tauri::async_runtime::block_on($e)));
}};
}
macro_rules! run_file_dialog {
($e:expr, $h: ident) => {{
std::thread::spawn(move || $h(tauri::async_runtime::block_on($e)));
}};
}
impl From<MessageDialogKind> for rfd::MessageLevel {
fn from(kind: MessageDialogKind) -> Self {
match kind {
@ -132,7 +120,11 @@ pub fn pick_file<R: Runtime, F: FnOnce(Option<PathBuf>) + Send + 'static>(
f: F,
) {
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf()));
run_file_dialog!(AsyncFileDialog::from(dialog).pick_file(), f)
let handle = dialog.dialog.app_handle().to_owned();
let _ = handle.run_on_main_thread(move || {
let dialog = AsyncFileDialog::from(dialog).pick_file();
std::thread::spawn(move || f(tauri::async_runtime::block_on(dialog)));
});
}
pub fn pick_files<R: Runtime, F: FnOnce(Option<Vec<PathBuf>>) + Send + 'static>(
@ -142,7 +134,11 @@ pub fn pick_files<R: Runtime, F: FnOnce(Option<Vec<PathBuf>>) + Send + 'static>(
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!(AsyncFileDialog::from(dialog).pick_files(), f)
let handle = dialog.dialog.app_handle().to_owned();
let _ = handle.run_on_main_thread(move || {
let dialog = AsyncFileDialog::from(dialog).pick_files();
std::thread::spawn(move || f(tauri::async_runtime::block_on(dialog)));
});
}
pub fn pick_folder<R: Runtime, F: FnOnce(Option<PathBuf>) + Send + 'static>(
@ -150,7 +146,11 @@ pub fn pick_folder<R: Runtime, F: FnOnce(Option<PathBuf>) + Send + 'static>(
f: F,
) {
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf()));
run_file_dialog!(AsyncFileDialog::from(dialog).pick_folder(), f)
let handle = dialog.dialog.app_handle().to_owned();
let _ = handle.run_on_main_thread(move || {
let dialog = AsyncFileDialog::from(dialog).pick_folder();
std::thread::spawn(move || f(tauri::async_runtime::block_on(dialog)));
});
}
pub fn pick_folders<R: Runtime, F: FnOnce(Option<Vec<PathBuf>>) + Send + 'static>(
@ -160,7 +160,11 @@ pub fn pick_folders<R: Runtime, F: FnOnce(Option<Vec<PathBuf>>) + Send + 'static
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!(AsyncFileDialog::from(dialog).pick_folders(), f)
let handle = dialog.dialog.app_handle().to_owned();
let _ = handle.run_on_main_thread(move || {
let dialog = AsyncFileDialog::from(dialog).pick_folders();
std::thread::spawn(move || f(tauri::async_runtime::block_on(dialog)));
});
}
pub fn save_file<R: Runtime, F: FnOnce(Option<PathBuf>) + Send + 'static>(
@ -168,7 +172,11 @@ pub fn save_file<R: Runtime, F: FnOnce(Option<PathBuf>) + Send + 'static>(
f: F,
) {
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf()));
run_file_dialog!(AsyncFileDialog::from(dialog).save_file(), f)
let handle = dialog.dialog.app_handle().to_owned();
let _ = handle.run_on_main_thread(move || {
let dialog = AsyncFileDialog::from(dialog).save_file();
std::thread::spawn(move || f(tauri::async_runtime::block_on(dialog)));
});
}
/// Shows a message dialog
@ -187,5 +195,9 @@ pub fn show_message_dialog<R: Runtime, F: FnOnce(bool) + Send + 'static>(
});
};
run_dialog!(AsyncMessageDialog::from(dialog).show(), f);
let handle = dialog.dialog.app_handle().to_owned();
let _ = handle.run_on_main_thread(move || {
let dialog = AsyncMessageDialog::from(dialog).show();
std::thread::spawn(move || f(tauri::async_runtime::block_on(dialog)));
});
}

@ -139,10 +139,14 @@
},
"platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"type": [
"array",
"null"
"default": [
"linux",
"macOS",
"windows",
"android",
"iOS"
],
"type": "array",
"items": {
"$ref": "#/definitions/Target"
}

Loading…
Cancel
Save