Skip to content

Commit 039f44b

Browse files
authored
fix(core): fix TrayIcon.getById returning new resource IDs (#13307)
* fix(core): fix TrayIcon.getById returning new resource IDs this prevents the close() from working properly if you somehow lose the new() resource ID (for instance when the app reloads) and need to pick it up again and close it. * cleanup on close
1 parent 00dfc32 commit 039f44b

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

.changes/fix-tray-get-by-id.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch:bug
3+
---
4+
5+
Fix `TrayIcon.getById` returning a new resource ID instead of reusing a previously created id from `TrayIcon.new`.

crates/tauri/src/tray/mod.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,13 @@ impl<R: Runtime> TrayIcon<R> {
598598

599599
impl<R: Runtime> Resource for TrayIcon<R> {
600600
fn close(self: std::sync::Arc<Self>) {
601+
self
602+
.app_handle
603+
.state::<plugin::TrayIcons>()
604+
.icons
605+
.lock()
606+
.unwrap()
607+
.remove(&self.id.0);
601608
self.app_handle.remove_tray_by_id(&self.id);
602609
}
603610
}

crates/tauri/src/tray/plugin.rs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
// SPDX-License-Identifier: MIT
44

5-
use std::path::PathBuf;
5+
use std::{collections::HashMap, path::PathBuf, sync::Mutex};
66

77
use serde::Deserialize;
88

@@ -14,11 +14,15 @@ use crate::{
1414
plugin::{Builder, TauriPlugin},
1515
resources::ResourceId,
1616
tray::TrayIconBuilder,
17-
AppHandle, Manager, Runtime, Webview,
17+
AppHandle, Manager, Runtime, State, Webview,
1818
};
1919

2020
use super::{TrayIcon, TrayIconEvent};
2121

22+
pub(crate) struct TrayIcons {
23+
pub(crate) icons: Mutex<HashMap<String, ResourceId>>,
24+
}
25+
2226
#[derive(Deserialize)]
2327
#[serde(rename_all = "camelCase")]
2428
struct TrayIconOptions {
@@ -36,6 +40,7 @@ struct TrayIconOptions {
3640
#[command(root = "crate")]
3741
fn new<R: Runtime>(
3842
webview: Webview<R>,
43+
icons: State<'_, TrayIcons>,
3944
options: TrayIconOptions,
4045
handler: Channel<TrayIconEvent>,
4146
) -> crate::Result<(ResourceId, String)> {
@@ -91,20 +96,35 @@ fn new<R: Runtime>(
9196
let id = tray.id().as_ref().to_string();
9297
let rid = resources_table.add(tray);
9398

99+
icons.icons.lock().unwrap().insert(id.clone(), rid);
100+
94101
Ok((rid, id))
95102
}
96103

97104
#[command(root = "crate")]
98105
fn get_by_id<R: Runtime>(
99106
app: AppHandle<R>,
100107
webview: Webview<R>,
108+
icons: State<'_, TrayIcons>,
101109
id: &str,
102110
) -> crate::Result<Option<ResourceId>> {
111+
// if the icon was created by this plugin, return the resource id
112+
// this lets a getById call match the rid of a TrayIcon.new call
113+
// which allows it to close a previously created icon
114+
if let Some(rid) = icons.icons.lock().unwrap().get(id) {
115+
return Ok(Some(*rid));
116+
}
117+
103118
let tray = app.tray_by_id(id);
104119
let maybe_rid = tray.map(|tray| {
105120
let mut resources_table = webview.resources_table();
106121
resources_table.add(tray)
107122
});
123+
124+
if let Some(rid) = maybe_rid {
125+
icons.icons.lock().unwrap().insert(id.to_string(), rid);
126+
}
127+
108128
Ok(maybe_rid)
109129
}
110130

@@ -226,6 +246,12 @@ fn set_show_menu_on_left_click<R: Runtime>(
226246

227247
pub(crate) fn init<R: Runtime>() -> TauriPlugin<R> {
228248
Builder::new("tray")
249+
.setup(|app, _api| {
250+
app.manage(TrayIcons {
251+
icons: Default::default(),
252+
});
253+
Ok(())
254+
})
229255
.invoke_handler(crate::generate_handler![
230256
#![plugin(tray)]
231257
new,

0 commit comments

Comments
 (0)