From 35ea5956d060f0bdafd140f2541c607bb811805b Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Wed, 13 Mar 2024 14:41:23 +0100 Subject: [PATCH] fix(dialog): Create dialogs on main thread (#1073) fixes https://github.com/tauri-apps/tauri/issues/6301 --- .changes/dialog-main-thread.md | 5 ++ .../src-tauri/gen/schemas/desktop-schema.json | 8 ++-- plugins/dialog/src/desktop.rs | 48 ++++++++++++------- .../updater/permissions/schemas/schema.json | 10 ++-- 4 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 .changes/dialog-main-thread.md diff --git a/.changes/dialog-main-thread.md b/.changes/dialog-main-thread.md new file mode 100644 index 00000000..c4388bc6 --- /dev/null +++ b/.changes/dialog-main-thread.md @@ -0,0 +1,5 @@ +--- +dialog: patch +--- + +Fixed an issue where the dialog apis panicked when they were called with no application windows open. diff --git a/examples/api/src-tauri/gen/schemas/desktop-schema.json b/examples/api/src-tauri/gen/schemas/desktop-schema.json index 52ed8e22..a01af248 100644 --- a/examples/api/src-tauri/gen/schemas/desktop-schema.json +++ b/examples/api/src-tauri/gen/schemas/desktop-schema.json @@ -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" }, diff --git a/plugins/dialog/src/desktop.rs b/plugins/dialog/src/desktop.rs index 5d98952d..606a933f 100644 --- a/plugins/dialog/src/desktop.rs +++ b/plugins/dialog/src/desktop.rs @@ -42,18 +42,6 @@ impl Dialog { } } -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 for rfd::MessageLevel { fn from(kind: MessageDialogKind) -> Self { match kind { @@ -132,7 +120,11 @@ pub fn pick_file) + Send + 'static>( f: F, ) { let f = |path: Option| 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>) + Send + 'static>( @@ -142,7 +134,11 @@ pub fn pick_files>) + Send + 'static>( let f = |paths: Option>| { 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) + Send + 'static>( @@ -150,7 +146,11 @@ pub fn pick_folder) + Send + 'static>( f: F, ) { let f = |path: Option| 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>) + Send + 'static>( @@ -160,7 +160,11 @@ pub fn pick_folders>) + Send + 'static let f = |paths: Option>| { 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) + Send + 'static>( @@ -168,7 +172,11 @@ pub fn save_file) + Send + 'static>( f: F, ) { let f = |path: Option| 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( }); }; - 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))); + }); } diff --git a/plugins/updater/permissions/schemas/schema.json b/plugins/updater/permissions/schemas/schema.json index 69135976..6d6a3c21 100644 --- a/plugins/updater/permissions/schemas/schema.json +++ b/plugins/updater/permissions/schemas/schema.json @@ -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" }