瀏覽代碼

fix(core): mark event commands as async (#11355)

* fix(core): mark event commands as async

this fixes a deadlock on certain situations

* add tag
Lucas Fernandes Nogueira 9 月之前
父節點
當前提交
3cb73d08c6

+ 5 - 0
.changes/event-commands-async.md

@@ -0,0 +1,5 @@
+---
+"tauri": patch:enhance
+---
+
+Mark the event commands as async so they do not block the main thread.

+ 4 - 4
crates/tauri/src/event/plugin.rs

@@ -65,7 +65,7 @@ impl<'de> Deserialize<'de> for WebviewLabel {
 }
 
 #[command(root = "crate")]
-pub fn listen<R: Runtime>(
+pub async fn listen<R: Runtime>(
   webview: Webview<R>,
   event: EventName,
   target: EventTarget,
@@ -75,7 +75,7 @@ pub fn listen<R: Runtime>(
 }
 
 #[command(root = "crate")]
-pub fn unlisten<R: Runtime>(
+pub async fn unlisten<R: Runtime>(
   webview: Webview<R>,
   event: EventName,
   event_id: EventId,
@@ -84,7 +84,7 @@ pub fn unlisten<R: Runtime>(
 }
 
 #[command(root = "crate")]
-pub fn emit<R: Runtime>(
+pub async fn emit<R: Runtime>(
   app: AppHandle<R>,
   event: EventName,
   payload: Option<JsonValue>,
@@ -93,7 +93,7 @@ pub fn emit<R: Runtime>(
 }
 
 #[command(root = "crate")]
-pub fn emit_to<R: Runtime>(
+pub async fn emit_to<R: Runtime>(
   app: AppHandle<R>,
   target: EventTarget,
   event: EventName,

+ 8 - 2
crates/tauri/src/manager/mod.rs

@@ -532,8 +532,14 @@ impl<R: Runtime> AppManager<R> {
     let emit_args = EmitArgs::new(event, payload)?;
 
     let listeners = self.listeners();
-
-    listeners.emit_js(self.webview.webviews_lock().values(), event, &emit_args)?;
+    let webviews = self
+      .webview
+      .webviews_lock()
+      .values()
+      .cloned()
+      .collect::<Vec<_>>();
+
+    listeners.emit_js(webviews.iter(), event, &emit_args)?;
     listeners.emit(emit_args)?;
 
     Ok(())

+ 3 - 3
crates/tauri/src/manager/webview.rs

@@ -624,9 +624,9 @@ impl<R: Runtime> WebviewManager<R> {
 
   pub fn eval_script_all<S: Into<String>>(&self, script: S) -> crate::Result<()> {
     let script = script.into();
-    self
-      .webviews_lock()
-      .values()
+    let webviews = self.webviews_lock().values().cloned().collect::<Vec<_>>();
+    webviews
+      .iter()
       .try_for_each(|webview| webview.eval(&script))
   }