Browse Source

fix(core): wait for tray cleanup before exiting app, closes #5244 (#5245)

Amr Bashir 2 years ago
parent
commit
f756cd5e7e

+ 5 - 0
.changes/tray-cleanup.md

@@ -0,0 +1,5 @@
+---
+"tauri-runtime-wry": "patch"
+---
+
+Fix regression introduce in tauri@1.1 which prevented removing tray icon when the app exits on Windows.

+ 10 - 5
core/tauri-runtime-wry/src/lib.rs

@@ -164,7 +164,10 @@ macro_rules! window_getter {
   }};
 }
 
-fn send_user_message<T: UserEvent>(context: &Context<T>, message: Message<T>) -> Result<()> {
+pub(crate) fn send_user_message<T: UserEvent>(
+  context: &Context<T>,
+  message: Message<T>,
+) -> Result<()> {
   if current_thread().id() == context.main_thread_id {
     handle_user_message(
       &context.main_thread.window_target,
@@ -1126,7 +1129,7 @@ pub enum TrayMessage {
   #[cfg(target_os = "macos")]
   UpdateTitle(String),
   Create(SystemTray, Sender<Result<()>>),
-  Destroy,
+  Destroy(Sender<Result<()>>),
 }
 
 pub type CreateWebviewClosure<T> = Box<
@@ -1789,6 +1792,7 @@ impl<T: UserEvent> RuntimeHandle<T> for WryHandle<T> {
     )?;
     rx.recv().unwrap()?;
     Ok(SystemTrayHandle {
+      context: self.context.clone(),
       id,
       proxy: self.context.proxy.clone(),
     })
@@ -1993,6 +1997,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
       );
 
     Ok(SystemTrayHandle {
+      context: self.context.clone(),
       id,
       proxy: self.event_loop.create_proxy(),
     })
@@ -2580,10 +2585,11 @@ fn handle_user_message<T: UserEvent>(
           TrayMessage::Create(_tray, _tx) => {
             // already handled
           }
-          TrayMessage::Destroy => {
+          TrayMessage::Destroy(tx) => {
             *tray_context.tray.lock().unwrap() = None;
             tray_context.listeners.lock().unwrap().clear();
             tray_context.items.lock().unwrap().clear();
+            tx.send(Ok(())).unwrap();
           }
         }
       }
@@ -2712,14 +2718,13 @@ fn handle_event_loop<T: UserEvent>(
           items.contains_key(&menu_id.0)
         };
         if has_menu {
-          listeners.replace(tray_context.listeners.clone());
+          listeners.replace(tray_context.listeners.lock().unwrap().clone());
           tray_id = *id;
           break;
         }
       }
       drop(trays);
       if let Some(listeners) = listeners {
-        let listeners = listeners.lock().unwrap();
         let handlers = listeners.iter();
         for handler in handlers {
           handler(&event);

+ 9 - 5
core/tauri-runtime-wry/src/system_tray.rs

@@ -27,7 +27,7 @@ pub use wry::application::platform::macos::{
 
 use wry::application::system_tray::{SystemTray as WrySystemTray, SystemTrayBuilder};
 
-use crate::{Error, Message, Result, TrayId, TrayMessage};
+use crate::{send_user_message, Context, Error, Message, Result, TrayId, TrayMessage};
 
 use tauri_runtime::{menu::MenuHash, SystemTray, UserEvent};
 
@@ -123,6 +123,7 @@ pub fn create_tray<T>(
 
 #[derive(Debug, Clone)]
 pub struct SystemTrayHandle<T: UserEvent> {
+  pub(crate) context: Context<T>,
   pub(crate) id: TrayId,
   pub(crate) proxy: EventLoopProxy<super::Message<T>>,
 }
@@ -172,10 +173,13 @@ impl<T: UserEvent> TrayHandle for SystemTrayHandle<T> {
   }
 
   fn destroy(&self) -> Result<()> {
-    self
-      .proxy
-      .send_event(Message::Tray(self.id, TrayMessage::Destroy))
-      .map_err(|_| Error::FailedToSendMessage)
+    let (tx, rx) = std::sync::mpsc::channel();
+    send_user_message(
+      &self.context,
+      Message::Tray(self.id, TrayMessage::Destroy(tx)),
+    )?;
+    rx.recv().unwrap()?;
+    Ok(())
   }
 }