mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-01-31 00:35:19 +01:00
refactor!: simplify TrayIconEvent in JS by tagging it with type field (#11121)
Co-authored-by: Tony <68118705+Legend-Master@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
---
|
||||
"@tauri-apps/api": "patch:bug"
|
||||
---
|
||||
|
||||
Add missing `TrayIconDoubleClickEvent` type and `doubleClick` variant in `TrayIconEvent` type.
|
||||
7
.changes/api-tray-event-refactor.md
Normal file
7
.changes/api-tray-event-refactor.md
Normal file
@@ -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.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
"@tauri-apps/api": "patch:bug"
|
||||
---
|
||||
|
||||
Fix invalid value passed to the callback `action` function that doesn't match the `TrayIconEvent` type.
|
||||
|
||||
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -8190,9 +8190,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tray-icon"
|
||||
version = "0.18.0"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1730884cee088bb1dc1570c0a8b70a59e740ee780563407fd249e3e11ef26ff"
|
||||
checksum = "533fc2d4105e0e3d96ce1c71f2d308c9fbbe2ef9c587cab63dd627ab5bde218f"
|
||||
dependencies = [
|
||||
"core-graphics 0.24.0",
|
||||
"crossbeam-channel",
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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.
|
||||
@@ -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,
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,88 +9,34 @@ 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
|
||||
}
|
||||
}
|
||||
|
||||
export type TrayIconClickEvent = {
|
||||
/** 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
|
||||
}
|
||||
/** 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
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes a tray icon event.
|
||||
*
|
||||
@@ -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.
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user