Skip to content

Commit 0e4d12b

Browse files
fnunelucasfernog
andauthored
fix: #2502 Expose set_menu from tao through the TrayHandle struct (#2532)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent 170b96b commit 0e4d12b

6 files changed

Lines changed: 57 additions & 11 deletions

File tree

.changes/tray-set-menu.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch
3+
---
4+
5+
Add `set_menu` API on `tauri::SystemTrayHandle`.

core/tauri-runtime-wry/src/lib.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,7 @@ pub enum WebviewEvent {
989989
#[derive(Debug, Clone)]
990990
pub enum TrayMessage {
991991
UpdateItem(u16, MenuUpdate),
992+
UpdateMenu(SystemTrayMenu),
992993
UpdateIcon(Icon),
993994
#[cfg(target_os = "macos")]
994995
UpdateIconAsTemplate(bool),
@@ -2116,6 +2117,16 @@ fn handle_user_message(
21162117
}
21172118
}
21182119
}
2120+
TrayMessage::UpdateMenu(menu) => {
2121+
if let Some(tray) = &*tray_context.tray.lock().unwrap() {
2122+
let mut items = HashMap::new();
2123+
tray
2124+
.lock()
2125+
.unwrap()
2126+
.set_menu(&to_wry_context_menu(&mut items, menu));
2127+
*tray_context.items.lock().unwrap() = items;
2128+
}
2129+
}
21192130
TrayMessage::UpdateIcon(icon) => {
21202131
if let Some(tray) = &*tray_context.tray.lock().unwrap() {
21212132
tray.lock().unwrap().set_icon(icon.into_tray_icon());

core/tauri-runtime-wry/src/system_tray.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ impl TrayHandle for SystemTrayHandle {
4747
.send_event(Message::Tray(TrayMessage::UpdateIcon(icon)))
4848
.map_err(|_| Error::FailedToSendMessage)
4949
}
50+
fn set_menu(&self, menu: SystemTrayMenu) -> Result<()> {
51+
self
52+
.proxy
53+
.send_event(Message::Tray(TrayMessage::UpdateMenu(menu)))
54+
.map_err(|_| Error::FailedToSendMessage)
55+
}
5056
fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> {
5157
self
5258
.proxy

core/tauri-runtime/src/menu.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ pub enum MenuUpdate {
148148

149149
pub trait TrayHandle: fmt::Debug {
150150
fn set_icon(&self, icon: crate::Icon) -> crate::Result<()>;
151+
fn set_menu(&self, menu: crate::menu::SystemTrayMenu) -> crate::Result<()>;
151152
fn update_item(&self, id: u16, update: MenuUpdate) -> crate::Result<()>;
152153
#[cfg(target_os = "macos")]
153154
fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()>;

core/tauri/src/app/tray.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,11 @@ impl<R: Runtime> SystemTrayHandle<R> {
129129
self.inner.set_icon(icon).map_err(Into::into)
130130
}
131131

132+
/// Updates the tray menu.
133+
pub fn set_menu(&self, menu: SystemTrayMenu) -> crate::Result<()> {
134+
self.inner.set_menu(menu).map_err(Into::into)
135+
}
136+
132137
/// Support [macOS tray icon template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) to adjust automatically based on taskbar color.
133138
#[cfg(target_os = "macos")]
134139
pub fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()> {

examples/api/src-tauri/src/main.rs

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod menu;
1212

1313
#[cfg(target_os = "linux")]
1414
use std::path::PathBuf;
15+
use std::sync::atomic::{AtomicBool, Ordering};
1516

1617
use serde::{Deserialize, Serialize};
1718
use tauri::{
@@ -42,6 +43,20 @@ async fn menu_toggle(window: tauri::Window) {
4243
}
4344

4445
fn main() {
46+
let tray_menu1 = SystemTrayMenu::new()
47+
.add_item(CustomMenuItem::new("toggle", "Toggle"))
48+
.add_item(CustomMenuItem::new("new", "New window"))
49+
.add_item(CustomMenuItem::new("icon_1", "Tray Icon 1"))
50+
.add_item(CustomMenuItem::new("icon_2", "Tray Icon 2"))
51+
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
52+
.add_item(CustomMenuItem::new("exit_app", "Quit"));
53+
let tray_menu2 = SystemTrayMenu::new()
54+
.add_item(CustomMenuItem::new("toggle", "Toggle"))
55+
.add_item(CustomMenuItem::new("new", "New window"))
56+
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
57+
.add_item(CustomMenuItem::new("exit_app", "Quit"));
58+
let is_menu1 = AtomicBool::new(true);
59+
4560
#[allow(unused_mut)]
4661
let mut app = tauri::Builder::default()
4762
.on_page_load(|window, _| {
@@ -79,17 +94,8 @@ fn main() {
7994
.on_menu_event(|event| {
8095
println!("{:?}", event.menu_item_id());
8196
})
82-
.system_tray(
83-
SystemTray::new().with_menu(
84-
SystemTrayMenu::new()
85-
.add_item(CustomMenuItem::new("toggle", "Toggle"))
86-
.add_item(CustomMenuItem::new("new", "New window"))
87-
.add_item(CustomMenuItem::new("icon_1", "Tray Icon 1"))
88-
.add_item(CustomMenuItem::new("icon_2", "Tray Icon 2"))
89-
.add_item(CustomMenuItem::new("exit_app", "Quit")),
90-
),
91-
)
92-
.on_system_tray_event(|app, event| match event {
97+
.system_tray(SystemTray::new().with_menu(tray_menu1.clone()))
98+
.on_system_tray_event(move |app, event| match event {
9399
SystemTrayEvent::LeftClick {
94100
position: _,
95101
size: _,
@@ -176,6 +182,18 @@ fn main() {
176182
include_bytes!("../../../.icons/icon.ico").to_vec(),
177183
))
178184
.unwrap(),
185+
"switch_menu" => {
186+
let flag = is_menu1.load(Ordering::Relaxed);
187+
app
188+
.tray_handle()
189+
.set_menu(if flag {
190+
tray_menu2.clone()
191+
} else {
192+
tray_menu1.clone()
193+
})
194+
.unwrap();
195+
is_menu1.store(!flag, Ordering::Relaxed);
196+
}
179197
_ => {}
180198
}
181199
}

0 commit comments

Comments
 (0)