Skip to content

Commit

Permalink
refactor!: simplify TrayIconEvent in JS by tagging it with type f…
Browse files Browse the repository at this point in the history
…ield (#11121)



Co-authored-by: Tony <[email protected]>
  • Loading branch information
amrbashir and Legend-Master authored Sep 26, 2024
1 parent 544328d commit 0b44959
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 128 deletions.
5 changes: 0 additions & 5 deletions .changes/api-tray-doubleClick-event.md

This file was deleted.

7 changes: 7 additions & 0 deletions .changes/api-tray-event-refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"tauri": "patch:breaking"
"@tauri-apps/api": "patch:breaking"
---

Simplified emitted tray event JS value and updated `TrayIconEvent` type definition to match it.

6 changes: 0 additions & 6 deletions .changes/api-tray-icon-event-value-mismatch-type.md

This file was deleted.

4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ specta = { version = "^2.0.0-rc.16", optional = true, default-features = false,

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

Expand Down
2 changes: 1 addition & 1 deletion crates/tauri/scripts/bundle.global.js

Large diffs are not rendered by default.

51 changes: 50 additions & 1 deletion crates/tauri/src/tray/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ impl From<tray_icon::MouseButton> for MouseButton {
/// - **Linux**: Unsupported. The event is not emmited even though the icon is shown
/// and will still show a context menu on right click.
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
#[serde(tag = "type")]
#[non_exhaustive]
pub enum TrayIconEvent {
/// A click happened on the tray icon.
Expand Down Expand Up @@ -563,3 +563,52 @@ impl<R: Runtime> Resource for TrayIcon<R> {
self.app_handle.remove_tray_by_id(&self.id);
}
}

#[cfg(test)]
mod tests {
#[test]
fn tray_event_json_serialization() {
// NOTE: if this test is ever changed, you probably need to change `TrayIconEvent` in JS as well

use super::*;
let event = TrayIconEvent::Click {
button: MouseButton::Left,
button_state: MouseButtonState::Down,
id: TrayIconId::new("id"),
position: crate::PhysicalPosition::default(),
rect: crate::Rect {
position: tray_icon::Rect::default().position.into(),
size: tray_icon::Rect::default().size.into(),
},
};

let value = serde_json::to_value(&event).unwrap();
assert_eq!(
value,
serde_json::json!({
"type": "Click",
"button": "Left",
"buttonState": "Down",
"id": "id",
"position": {
"x": 0.0,
"y": 0.0,
},
"rect": {
"size": {
"Physical": {
"width": 0,
"height": 0,
}
},
"position": {
"Physical": {
"x": 0,
"y": 0,
}
},
}
})
);
}
}
159 changes: 47 additions & 112 deletions packages/api/src/tray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,86 +9,32 @@ import { PhysicalPosition, PhysicalSize } from './dpi'

export type MouseButtonState = 'Up' | 'Down'
export type MouseButton = 'Left' | 'Right' | 'Middle'
export type TrayIconEventType =
| 'Click'
| 'DoubleClick'
| 'Enter'
| 'Move'
| 'Leave'

/** A click happened on the tray icon. */
export interface TrayIconClickEvent {
export type TrayIconEventBase<T extends TrayIconEventType> = {
/** The tray icon event type */
type: T
/** Id of the tray icon which triggered this event. */
id: string
/** Physical X Position of the click the triggered this event. */
x: number
/** Physical Y Position of the click the triggered this event. */
y: number
/** Physical position of the click the triggered this event. */
position: PhysicalPosition
/** Position and size of the tray icon. */
rect: {
position: PhysicalPosition
size: PhysicalSize
}
/** Mouse button that triggered this event. */
button: MouseButton
/** Mouse button state when this event was triggered. */
buttonState: MouseButtonState
}

/** A double click happened on the tray icon. **Windows Only** */
export interface TrayIconDoubleClickEvent {
/** Id of the tray icon which triggered this event. */
id: string
/** Physical X Position of the click the triggered this event. */
x: number
/** Physical Y Position of the click the triggered this event. */
y: number
/** Position and size of the tray icon. */
rect: {
position: PhysicalPosition
size: PhysicalSize
}
export type TrayIconClickEvent = {
/** Mouse button that triggered this event. */
button: MouseButton
}

/** The mouse entered the tray icon region. */
export interface TrayIconEnterEvent {
/** Id of the tray icon which triggered this event. */
id: string
/** Physical X Position of the click the triggered this event. */
x: number
/** Physical Y Position of the click the triggered this event. */
y: number
/** Position and size of the tray icon. */
rect: {
position: PhysicalPosition
size: PhysicalSize
}
}

/** The mouse moved over the tray icon region. */
export interface TrayIconMoveEvent {
/** Id of the tray icon which triggered this event. */
id: string
/** Physical X Position of the click the triggered this event. */
x: number
/** Physical Y Position of the click the triggered this event. */
y: number
/** Position and size of the tray icon. */
rect: {
position: PhysicalPosition
size: PhysicalSize
}
}

/** The mouse left the tray icon region. */
export interface TrayIconLeaveEvent {
/** Id of the tray icon which triggered this event. */
id: string
/** Physical X Position of the click the triggered this event. */
x: number
/** Physical Y Position of the click the triggered this event. */
y: number
/** Position and size of the tray icon. */
rect: {
position: PhysicalPosition
size: PhysicalSize
}
/** Mouse button state when this event was triggered. */
buttonState: MouseButtonState
}

/**
Expand All @@ -100,11 +46,22 @@ export interface TrayIconLeaveEvent {
* the icon will still show a context menu on right click.
*/
export type TrayIconEvent =
| { click: TrayIconClickEvent }
| { doubleClick: TrayIconDoubleClickEvent }
| { enter: TrayIconEnterEvent }
| { move: TrayIconMoveEvent }
| { leave: TrayIconLeaveEvent }
| (TrayIconEventBase<'Click'> & TrayIconClickEvent)
| (TrayIconEventBase<'DoubleClick'> & Omit<TrayIconClickEvent, 'buttonState'>)
| TrayIconEventBase<'Enter'>
| TrayIconEventBase<'Move'>
| TrayIconEventBase<'Leave'>

type RustTrayIconEvent = Omit<TrayIconEvent, 'rect'> & {
rect: {
position: {
Physical: { x: number; y: number }
}
size: {
Physical: { width: number; height: number }
}
}
}

/**
* Tray icon types and utilities.
Expand Down Expand Up @@ -223,38 +180,10 @@ export class TrayIcon extends Resource {
options.icon = transformImage(options.icon)
}

const handler = new Channel<TrayIconEvent>()
const handler = new Channel<RustTrayIconEvent>()
if (options?.action) {
const action = options.action
handler.onmessage = (e) => {
if ('click' in e) {
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.click.rect.position = mapPosition(e.click.rect.position)
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.click.rect.size = mapSize(e.click.rect.size)
} else if ('doubleClick' in e) {
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.doubleClick.rect.position = mapPosition(e.doubleClick.rect.position)
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.doubleClick.rect.size = mapSize(e.doubleClick.rect.size)
} else if ('enter' in e) {
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.enter.rect.position = mapPosition(e.enter.rect.position)
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.enter.rect.size = mapSize(e.enter.rect.size)
} else if ('move' in e) {
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.move.rect.position = mapPosition(e.move.rect.position)
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.move.rect.size = mapSize(e.move.rect.size)
} else if ('leave' in e) {
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.leave.rect.position = mapPosition(e.leave.rect.position)
// @ts-expect-error `TrayIconEvent` doesn't quite match the value yet so we reconstruct the incorrect fields
e.leave.rect.size = mapSize(e.leave.rect.size)
}
action(e)
}
handler.onmessage = (e) => action(mapEvent(e))
delete options.action
}

Expand Down Expand Up @@ -358,13 +287,19 @@ export class TrayIcon extends Resource {
}
}

function mapPosition(pos: {
Physical: { x: number; y: number }
}): PhysicalPosition {
return new PhysicalPosition(pos.Physical.x, pos.Physical.y)
}
function mapSize(pos: {
Physical: { width: number; height: number }
}): PhysicalSize {
return new PhysicalSize(pos.Physical.width, pos.Physical.height)
function mapEvent(e: RustTrayIconEvent): TrayIconEvent {
const out = e as unknown as TrayIconEvent

out.position = new PhysicalPosition(e.position.x, e.position.y)

out.rect.position = new PhysicalPosition(
e.rect.position.Physical.x,
e.rect.position.Physical.y
)
out.rect.size = new PhysicalSize(
e.rect.size.Physical.width,
e.rect.size.Physical.height
)

return out
}

0 comments on commit 0b44959

Please sign in to comment.