Skip to content

Commit c4410da

Browse files
feat(tray): add enter, move and leave events (#9777)
* feat(tray): add `enter`, `move` and `leave` events closes #8584 * update api example * check button state [skip ci] * fix enum [skip ci] --------- Co-authored-by: Lucas Nogueira <lucas@tauri.studio> Co-authored-by: Lucas Nogueira <lucas@tauri.app>
1 parent 276c4b1 commit c4410da

File tree

8 files changed

+229
-77
lines changed

8 files changed

+229
-77
lines changed

.changes/tray-icon-event.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"tauri": "patch:breaking"
3+
"@tauri-apps/api": "patch:breaking"
4+
---
5+
6+
This release contains breaking changes to the tray event structure because of newly added events:
7+
- Changed `TrayIconEvent` to be an enum instead of a struct.
8+
- Added `MouseButtonState` and `MouseButton` enums.
9+
- Removed `ClickType` enum and replaced it with `MouseButton` enum.
10+
- Added `MouseButtonState` enum.

Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/tauri/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ specta = { version = "^2.0.0-rc.9", optional = true, default-features = false, f
7979

8080
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\", target_os = \"windows\", target_os = \"macos\"))".dependencies]
8181
muda = { version = "0.13.4", default-features = false, features = [ "serde" ] }
82-
tray-icon = { version = "0.13", default-features = false, features = [ "serde" ], optional = true }
82+
tray-icon = { version = "0.14", default-features = false, features = [ "serde" ], optional = true }
8383

8484
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
8585
gtk = { version = "0.18", features = [ "v3_24" ] }

core/tauri/src/app.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1947,7 +1947,7 @@ fn on_event_loop_event<R: Runtime>(
19471947
}
19481948

19491949
for (id, listener) in &*app_handle.manager.tray.event_listeners.lock().unwrap() {
1950-
if e.id == id {
1950+
if e.id() == id {
19511951
if let Some(tray) = app_handle.tray_by_id(id) {
19521952
listener(&tray, e.clone());
19531953
}

core/tauri/src/tray/mod.rs

+134-38
Original file line numberDiff line numberDiff line change
@@ -19,69 +19,165 @@ use serde::Serialize;
1919
use std::path::Path;
2020
pub use tray_icon::TrayIconId;
2121

22-
/// Describes the click type that triggered this tray icon event.
22+
/// Describes the mouse button state.
2323
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize)]
24-
pub enum ClickType {
25-
/// Left mouse click.
24+
pub enum MouseButtonState {
25+
/// Mouse button pressed.
26+
Up,
27+
/// Mouse button released.
28+
Down,
29+
}
30+
31+
impl Default for MouseButtonState {
32+
fn default() -> Self {
33+
Self::Up
34+
}
35+
}
36+
37+
impl From<tray_icon::MouseButtonState> for MouseButtonState {
38+
fn from(value: tray_icon::MouseButtonState) -> Self {
39+
match value {
40+
tray_icon::MouseButtonState::Up => MouseButtonState::Up,
41+
tray_icon::MouseButtonState::Down => MouseButtonState::Down,
42+
}
43+
}
44+
}
45+
46+
/// Describes which mouse button triggered the event..
47+
#[derive(Clone, Copy, PartialEq, Eq, Debug, Serialize)]
48+
pub enum MouseButton {
49+
/// Left mouse button.
2650
Left,
27-
/// Right mouse click.
51+
/// Right mouse button.
2852
Right,
29-
/// Double left mouse click.
30-
Double,
53+
/// Middle mouse button.
54+
Middle,
3155
}
3256

33-
impl Default for ClickType {
57+
impl Default for MouseButton {
3458
fn default() -> Self {
3559
Self::Left
3660
}
3761
}
3862

39-
/// Describes a tray event emitted when a tray icon is clicked
63+
impl From<tray_icon::MouseButton> for MouseButton {
64+
fn from(value: tray_icon::MouseButton) -> Self {
65+
match value {
66+
tray_icon::MouseButton::Left => MouseButton::Left,
67+
tray_icon::MouseButton::Right => MouseButton::Right,
68+
tray_icon::MouseButton::Middle => MouseButton::Middle,
69+
}
70+
}
71+
}
72+
73+
/// Describes a tray icon event.
4074
///
4175
/// ## Platform-specific:
4276
///
43-
/// - **Linux**: Unsupported. The event is not emitted even though the icon is shown,
44-
/// the icon will still show a context menu on right click.
45-
#[derive(Debug, Clone, Default, Serialize)]
77+
/// - **Linux**: Unsupported. The event is not emmited even though the icon is shown
78+
/// and will still show a context menu on right click.
79+
#[derive(Debug, Clone, Serialize)]
4680
#[serde(rename_all = "camelCase")]
47-
pub struct TrayIconEvent {
48-
/// Id of the tray icon which triggered this event.
49-
pub id: TrayIconId,
50-
/// Physical Position of the click the triggered this event.
51-
pub position: PhysicalPosition<f64>,
52-
/// Position and size of the tray icon
53-
pub icon_rect: Rect,
54-
/// The click type that triggered this event.
55-
pub click_type: ClickType,
81+
#[non_exhaustive]
82+
pub enum TrayIconEvent {
83+
/// A click happened on the tray icon.
84+
Click {
85+
/// Id of the tray icon which triggered this event.
86+
id: TrayIconId,
87+
/// Physical Position of this event.
88+
position: PhysicalPosition<f64>,
89+
/// Position and size of the tray icon.
90+
rect: Rect,
91+
/// Mouse button that triggered this event.
92+
button: MouseButton,
93+
/// Mouse button state when this event was triggered.
94+
button_state: MouseButtonState,
95+
},
96+
/// The mouse entered the tray icon region.
97+
Enter {
98+
/// Id of the tray icon which triggered this event.
99+
id: TrayIconId,
100+
/// Physical Position of this event.
101+
position: PhysicalPosition<f64>,
102+
/// Position and size of the tray icon.
103+
rect: Rect,
104+
},
105+
/// The mouse moved over the tray icon region.
106+
Move {
107+
/// Id of the tray icon which triggered this event.
108+
id: TrayIconId,
109+
/// Physical Position of this event.
110+
position: PhysicalPosition<f64>,
111+
/// Position and size of the tray icon.
112+
rect: Rect,
113+
},
114+
/// The mouse left the tray icon region.
115+
Leave {
116+
/// Id of the tray icon which triggered this event.
117+
id: TrayIconId,
118+
/// Physical Position of this event.
119+
position: PhysicalPosition<f64>,
120+
/// Position and size of the tray icon.
121+
rect: Rect,
122+
},
56123
}
57124

58125
impl TrayIconEvent {
59-
/// Returns the id of the tray icon which triggered this event.
126+
/// Get the id of the tray icon that triggered this event.
60127
pub fn id(&self) -> &TrayIconId {
61-
&self.id
62-
}
63-
}
64-
65-
impl From<tray_icon::ClickType> for ClickType {
66-
fn from(value: tray_icon::ClickType) -> Self {
67-
match value {
68-
tray_icon::ClickType::Left => Self::Left,
69-
tray_icon::ClickType::Right => Self::Right,
70-
tray_icon::ClickType::Double => Self::Double,
128+
match self {
129+
TrayIconEvent::Click { id, .. } => id,
130+
TrayIconEvent::Enter { id, .. } => id,
131+
TrayIconEvent::Move { id, .. } => id,
132+
TrayIconEvent::Leave { id, .. } => id,
71133
}
72134
}
73135
}
74136

75137
impl From<tray_icon::TrayIconEvent> for TrayIconEvent {
76138
fn from(value: tray_icon::TrayIconEvent) -> Self {
77-
Self {
78-
id: value.id,
79-
position: value.position,
80-
icon_rect: Rect {
81-
position: value.icon_rect.position.into(),
82-
size: value.icon_rect.size.into(),
139+
match value {
140+
tray_icon::TrayIconEvent::Click {
141+
id,
142+
position,
143+
rect,
144+
button,
145+
button_state,
146+
} => TrayIconEvent::Click {
147+
id,
148+
position,
149+
rect: Rect {
150+
position: rect.position.into(),
151+
size: rect.size.into(),
152+
},
153+
button: button.into(),
154+
button_state: button_state.into(),
155+
},
156+
tray_icon::TrayIconEvent::Enter { id, position, rect } => TrayIconEvent::Enter {
157+
id,
158+
position,
159+
rect: Rect {
160+
position: rect.position.into(),
161+
size: rect.size.into(),
162+
},
163+
},
164+
tray_icon::TrayIconEvent::Move { id, position, rect } => TrayIconEvent::Move {
165+
id,
166+
position,
167+
rect: Rect {
168+
position: rect.position.into(),
169+
size: rect.size.into(),
170+
},
171+
},
172+
tray_icon::TrayIconEvent::Leave { id, position, rect } => TrayIconEvent::Leave {
173+
id,
174+
position,
175+
rect: Rect {
176+
position: rect.position.into(),
177+
size: rect.size.into(),
178+
},
83179
},
84-
click_type: value.click_type.into(),
180+
_ => todo!(),
85181
}
86182
}
87183
}

examples/api/src-tauri/Cargo.lock

+2-13
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use std::sync::atomic::{AtomicBool, Ordering};
66
use tauri::{
77
menu::{Menu, MenuItem},
8-
tray::{ClickType, TrayIconBuilder},
8+
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
99
Manager, Runtime, WebviewUrl,
1010
};
1111

@@ -108,7 +108,12 @@ pub fn create_tray<R: Runtime>(app: &tauri::AppHandle<R>) -> tauri::Result<()> {
108108
_ => {}
109109
})
110110
.on_tray_icon_event(|tray, event| {
111-
if event.click_type == ClickType::Left {
111+
if let TrayIconEvent::Click {
112+
button: MouseButton::Left,
113+
button_state: MouseButtonState::Up,
114+
..
115+
} = event
116+
{
112117
let app = tray.app_handle();
113118
if let Some(window) = app.get_webview_window("main") {
114119
let _ = window.show();

0 commit comments

Comments
 (0)