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", "type": "object",
"required": [ "required": [
"args", "args",
"command", "cmd",
"name", "name",
"sidecar" "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`.", "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" "type": "string"
}, },
@ -2397,7 +2397,7 @@
"type": "object", "type": "object",
"required": [ "required": [
"args", "args",
"command", "cmd",
"name", "name",
"sidecar" "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`.", "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" "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 { impl From<MessageDialogKind> for rfd::MessageLevel {
fn from(kind: MessageDialogKind) -> Self { fn from(kind: MessageDialogKind) -> Self {
match kind { match kind {
@ -132,7 +120,11 @@ pub fn pick_file<R: Runtime, F: FnOnce(Option<PathBuf>) + Send + 'static>(
f: F, f: F,
) { ) {
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf())); 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>( 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>>| { let f = |paths: Option<Vec<rfd::FileHandle>>| {
f(paths.map(|list| list.into_iter().map(|p| p.path().to_path_buf()).collect())) 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>( 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, f: F,
) { ) {
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf())); 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>( 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>>| { let f = |paths: Option<Vec<rfd::FileHandle>>| {
f(paths.map(|list| list.into_iter().map(|p| p.path().to_path_buf()).collect())) 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>( 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, f: F,
) { ) {
let f = |path: Option<rfd::FileHandle>| f(path.map(|p| p.path().to_path_buf())); 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 /// 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": { "platforms": {
"description": "Target platforms this permission applies. By default all platforms are affected by this permission.", "description": "Target platforms this permission applies. By default all platforms are affected by this permission.",
"type": [ "default": [
"array", "linux",
"null" "macOS",
"windows",
"android",
"iOS"
], ],
"type": "array",
"items": { "items": {
"$ref": "#/definitions/Target" "$ref": "#/definitions/Target"
} }

Loading…
Cancel
Save