mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-14 21:21:44 +03:00
feat(api): add abstractions to updater and window event listeners (#4569)
This commit is contained in:
parent
e29fff2566
commit
b02fc90f45
5
.changes/api-event-listeners.md
Normal file
5
.changes/api-event-listeners.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"api": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Added helper functions to listen to updater and window events.
|
File diff suppressed because one or more lines are too long
70
examples/api/dist/assets/index.js
vendored
70
examples/api/dist/assets/index.js
vendored
File diff suppressed because one or more lines are too long
@ -214,24 +214,27 @@ fn main() {
|
|||||||
event: WindowEvent::CloseRequested { api, .. },
|
event: WindowEvent::CloseRequested { api, .. },
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let app_handle = app_handle.clone();
|
// for other windows, we handle it in JS
|
||||||
let window = app_handle.get_window(&label).unwrap();
|
if label == "main" {
|
||||||
// use the exposed close api, and prevent the event loop to close
|
let app_handle = app_handle.clone();
|
||||||
api.prevent_close();
|
let window = app_handle.get_window(&label).unwrap();
|
||||||
// ask the user if he wants to quit
|
// use the exposed close api, and prevent the event loop to close
|
||||||
ask(
|
api.prevent_close();
|
||||||
Some(&window),
|
// ask the user if he wants to quit
|
||||||
"Tauri API",
|
ask(
|
||||||
"Are you sure that you want to close this window?",
|
Some(&window),
|
||||||
move |answer| {
|
"Tauri API",
|
||||||
if answer {
|
"Are you sure that you want to close this window?",
|
||||||
// .close() cannot be called on the main thread
|
move |answer| {
|
||||||
std::thread::spawn(move || {
|
if answer {
|
||||||
app_handle.get_window(&label).unwrap().close().unwrap();
|
// .close() cannot be called on the main thread
|
||||||
});
|
std::thread::spawn(move || {
|
||||||
}
|
app_handle.get_window(&label).unwrap().close().unwrap();
|
||||||
},
|
});
|
||||||
);
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the event loop running even if all windows are closed
|
// Keep the event loop running even if all windows are closed
|
||||||
|
@ -22,8 +22,18 @@
|
|||||||
import { listen } from '@tauri-apps/api/event'
|
import { listen } from '@tauri-apps/api/event'
|
||||||
import { ask } from '@tauri-apps/api/dialog'
|
import { ask } from '@tauri-apps/api/dialog'
|
||||||
|
|
||||||
appWindow.listen('tauri://file-drop', function (event) {
|
if (appWindow.label !== 'main') {
|
||||||
onMessage(`File drop: ${event.payload}`)
|
appWindow.onCloseRequested(async (event) => {
|
||||||
|
const confirmed = await confirm('Are you sure?')
|
||||||
|
if (!confirmed) {
|
||||||
|
// user did not confirm closing the window; let's prevent it
|
||||||
|
event.preventDefault()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
appWindow.onFileDropEvent((event) => {
|
||||||
|
onMessage(`File drop: ${JSON.stringify(event.payload)}`)
|
||||||
})
|
})
|
||||||
|
|
||||||
const views = [
|
const views = [
|
||||||
|
@ -19,6 +19,7 @@ import type {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen to an event from the backend.
|
* Listen to an event from the backend.
|
||||||
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* import { listen } from '@tauri-apps/api/event';
|
* import { listen } from '@tauri-apps/api/event';
|
||||||
@ -26,13 +27,14 @@ import type {
|
|||||||
* console.log(`Got error in window ${event.windowLabel}, payload: ${payload}`);
|
* console.log(`Got error in window ${event.windowLabel}, payload: ${payload}`);
|
||||||
* });
|
* });
|
||||||
*
|
*
|
||||||
* // removes the listener later
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
* await unlisten();
|
* unlisten();
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
||||||
* @param handler Event handler callback.
|
* @param handler Event handler callback.
|
||||||
* @return A promise resolving to a function to unlisten to the event.
|
* @return A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
*/
|
*/
|
||||||
async function listen<T>(
|
async function listen<T>(
|
||||||
event: EventName,
|
event: EventName,
|
||||||
@ -43,6 +45,7 @@ async function listen<T>(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen to an one-off event from the backend.
|
* Listen to an one-off event from the backend.
|
||||||
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* import { once } from '@tauri-apps/api/event';
|
* import { once } from '@tauri-apps/api/event';
|
||||||
@ -53,11 +56,15 @@ async function listen<T>(
|
|||||||
* const unlisten = await once<LoadedPayload>('loaded', (event) => {
|
* const unlisten = await once<LoadedPayload>('loaded', (event) => {
|
||||||
* console.log(`App is loaded, logggedIn: ${event.payload.loggedIn}, token: ${event.payload.token}`);
|
* console.log(`App is loaded, logggedIn: ${event.payload.loggedIn}, token: ${event.payload.token}`);
|
||||||
* });
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
||||||
* @param handler Event handler callback.
|
* @param handler Event handler callback.
|
||||||
* @returns A promise resolving to a function to unlisten to the event.
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
*/
|
*/
|
||||||
async function once<T>(
|
async function once<T>(
|
||||||
event: EventName,
|
event: EventName,
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
import { WindowLabel } from '../window'
|
import { WindowLabel } from '../window'
|
||||||
import { invokeTauriCommand } from './tauri'
|
import { invokeTauriCommand } from './tauri'
|
||||||
import { transformCallback } from '../tauri'
|
import { transformCallback } from '../tauri'
|
||||||
import { LiteralUnion } from 'type-fest'
|
|
||||||
|
|
||||||
export interface Event<T> {
|
export interface Event<T> {
|
||||||
/** Event name */
|
/** Event name */
|
||||||
@ -18,25 +17,7 @@ export interface Event<T> {
|
|||||||
payload: T
|
payload: T
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EventName = LiteralUnion<
|
export type EventName = string
|
||||||
| 'tauri://update'
|
|
||||||
| 'tauri://update-available'
|
|
||||||
| 'tauri://update-download-progress'
|
|
||||||
| 'tauri://update-install'
|
|
||||||
| 'tauri://update-status'
|
|
||||||
| 'tauri://resize'
|
|
||||||
| 'tauri://move'
|
|
||||||
| 'tauri://close-requested'
|
|
||||||
| 'tauri://focus'
|
|
||||||
| 'tauri://blur'
|
|
||||||
| 'tauri://scale-change'
|
|
||||||
| 'tauri://menu'
|
|
||||||
| 'tauri://file-drop'
|
|
||||||
| 'tauri://file-drop-hover'
|
|
||||||
| 'tauri://file-drop-cancelled'
|
|
||||||
| 'tauri://theme-changed',
|
|
||||||
string
|
|
||||||
>
|
|
||||||
|
|
||||||
export type EventCallback<T> = (event: Event<T>) => void
|
export type EventCallback<T> = (event: Event<T>) => void
|
||||||
|
|
||||||
|
@ -29,6 +29,31 @@ interface UpdateResult {
|
|||||||
shouldUpdate: boolean
|
shouldUpdate: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to an updater event.
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { onUpdaterEvent } from "@tauri-apps/api/updater";
|
||||||
|
* const unlisten = await onUpdaterEvent(({ error, status }) => {
|
||||||
|
* console.log('Updater event', error, status);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async function onUpdaterEvent(
|
||||||
|
handler: (status: UpdateStatusResult) => void
|
||||||
|
): Promise<UnlistenFn> {
|
||||||
|
return listen('tauri://update-status', (data: { payload: any }) => {
|
||||||
|
handler(data?.payload as UpdateStatusResult)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install the update if there's one available.
|
* Install the update if there's one available.
|
||||||
* @example
|
* @example
|
||||||
@ -68,9 +93,7 @@ async function installUpdate(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// listen status change
|
// listen status change
|
||||||
listen('tauri://update-status', (data: { payload: any }) => {
|
onUpdaterEvent(onStatusChange)
|
||||||
onStatusChange(data?.payload as UpdateStatusResult)
|
|
||||||
})
|
|
||||||
.then((fn) => {
|
.then((fn) => {
|
||||||
unlistenerFn = fn
|
unlistenerFn = fn
|
||||||
})
|
})
|
||||||
@ -144,9 +167,7 @@ async function checkUpdate(): Promise<UpdateResult> {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// listen status change
|
// listen status change
|
||||||
listen('tauri://update-status', (data: { payload: any }) => {
|
onUpdaterEvent(onStatusChange)
|
||||||
onStatusChange(data?.payload as UpdateStatusResult)
|
|
||||||
})
|
|
||||||
.then((fn) => {
|
.then((fn) => {
|
||||||
unlistenerFn = fn
|
unlistenerFn = fn
|
||||||
})
|
})
|
||||||
@ -167,4 +188,4 @@ async function checkUpdate(): Promise<UpdateResult> {
|
|||||||
|
|
||||||
export type { UpdateStatus, UpdateStatusResult, UpdateManifest, UpdateResult }
|
export type { UpdateStatus, UpdateStatusResult, UpdateManifest, UpdateResult }
|
||||||
|
|
||||||
export { installUpdate, checkUpdate }
|
export { onUpdaterEvent, installUpdate, checkUpdate }
|
||||||
|
@ -53,67 +53,8 @@
|
|||||||
*
|
*
|
||||||
* Events can be listened using `appWindow.listen`:
|
* Events can be listened using `appWindow.listen`:
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* import { appWindow } from "@tauri-apps/api/window"
|
|
||||||
* appWindow.listen("tauri://move", ({ event, payload }) => {
|
|
||||||
* const { x, y } = payload; // payload here is a `PhysicalPosition`
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* Window-specific events emitted by the backend:
|
|
||||||
*
|
|
||||||
* #### 'tauri://resize'
|
|
||||||
* Emitted when the size of the window has changed.
|
|
||||||
* *EventPayload*:
|
|
||||||
* ```typescript
|
|
||||||
* type ResizePayload = PhysicalSize
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* #### 'tauri://move'
|
|
||||||
* Emitted when the position of the window has changed.
|
|
||||||
* *EventPayload*:
|
|
||||||
* ```typescript
|
|
||||||
* type MovePayload = PhysicalPosition
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* #### 'tauri://close-requested'
|
|
||||||
* Emitted when the user requests the window to be closed.
|
|
||||||
* If a listener is registered for this event, Tauri won't close the window so you must call `appWindow.close()` manually.
|
|
||||||
* ```typescript
|
|
||||||
* import { appWindow } from "@tauri-apps/api/window";
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
* import { confirm } from '@tauri-apps/api/dialog';
|
* appWindow.listen("my-window-event", ({ event, payload }) => { });
|
||||||
* appWindow.listen("tauri://close-requested", async ({ event, payload }) => {
|
|
||||||
* const confirmed = await confirm('Are you sure?');
|
|
||||||
* if (confirmed) {
|
|
||||||
* await appWindow.close();
|
|
||||||
* }
|
|
||||||
* });
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* #### 'tauri://focus'
|
|
||||||
* Emitted when the window gains focus.
|
|
||||||
*
|
|
||||||
* #### 'tauri://blur'
|
|
||||||
* Emitted when the window loses focus.
|
|
||||||
*
|
|
||||||
* #### 'tauri://scale-change'
|
|
||||||
* Emitted when the window's scale factor has changed.
|
|
||||||
* The following user actions can cause DPI changes:
|
|
||||||
* - Changing the display's resolution.
|
|
||||||
* - Changing the display's scale factor (e.g. in Control Panel on Windows).
|
|
||||||
* - Moving the window to a display with a different scale factor.
|
|
||||||
* *Event payload*:
|
|
||||||
* ```typescript
|
|
||||||
* interface ScaleFactorChanged {
|
|
||||||
* scaleFactor: number
|
|
||||||
* size: PhysicalSize
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*
|
|
||||||
* #### 'tauri://menu'
|
|
||||||
* Emitted when a menu item is clicked.
|
|
||||||
* *EventPayload*:
|
|
||||||
* ```typescript
|
|
||||||
* type MenuClicked = string
|
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @module
|
* @module
|
||||||
@ -121,7 +62,7 @@
|
|||||||
|
|
||||||
import { invokeTauriCommand } from './helpers/tauri'
|
import { invokeTauriCommand } from './helpers/tauri'
|
||||||
import type { EventName, EventCallback, UnlistenFn } from './event'
|
import type { EventName, EventCallback, UnlistenFn } from './event'
|
||||||
import { emit, listen, once } from './helpers/event'
|
import { emit, Event, listen, once } from './helpers/event'
|
||||||
|
|
||||||
type Theme = 'light' | 'dark'
|
type Theme = 'light' | 'dark'
|
||||||
|
|
||||||
@ -137,6 +78,20 @@ interface Monitor {
|
|||||||
scaleFactor: number
|
scaleFactor: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The payload for the `scaleChange` event. */
|
||||||
|
interface ScaleFactorChanged {
|
||||||
|
/** The new window scale factor. */
|
||||||
|
scaleFactor: number
|
||||||
|
/** The new window size */
|
||||||
|
size: PhysicalSize
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The file drop event types. */
|
||||||
|
type FileDropEvent =
|
||||||
|
| { type: 'hover'; paths: string[] }
|
||||||
|
| { type: 'drop'; paths: string[] }
|
||||||
|
| { type: 'cancel' }
|
||||||
|
|
||||||
/** A size represented in logical pixels. */
|
/** A size represented in logical pixels. */
|
||||||
class LogicalSize {
|
class LogicalSize {
|
||||||
type = 'Logical'
|
type = 'Logical'
|
||||||
@ -335,9 +290,21 @@ class WebviewWindowHandle {
|
|||||||
/**
|
/**
|
||||||
* Listen to an event emitted by the backend that is tied to the webview window.
|
* Listen to an event emitted by the backend that is tied to the webview window.
|
||||||
*
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from '@tauri-apps/api/window';
|
||||||
|
* const unlisten = await appWindow.listen<string>('state-changed', (event) => {
|
||||||
|
* console.log(`Got error: ${payload}`);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
||||||
* @param handler Event handler.
|
* @param handler Event handler.
|
||||||
* @returns A promise resolving to a function to unlisten to the event.
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
*/
|
*/
|
||||||
async listen<T>(
|
async listen<T>(
|
||||||
event: EventName,
|
event: EventName,
|
||||||
@ -356,9 +323,21 @@ class WebviewWindowHandle {
|
|||||||
/**
|
/**
|
||||||
* Listen to an one-off event emitted by the backend that is tied to the webview window.
|
* Listen to an one-off event emitted by the backend that is tied to the webview window.
|
||||||
*
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from '@tauri-apps/api/window';
|
||||||
|
* const unlisten = await appWindow.once<null>('initialized', (event) => {
|
||||||
|
* console.log(`Window initialized!`);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
||||||
* @param handler Event handler.
|
* @param handler Event handler.
|
||||||
* @returns A promise resolving to a function to unlisten to the event.
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
*/
|
*/
|
||||||
async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
|
async once<T>(event: string, handler: EventCallback<T>): Promise<UnlistenFn> {
|
||||||
if (this._handleTauriEvent(event, handler)) {
|
if (this._handleTauriEvent(event, handler)) {
|
||||||
@ -373,6 +352,11 @@ class WebviewWindowHandle {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Emits an event to the backend, tied to the webview window.
|
* Emits an event to the backend, tied to the webview window.
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from '@tauri-apps/api/window';
|
||||||
|
* await appWindow.emit('window-loaded', { loggedIn: true, token: 'authToken' });
|
||||||
|
* ```
|
||||||
*
|
*
|
||||||
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
* @param event Event name. Must include only alphanumeric characters, `-`, `/`, `:` and `_`.
|
||||||
* @param payload Event payload.
|
* @param payload Event payload.
|
||||||
@ -1517,6 +1501,278 @@ class WindowManager extends WebviewWindowHandle {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Listeners
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to window resize.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
|
* const unlisten = await appWindow.onResized(({ payload: size }) => {
|
||||||
|
* console.log('Window resized', size);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async onResized(handler: EventCallback<PhysicalSize>): Promise<UnlistenFn> {
|
||||||
|
return this.listen<PhysicalSize>('tauri://resize', handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to window move.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
|
* const unlisten = await appWindow.onMoved(({ payload: position }) => {
|
||||||
|
* console.log('Window moved', position);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async onMoved(handler: EventCallback<PhysicalPosition>): Promise<UnlistenFn> {
|
||||||
|
return this.listen<PhysicalPosition>('tauri://move', handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to window close requested. Emitted when the user requests to closes the window.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
|
* import { confirm } from '@tauri-apps/api/dialog';
|
||||||
|
* const unlisten = await appWindow.onCloseRequested(async (event) => {
|
||||||
|
* const confirmed = await confirm('Are you sure?');
|
||||||
|
* if (!confirmed) {
|
||||||
|
* // user did not confirm closing the window; let's prevent it
|
||||||
|
* event.preventDefault();
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async onCloseRequested(
|
||||||
|
handler: (event: CloseRequestedEvent) => void
|
||||||
|
): Promise<UnlistenFn> {
|
||||||
|
return this.listen<null>('tauri://close-requested', (event) => {
|
||||||
|
const evt = new CloseRequestedEvent(event)
|
||||||
|
void Promise.resolve(handler(evt)).then(() => {
|
||||||
|
if (!evt.isPreventDefault()) {
|
||||||
|
return this.close()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to window focus change.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
|
* const unlisten = await appWindow.onFocusChanged(({ payload: focused }) => {
|
||||||
|
* console.log('Focus changed, window is focused? ' + focused);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async onFocusChanged(handler: EventCallback<boolean>): Promise<UnlistenFn> {
|
||||||
|
const unlistenFocus = await this.listen<PhysicalPosition>(
|
||||||
|
'tauri://focus',
|
||||||
|
(event) => {
|
||||||
|
handler({ ...event, payload: true })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const unlistenBlur = await this.listen<PhysicalPosition>(
|
||||||
|
'tauri://blur',
|
||||||
|
(event) => {
|
||||||
|
handler({ ...event, payload: false })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return () => {
|
||||||
|
unlistenFocus()
|
||||||
|
unlistenBlur()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to window scale change. Emitted when the window's scale factor has changed.
|
||||||
|
* The following user actions can cause DPI changes:
|
||||||
|
* - Changing the display's resolution.
|
||||||
|
* - Changing the display's scale factor (e.g. in Control Panel on Windows).
|
||||||
|
* - Moving the window to a display with a different scale factor.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
|
* const unlisten = await appWindow.onScaleChanged(({ payload }) => {
|
||||||
|
* console.log('Scale changed', payload.scaleFactor, payload.size);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async onScaleChanged(
|
||||||
|
handler: EventCallback<ScaleFactorChanged>
|
||||||
|
): Promise<UnlistenFn> {
|
||||||
|
return this.listen<ScaleFactorChanged>('tauri://scale-change', handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to the window menu item click. The payload is the item id.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
|
* const unlisten = await appWindow.onMenuClicked(({ payload: menuId }) => {
|
||||||
|
* console.log('Menu clicked: ' + menuId);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async onMenuClicked(handler: EventCallback<string>): Promise<UnlistenFn> {
|
||||||
|
return this.listen<string>('tauri://menu', handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to a file drop event.
|
||||||
|
* The listener is triggered when the user hovers the selected files on the window,
|
||||||
|
* drops the files or cancels the operation.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
|
* const unlisten = await appWindow.onFileDropEvent((event) => {
|
||||||
|
* if (event.payload.type === 'hover') {
|
||||||
|
* console.log('User hovering', event.payload.paths);
|
||||||
|
* } else if (event.payload.type === 'drop') {
|
||||||
|
* console.log('User dropped', event.payload.paths);
|
||||||
|
* } else {
|
||||||
|
* console.log('File drop cancelled');
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async onFileDropEvent(
|
||||||
|
handler: EventCallback<FileDropEvent>
|
||||||
|
): Promise<UnlistenFn> {
|
||||||
|
const unlistenFileDrop = await this.listen<string[]>(
|
||||||
|
'tauri://file-drop',
|
||||||
|
(event) => {
|
||||||
|
handler({ ...event, payload: { type: 'drop', paths: event.payload } })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const unlistenFileHover = await this.listen<string[]>(
|
||||||
|
'tauri://file-drop-hover',
|
||||||
|
(event) => {
|
||||||
|
handler({ ...event, payload: { type: 'hover', paths: event.payload } })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const unlistenCancel = await this.listen<null>(
|
||||||
|
'tauri://file-drop-cancelled',
|
||||||
|
(event) => {
|
||||||
|
handler({ ...event, payload: { type: 'cancel' } })
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unlistenFileDrop()
|
||||||
|
unlistenFileHover()
|
||||||
|
unlistenCancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen to the system theme change.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* import { appWindow } from "@tauri-apps/api/window";
|
||||||
|
* const unlisten = await appWindow.onThemeChanged(({ payload: theme }) => {
|
||||||
|
* console.log('New theme: ' + theme);
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // you need to call unlisten if your handler goes out of scope e.g. the component is unmounted
|
||||||
|
* unlisten();
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* @returns A promise resolving to a function to unlisten to the event.
|
||||||
|
* Note that removing the listener is required if your listener goes out of scope e.g. the component is unmounted.
|
||||||
|
*/
|
||||||
|
async onThemeChanged(handler: EventCallback<Theme>): Promise<UnlistenFn> {
|
||||||
|
return this.listen<Theme>('tauri://theme-changed', handler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CloseRequestedEvent {
|
||||||
|
/** Event name */
|
||||||
|
event: EventName
|
||||||
|
/** The label of the window that emitted this event. */
|
||||||
|
windowLabel: string
|
||||||
|
/** Event identifier used to unlisten */
|
||||||
|
id: number
|
||||||
|
private _preventDefault = false
|
||||||
|
|
||||||
|
constructor(event: Event<null>) {
|
||||||
|
this.event = event.event
|
||||||
|
this.windowLabel = event.windowLabel
|
||||||
|
this.id = event.id
|
||||||
|
}
|
||||||
|
|
||||||
|
preventDefault(): void {
|
||||||
|
this._preventDefault = true
|
||||||
|
}
|
||||||
|
|
||||||
|
isPreventDefault(): boolean {
|
||||||
|
return this._preventDefault
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1769,6 +2025,7 @@ export {
|
|||||||
WebviewWindow,
|
WebviewWindow,
|
||||||
WebviewWindowHandle,
|
WebviewWindowHandle,
|
||||||
WindowManager,
|
WindowManager,
|
||||||
|
CloseRequestedEvent,
|
||||||
getCurrent,
|
getCurrent,
|
||||||
getAll,
|
getAll,
|
||||||
appWindow,
|
appWindow,
|
||||||
@ -1782,4 +2039,4 @@ export {
|
|||||||
availableMonitors
|
availableMonitors
|
||||||
}
|
}
|
||||||
|
|
||||||
export type { Theme, Monitor, WindowOptions }
|
export type { Theme, Monitor, ScaleFactorChanged, FileDropEvent, WindowOptions }
|
||||||
|
Loading…
Reference in New Issue
Block a user