fix: #2502 Expose set_menu from tao through the TrayHandle struct (#2532)

Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
This commit is contained in:
Fausto Núñez Alberro 2021-10-02 20:57:53 +02:00 committed by GitHub
parent 170b96b3f3
commit 0e4d12b541
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 57 additions and 11 deletions

View File

@ -0,0 +1,5 @@
---
"tauri": patch
---
Add `set_menu` API on `tauri::SystemTrayHandle`.

View File

@ -989,6 +989,7 @@ pub enum WebviewEvent {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum TrayMessage { pub enum TrayMessage {
UpdateItem(u16, MenuUpdate), UpdateItem(u16, MenuUpdate),
UpdateMenu(SystemTrayMenu),
UpdateIcon(Icon), UpdateIcon(Icon),
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
UpdateIconAsTemplate(bool), UpdateIconAsTemplate(bool),
@ -2116,6 +2117,16 @@ fn handle_user_message(
} }
} }
} }
TrayMessage::UpdateMenu(menu) => {
if let Some(tray) = &*tray_context.tray.lock().unwrap() {
let mut items = HashMap::new();
tray
.lock()
.unwrap()
.set_menu(&to_wry_context_menu(&mut items, menu));
*tray_context.items.lock().unwrap() = items;
}
}
TrayMessage::UpdateIcon(icon) => { TrayMessage::UpdateIcon(icon) => {
if let Some(tray) = &*tray_context.tray.lock().unwrap() { if let Some(tray) = &*tray_context.tray.lock().unwrap() {
tray.lock().unwrap().set_icon(icon.into_tray_icon()); tray.lock().unwrap().set_icon(icon.into_tray_icon());

View File

@ -47,6 +47,12 @@ impl TrayHandle for SystemTrayHandle {
.send_event(Message::Tray(TrayMessage::UpdateIcon(icon))) .send_event(Message::Tray(TrayMessage::UpdateIcon(icon)))
.map_err(|_| Error::FailedToSendMessage) .map_err(|_| Error::FailedToSendMessage)
} }
fn set_menu(&self, menu: SystemTrayMenu) -> Result<()> {
self
.proxy
.send_event(Message::Tray(TrayMessage::UpdateMenu(menu)))
.map_err(|_| Error::FailedToSendMessage)
}
fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> { fn update_item(&self, id: u16, update: MenuUpdate) -> Result<()> {
self self
.proxy .proxy

View File

@ -148,6 +148,7 @@ pub enum MenuUpdate {
pub trait TrayHandle: fmt::Debug { pub trait TrayHandle: fmt::Debug {
fn set_icon(&self, icon: crate::Icon) -> crate::Result<()>; fn set_icon(&self, icon: crate::Icon) -> crate::Result<()>;
fn set_menu(&self, menu: crate::menu::SystemTrayMenu) -> crate::Result<()>;
fn update_item(&self, id: u16, update: MenuUpdate) -> crate::Result<()>; fn update_item(&self, id: u16, update: MenuUpdate) -> crate::Result<()>;
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()>; fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()>;

View File

@ -129,6 +129,11 @@ impl<R: Runtime> SystemTrayHandle<R> {
self.inner.set_icon(icon).map_err(Into::into) self.inner.set_icon(icon).map_err(Into::into)
} }
/// Updates the tray menu.
pub fn set_menu(&self, menu: SystemTrayMenu) -> crate::Result<()> {
self.inner.set_menu(menu).map_err(Into::into)
}
/// Support [macOS tray icon template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) to adjust automatically based on taskbar color. /// Support [macOS tray icon template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) to adjust automatically based on taskbar color.
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()> { pub fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()> {

View File

@ -12,6 +12,7 @@ mod menu;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tauri::{ use tauri::{
@ -42,6 +43,20 @@ async fn menu_toggle(window: tauri::Window) {
} }
fn main() { fn main() {
let tray_menu1 = SystemTrayMenu::new()
.add_item(CustomMenuItem::new("toggle", "Toggle"))
.add_item(CustomMenuItem::new("new", "New window"))
.add_item(CustomMenuItem::new("icon_1", "Tray Icon 1"))
.add_item(CustomMenuItem::new("icon_2", "Tray Icon 2"))
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
.add_item(CustomMenuItem::new("exit_app", "Quit"));
let tray_menu2 = SystemTrayMenu::new()
.add_item(CustomMenuItem::new("toggle", "Toggle"))
.add_item(CustomMenuItem::new("new", "New window"))
.add_item(CustomMenuItem::new("switch_menu", "Switch Menu"))
.add_item(CustomMenuItem::new("exit_app", "Quit"));
let is_menu1 = AtomicBool::new(true);
#[allow(unused_mut)] #[allow(unused_mut)]
let mut app = tauri::Builder::default() let mut app = tauri::Builder::default()
.on_page_load(|window, _| { .on_page_load(|window, _| {
@ -79,17 +94,8 @@ fn main() {
.on_menu_event(|event| { .on_menu_event(|event| {
println!("{:?}", event.menu_item_id()); println!("{:?}", event.menu_item_id());
}) })
.system_tray( .system_tray(SystemTray::new().with_menu(tray_menu1.clone()))
SystemTray::new().with_menu( .on_system_tray_event(move |app, event| match event {
SystemTrayMenu::new()
.add_item(CustomMenuItem::new("toggle", "Toggle"))
.add_item(CustomMenuItem::new("new", "New window"))
.add_item(CustomMenuItem::new("icon_1", "Tray Icon 1"))
.add_item(CustomMenuItem::new("icon_2", "Tray Icon 2"))
.add_item(CustomMenuItem::new("exit_app", "Quit")),
),
)
.on_system_tray_event(|app, event| match event {
SystemTrayEvent::LeftClick { SystemTrayEvent::LeftClick {
position: _, position: _,
size: _, size: _,
@ -176,6 +182,18 @@ fn main() {
include_bytes!("../../../.icons/icon.ico").to_vec(), include_bytes!("../../../.icons/icon.ico").to_vec(),
)) ))
.unwrap(), .unwrap(),
"switch_menu" => {
let flag = is_menu1.load(Ordering::Relaxed);
app
.tray_handle()
.set_menu(if flag {
tray_menu2.clone()
} else {
tray_menu1.clone()
})
.unwrap();
is_menu1.store(!flag, Ordering::Relaxed);
}
_ => {} _ => {}
} }
} }