pub use crate::runtime::{
menu::{
MenuHash, MenuId, MenuIdRef, MenuUpdate, SystemTrayMenu, SystemTrayMenuEntry, TrayHandle,
},
window::dpi::{PhysicalPosition, PhysicalSize},
Icon, Runtime, SystemTray,
};
use tauri_macros::default_runtime;
use std::{collections::HashMap, sync::Arc};
pub(crate) fn get_menu_ids(map: &mut HashMap<MenuHash, MenuId>, menu: &SystemTrayMenu) {
for item in &menu.items {
match item {
SystemTrayMenuEntry::CustomItem(c) => {
map.insert(c.id, c.id_str.clone());
}
SystemTrayMenuEntry::Submenu(s) => get_menu_ids(map, &s.inner),
_ => {}
}
}
}
#[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))]
#[non_exhaustive]
pub enum SystemTrayEvent {
#[non_exhaustive]
MenuItemClick {
id: MenuId,
},
#[non_exhaustive]
LeftClick {
position: PhysicalPosition<f64>,
size: PhysicalSize<f64>,
},
#[non_exhaustive]
RightClick {
position: PhysicalPosition<f64>,
size: PhysicalSize<f64>,
},
#[non_exhaustive]
DoubleClick {
position: PhysicalPosition<f64>,
size: PhysicalSize<f64>,
},
}
#[default_runtime(crate::Wry, wry)]
#[derive(Debug)]
pub struct SystemTrayHandle<R: Runtime> {
pub(crate) ids: Arc<HashMap<MenuHash, MenuId>>,
pub(crate) inner: R::TrayHandler,
}
impl<R: Runtime> Clone for SystemTrayHandle<R> {
fn clone(&self) -> Self {
Self {
ids: self.ids.clone(),
inner: self.inner.clone(),
}
}
}
#[default_runtime(crate::Wry, wry)]
#[derive(Debug)]
pub struct SystemTrayMenuItemHandle<R: Runtime> {
id: MenuHash,
tray_handler: R::TrayHandler,
}
impl<R: Runtime> Clone for SystemTrayMenuItemHandle<R> {
fn clone(&self) -> Self {
Self {
id: self.id,
tray_handler: self.tray_handler.clone(),
}
}
}
impl<R: Runtime> SystemTrayHandle<R> {
pub fn get_item(&self, id: MenuIdRef<'_>) -> SystemTrayMenuItemHandle<R> {
for (raw, item_id) in self.ids.iter() {
if item_id == id {
return SystemTrayMenuItemHandle {
id: *raw,
tray_handler: self.inner.clone(),
};
}
}
panic!("item id not found")
}
pub fn set_icon(&self, icon: Icon) -> crate::Result<()> {
self.inner.set_icon(icon).map_err(Into::into)
}
pub fn set_menu(&self, menu: SystemTrayMenu) -> crate::Result<()> {
self.inner.set_menu(menu).map_err(Into::into)
}
#[cfg(target_os = "macos")]
pub fn set_icon_as_template(&self, is_template: bool) -> crate::Result<()> {
self
.inner
.set_icon_as_template(is_template)
.map_err(Into::into)
}
}
impl<R: Runtime> SystemTrayMenuItemHandle<R> {
pub fn set_enabled(&self, enabled: bool) -> crate::Result<()> {
self
.tray_handler
.update_item(self.id, MenuUpdate::SetEnabled(enabled))
.map_err(Into::into)
}
pub fn set_title<S: Into<String>>(&self, title: S) -> crate::Result<()> {
self
.tray_handler
.update_item(self.id, MenuUpdate::SetTitle(title.into()))
.map_err(Into::into)
}
pub fn set_selected(&self, selected: bool) -> crate::Result<()> {
self
.tray_handler
.update_item(self.id, MenuUpdate::SetSelected(selected))
.map_err(Into::into)
}
#[cfg(target_os = "macos")]
#[cfg_attr(doc_cfg, doc(cfg(target_os = "macos")))]
pub fn set_native_image(&self, image: crate::NativeImage) -> crate::Result<()> {
self
.tray_handler
.update_item(self.id, MenuUpdate::SetNativeImage(image))
.map_err(Into::into)
}
}