From 1ab930465f43fc4574ce71ed2bda57b1f80a802b Mon Sep 17 00:00:00 2001 From: shouyu Date: Wed, 14 Oct 2026 01:44:22 +0800 Subject: [PATCH] fix(opener): avoid blocking-runtime panic in reveal_item_in_dir (#3565) * fix(opener): avoid blocking-runtime panic in reveal_item_in_dir * fix(opener): run zbus reveal on a dedicated thread for all callers Move the runtime-panic fix into the Linux/BSD implementation so the public Rust APIs are covered too, not just the JS command, and propagate the spawn_blocking join error via the existing Tauri error variant. --------- Co-authored-by: Lucas Nogueira --- .../fix-opener-reveal-item-in-dir-blocking-panic.md | 6 ++++++ plugins/opener/src/commands.rs | 3 ++- plugins/opener/src/reveal_item_in_dir.rs | 11 +++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 .changes/fix-opener-reveal-item-in-dir-blocking-panic.md diff --git a/.changes/fix-opener-reveal-item-in-dir-blocking-panic.md b/.changes/fix-opener-reveal-item-in-dir-blocking-panic.md new file mode 100644 index 000000000..ecafb1837 --- /dev/null +++ b/.changes/fix-opener-reveal-item-in-dir-blocking-panic.md @@ -0,0 +1,6 @@ +--- +"opener": "patch" +"opener-js": "patch" +--- + +Fixed `revealItemInDir` and the `reveal_item_in_dir` / `reveal_items_in_dir` Rust APIs panicking on Linux and the BSDs with `Cannot start a runtime from within a runtime` when zbus is built with its `tokio` feature and the call happens inside an async runtime. The blocking D-Bus calls now run on a dedicated thread. diff --git a/plugins/opener/src/commands.rs b/plugins/opener/src/commands.rs index af66d9726..b8d9c89c4 100644 --- a/plugins/opener/src/commands.rs +++ b/plugins/opener/src/commands.rs @@ -72,5 +72,6 @@ pub async fn open_path( /// TODO: in the next major version, rename to `reveal_items_in_dir` #[tauri::command] pub async fn reveal_item_in_dir(paths: Vec) -> crate::Result<()> { - crate::reveal_items_in_dir(&paths) + // `reveal_items_in_dir` blocks on D-Bus / shell calls, so keep it off the async runtime workers. + tauri::async_runtime::spawn_blocking(move || crate::reveal_items_in_dir(&paths)).await? } diff --git a/plugins/opener/src/reveal_item_in_dir.rs b/plugins/opener/src/reveal_item_in_dir.rs index fa63b9508..461898c92 100644 --- a/plugins/opener/src/reveal_item_in_dir.rs +++ b/plugins/opener/src/reveal_item_in_dir.rs @@ -213,6 +213,17 @@ mod imp { use std::path::PathBuf; pub fn reveal_items_in_dir(paths: &[PathBuf]) -> crate::Result<()> { + // `zbus::blocking` starts its own tokio runtime when zbus is built with the `tokio` feature, + // which panics with "Cannot start a runtime from within a runtime" if the caller is already + // inside one (e.g. an async command), so always run it on a dedicated thread. + std::thread::scope(|s| { + s.spawn(|| reveal_items_in_dir_blocking(paths)) + .join() + .unwrap_or_else(|e| std::panic::resume_unwind(e)) + }) + } + + fn reveal_items_in_dir_blocking(paths: &[PathBuf]) -> crate::Result<()> { let connection = zbus::blocking::Connection::session()?; reveal_with_filemanager1(paths, &connection).or_else(|e| {