Skip to content

Commit 0b44959

Browse files
refactor!: simplify TrayIconEvent in JS by tagging it with type field (#11121)
Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>
1 parent 544328d commit 0b44959

File tree

8 files changed

+108
-128
lines changed

8 files changed

+108
-128
lines changed

.changes/api-tray-doubleClick-event.md

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"tauri": "patch:breaking"
3+
"@tauri-apps/api": "patch:breaking"
4+
---
5+
6+
Simplified emitted tray event JS value and updated `TrayIconEvent` type definition to match it.
7+

.changes/api-tray-icon-event-value-mismatch-type.md

Lines changed: 0 additions & 6 deletions
This file was deleted.

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ specta = { version = "^2.0.0-rc.16", optional = true, default-features = false,
9292

9393
[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]
9494
muda = { version = "0.15", default-features = false, features = ["serde"] }
95-
tray-icon = { version = "0.18", default-features = false, features = [
95+
tray-icon = { version = "0.19", default-features = false, features = [
9696
"serde",
9797
], optional = true }
9898

crates/tauri/scripts/bundle.global.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/tauri/src/tray/mod.rs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ impl From<tray_icon::MouseButton> for MouseButton {
7575
/// - **Linux**: Unsupported. The event is not emmited even though the icon is shown
7676
/// and will still show a context menu on right click.
7777
#[derive(Debug, Clone, Serialize)]
78-
#[serde(rename_all = "camelCase")]
78+
#[serde(tag = "type")]
7979
#[non_exhaustive]
8080
pub enum TrayIconEvent {
8181
/// A click happened on the tray icon.
@@ -563,3 +563,52 @@ impl<R: Runtime> Resource for TrayIcon<R> {
563563
self.app_handle.remove_tray_by_id(&self.id);
564564
}
565565
}
566+
567+
#[cfg(test)]
568+
mod tests {
569+
#[test]
570+
fn tray_event_json_serialization() {
571+
// NOTE: if this test is ever changed, you probably need to change `TrayIconEvent` in JS as well
572+
573+
use super::*;
574+
let event = TrayIconEvent::Click {
575+
button: MouseButton::Left,
576+
button_state: MouseButtonState::Down,
577+
id: TrayIconId::new("id"),
578+
position: crate::PhysicalPosition::default(),
579+
rect: crate::Rect {
580+
position: tray_icon::Rect::default().position.into(),
581+
size: tray_icon::Rect::default().size.into(),
582+
},
583+
};
584+
585+
let value = serde_json::to_value(&event).unwrap();
586+
assert_eq!(
587+
value,
588+
serde_json::json!({
589+
"type": "Click",
590+
"button": "Left",
591+
"buttonState": "Down",
592+
"id": "id",
593+
"position": {
594+
"x": 0.0,
595+
"y": 0.0,
596+
},
597+
"rect": {
598+
"size": {
599+
"Physical": {
600+
"width": 0,
601+
"height": 0,
602+
}
603+
},
604+
"position": {
605+
"Physical": {
606+
"x": 0,
607+
"y": 0,
608+
}
609+
},
610+
}
611+
})
612+
);
613+
}
614+
}

packages/api/src/tray.ts

Lines changed: 47 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -9,86 +9,32 @@ import { PhysicalPosition, PhysicalSize } from './dpi'
99

1010
export type MouseButtonState = 'Up' | 'Down'
1111
export type MouseButton = 'Left' | 'Right' | 'Middle'
12+
export type TrayIconEventType =
13+
| 'Click'
14+
| 'DoubleClick'
15+
| 'Enter'
16+
| 'Move'
17+
| 'Leave'
1218

13-
/** A click happened on the tray icon. */
14-
export interface TrayIconClickEvent {
19+
export type TrayIconEventBase<T extends TrayIconEventType> = {
20+
/** The tray icon event type */
21+
type: T
1522
/** Id of the tray icon which triggered this event. */
1623
id: string
17-
/** Physical X Position of the click the triggered this event. */
18-
x: number
19-
/** Physical Y Position of the click the triggered this event. */
20-
y: number
24+
/** Physical position of the click the triggered this event. */
25+
position: PhysicalPosition
2126
/** Position and size of the tray icon. */
2227
rect: {
2328
position: PhysicalPosition
2429
size: PhysicalSize
2530
}
26-
/** Mouse button that triggered this event. */
27-
button: MouseButton
28-
/** Mouse button state when this event was triggered. */
29-
buttonState: MouseButtonState
3031
}
3132

32-
/** A double click happened on the tray icon. **Windows Only** */
33-
export interface TrayIconDoubleClickEvent {
34-
/** Id of the tray icon which triggered this event. */
35-
id: string
36-
/** Physical X Position of the click the triggered this event. */
37-
x: number
38-
/** Physical Y Position of the click the triggered this event. */
39-
y: number
40-
/** Position and size of the tray icon. */
41-
rect: {
42-
position: PhysicalPosition
43-
size: PhysicalSize
44-
}
33+
export type TrayIconClickEvent = {
4534
/** Mouse button that triggered this event. */
4635
button: MouseButton
47-
}
48-
49-
/** The mouse entered the tray icon region. */
50-
export interface TrayIconEnterEvent {
51-
/** Id of the tray icon which triggered this event. */
52-
id: string
53-
/** Physical X Position of the click the triggered this event. */
54-
x: number
55-
/** Physical Y Position of the click the triggered this event. */
56-
y: number
57-
/** Position and size of the tray icon. */
58-
rect: {
59-
position: PhysicalPosition
60-
size: PhysicalSize
61-
}
62-
}
63-
64-
/** The mouse moved over the tray icon region. */
65-
export interface TrayIconMoveEvent {
66-
/** Id of the tray icon which triggered this event. */
67-
id: string
68-
/** Physical X Position of the click the triggered this event. */
69-
x: number
70-
/** Physical Y Position of the click the triggered this event. */
71-
y: number
72-
/** Position and size of the tray icon. */
73-
rect: {
74-
position: PhysicalPosition
75-
size: PhysicalSize
76-
}
77-
}
78-
79-
/** The mouse left the tray icon region. */
80-
export interface TrayIconLeaveEvent {
81-
/** Id of the tray icon which triggered this event. */
82-
id: string
83-
/** Physical X Position of the click the triggered this event. */
84-
x: number
85-
/** Physical Y Position of the click the triggered this event. */
86-
y: number
87-
/** Position and size of the tray icon. */
88-
rect: {
89-
position: PhysicalPosition
90-
size: PhysicalSize
91-
}
36+
/** Mouse button state when this event was triggered. */
37+
buttonState: MouseButtonState
9238
}
9339

9440
/**
@@ -100,11 +46,22 @@ export interface TrayIconLeaveEvent {
10046
* the icon will still show a context menu on right click.
10147
*/
10248
export type TrayIconEvent =
103-
| { click: TrayIconClickEvent }
104-
| { doubleClick: TrayIconDoubleClickEvent }
105-
| { enter: TrayIconEnterEvent }
106-
| { move: TrayIconMoveEvent }
107-
| { leave: TrayIconLeaveEvent }
49+
| (TrayIconEventBase<'Click'> & TrayIconClickEvent)
50+
| (TrayIconEventBase<'DoubleClick'> & Omit<TrayIconClickEvent, 'buttonState'>)
51+
| TrayIconEventBase<'Enter'>
52+
| TrayIconEventBase<'Move'>
53+
| TrayIconEventBase<'Leave'>
54+
55+
type RustTrayIconEvent = Omit<TrayIconEvent, 'rect'> & {
56+
rect: {
57+
position: {
58+
Physical: { x: number; y: number }
59+
}
60+
size: {
61+
Physical: { width: number; height: number }
62+
}
63+
}
64+
}
10865

10966
/**
11067
* Tray icon types and utilities.
@@ -223,38 +180,10 @@ export class TrayIcon extends Resource {
223180
options.icon = transformImage(options.icon)
224181
}
225182

226-
const handler = new Channel<TrayIconEvent>()
183+
const handler = new Channel<RustTrayIconEvent>()
227184
if (options?.action) {
228185
const action = options.action
229-
handler.onmessage = (e) => {
230-
if ('click' in e) {
231-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
232-
e.click.rect.position = mapPosition(e.click.rect.position)
233-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
234-
e.click.rect.size = mapSize(e.click.rect.size)
235-
} else if ('doubleClick' in e) {
236-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
237-
e.doubleClick.rect.position = mapPosition(e.doubleClick.rect.position)
238-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
239-
e.doubleClick.rect.size = mapSize(e.doubleClick.rect.size)
240-
} else if ('enter' in e) {
241-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
242-
e.enter.rect.position = mapPosition(e.enter.rect.position)
243-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
244-
e.enter.rect.size = mapSize(e.enter.rect.size)
245-
} else if ('move' in e) {
246-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
247-
e.move.rect.position = mapPosition(e.move.rect.position)
248-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
249-
e.move.rect.size = mapSize(e.move.rect.size)
250-
} else if ('leave' in e) {
251-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
252-
e.leave.rect.position = mapPosition(e.leave.rect.position)
253-
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
254-
e.leave.rect.size = mapSize(e.leave.rect.size)
255-
}
256-
action(e)
257-
}
186+
handler.onmessage = (e) => action(mapEvent(e))
258187
delete options.action
259188
}
260189

@@ -358,13 +287,19 @@ export class TrayIcon extends Resource {
358287
}
359288
}
360289

361-
function mapPosition(pos: {
362-
Physical: { x: number; y: number }
363-
}): PhysicalPosition {
364-
return new PhysicalPosition(pos.Physical.x, pos.Physical.y)
365-
}
366-
function mapSize(pos: {
367-
Physical: { width: number; height: number }
368-
}): PhysicalSize {
369-
return new PhysicalSize(pos.Physical.width, pos.Physical.height)
290+
function mapEvent(e: RustTrayIconEvent): TrayIconEvent {
291+
const out = e as unknown as TrayIconEvent
292+
293+
out.position = new PhysicalPosition(e.position.x, e.position.y)
294+
295+
out.rect.position = new PhysicalPosition(
296+
e.rect.position.Physical.x,
297+
e.rect.position.Physical.y
298+
)
299+
out.rect.size = new PhysicalSize(
300+
e.rect.size.Physical.width,
301+
e.rect.size.Physical.height
302+
)
303+
304+
return out
370305
}

0 commit comments

Comments
 (0)