1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use crate::{
Error, Icon, MenuBuilder, TrayIconBase, TrayIconBuilder, TrayIconEvent, TrayIconStatus,
};
pub struct TrayIcon<T>
where
T: TrayIconEvent,
{
sys: crate::TrayIconSys<T>,
builder: TrayIconBuilder<T>,
}
impl<T> TrayIcon<T>
where
T: TrayIconEvent,
{
pub(crate) fn new(sys: crate::TrayIconSys<T>, builder: TrayIconBuilder<T>) -> TrayIcon<T> {
TrayIcon { builder, sys }
}
/// Set the icon if changed
pub fn set_icon(&mut self, icon: &Icon) -> Result<(), Error> {
if self.builder.icon.as_ref() == Ok(icon) {
return Ok(());
}
self.builder.icon = Ok(icon.clone());
self.sys.set_icon(icon)
}
/// Set the menu if changed
///
/// This can be used reactively, each time the application state changes,
/// build a new menu and set it with this method. This way one can avoid
/// using more imperative `set_item_checkable`, `get_item_checkable` and
/// `set_item_disabled` methods.
pub fn set_menu(&mut self, menu: &MenuBuilder<T>) -> Result<(), Error> {
if self.builder.menu.as_ref() == Some(menu) {
return Ok(());
}
self.builder.menu = Some(menu.clone());
self.sys.set_menu(menu)
}
/// Set the tooltip if changed
pub fn set_tooltip(&mut self, tooltip: &str) -> Result<(), Error> {
if self.builder.tooltip.as_deref() == Some(tooltip) {
return Ok(());
}
self.builder.tooltip = Some(tooltip.to_string());
self.sys.set_tooltip(tooltip)
}
/// Set the title (KDE only)
///
/// Used in KDE as the application title for the tray icon (Title property).
/// On other platforms, this does nothing.
pub fn set_title(&mut self, title: &str) -> Result<(), Error> {
if self.builder.title.as_deref() == Some(title) {
return Ok(());
}
self.builder.title = Some(title.to_string());
self.sys.set_title(title)
}
/// Set disabled
///
/// Prefer building a new menu if application state changes instead of
/// mutating a menu with this method. Suggestion is to use just `set_menu`
/// method instead of this.
pub fn set_menu_item_disabled(&mut self, id: T, disabled: bool) -> Result<(), Error> {
if let Some(menu) = self.builder.menu.as_mut() {
let _ = menu.set_disabled(id, disabled);
let _ = self.sys.set_menu(menu);
}
Ok(())
}
/// Set checkable
///
/// Prefer building a new menu when application state changes instead of
/// mutating a menu with this method. Suggestion is to use just `set_menu`
/// method instead of this.
pub fn set_menu_item_checkable(&mut self, id: T, checked: bool) -> Result<(), Error> {
if let Some(menu) = self.builder.menu.as_mut() {
let _ = menu.set_checkable(id, checked);
let _ = self.sys.set_menu(menu);
}
Ok(())
}
/// Get checkable state
///
/// Prefer maintaining proper application state instead of getting checkable
/// state with this method. Suggestion is to use just `set_menu` method
/// instead of this.
pub fn get_menu_item_checkable(&mut self, id: T) -> Option<bool> {
if let Some(menu) = self.builder.menu.as_mut() {
menu.get_checkable(id)
} else {
None
}
}
/// Show the menu (Windows only)
///
/// On KDE and MacOS right click by default opens the menu, there is no programmatic way to open it.
pub fn show_menu(&mut self) -> Result<(), Error> {
self.sys.show_menu()
}
/// Set the status of the tray icon (KDE only)
///
/// On KDE, this controls the StatusNotifierItem status:
/// - Active: Normal visible state
/// - NeedsAttention: Icon blinks/animates to draw attention
/// - Passive: Icon is hidden or minimized
///
/// On other platforms, this does nothing by default.
pub fn set_status(&mut self, status: TrayIconStatus) -> Result<(), Error> {
self.sys.set_status(status)
}
/// Get the XDG activation token (KDE only)
pub fn get_xdg_activation_token(&self) -> Option<String> {
self.sys.get_xdg_activation_token()
}
}
unsafe impl<T> Sync for TrayIcon<T> where T: TrayIconEvent {}
unsafe impl<T> Send for TrayIcon<T> where T: TrayIconEvent {}