diff --git a/.changes/window-effects-api.md b/.changes/window-effects-api.md new file mode 100644 index 000000000..39845271e --- /dev/null +++ b/.changes/window-effects-api.md @@ -0,0 +1,5 @@ +--- +'api': minor +--- + +Added the `windowEffects` option when creating a window and `setWindowEffects` method to change it at runtime. diff --git a/.changes/window-effects-config.md b/.changes/window-effects-config.md new file mode 100644 index 000000000..efd8fc14d --- /dev/null +++ b/.changes/window-effects-config.md @@ -0,0 +1,5 @@ +--- +'tauri-utils': minor +--- + +Added the `window_effects` option to the window configuration. diff --git a/.changes/window-effects.md b/.changes/window-effects.md new file mode 100644 index 000000000..d7447873e --- /dev/null +++ b/.changes/window-effects.md @@ -0,0 +1,7 @@ +--- +'tauri': minor +'tauri-runtime-wry': minor +'tauri-runtime': minor +--- + +Added the `window_effects` option when creating a window and `Window::set_effects` to change it at runtime. diff --git a/core/tauri-config-schema/schema.json b/core/tauri-config-schema/schema.json index b5f5da379..24e4c6283 100644 --- a/core/tauri-config-schema/schema.json +++ b/core/tauri-config-schema/schema.json @@ -488,6 +488,17 @@ "description": "Whether or not the window has shadow.\n\n## Platform-specific\n\n- **Windows:** - `false` has no effect on decorated window, shadow are always ON. - `true` will make ndecorated window have a 1px white border, and on Windows 11, it will have a rounded corners. - **Linux:** Unsupported.", "default": true, "type": "boolean" + }, + "windowEffects": { + "description": "Window effects.\n\nRequires the window to be transparent.\n\n## Platform-specific:\n\n- **Windows**: If using decorations or shadows, you may want to try this workaround https://github.com/tauri-apps/tao/issues/72#issuecomment-975607891 - **Linux**: Unsupported", + "anyOf": [ + { + "$ref": "#/definitions/WindowEffectsConfig" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false @@ -551,6 +562,271 @@ } ] }, + "WindowEffectsConfig": { + "description": "The window effects configuration object", + "type": "object", + "required": [ + "effects" + ], + "properties": { + "effects": { + "description": "List of Window effects to apply to the Window. Conflicting effects will apply the first one and ignore the rest.", + "type": "array", + "items": { + "$ref": "#/definitions/WindowEffect" + } + }, + "state": { + "description": "Window effect state **macOS Only**", + "anyOf": [ + { + "$ref": "#/definitions/WindowEffectState" + }, + { + "type": "null" + } + ] + }, + "radius": { + "description": "Window effect corner radius **macOS Only**", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "color": { + "description": "Window effect color. Affects [`WindowEffects::Blur`] and [`WindowEffects::Acrylic`] only on Windows 10 v1903+. Doesn't have any effect on Windows 7 or Windows 11.", + "anyOf": [ + { + "$ref": "#/definitions/Color" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "WindowEffect": { + "description": "Platform-specific window effects", + "oneOf": [ + { + "description": "A default material appropriate for the view's effectiveAppearance. **macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "appearanceBased" + ] + }, + { + "description": "*macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "light" + ] + }, + { + "description": "*macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "dark" + ] + }, + { + "description": "*macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "mediumLight" + ] + }, + { + "description": "*macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "ultraDark" + ] + }, + { + "description": "*macOS 10.10+**", + "type": "string", + "enum": [ + "titlebar" + ] + }, + { + "description": "*macOS 10.10+**", + "type": "string", + "enum": [ + "selection" + ] + }, + { + "description": "*macOS 10.11+**", + "type": "string", + "enum": [ + "menu" + ] + }, + { + "description": "*macOS 10.11+**", + "type": "string", + "enum": [ + "popover" + ] + }, + { + "description": "*macOS 10.11+**", + "type": "string", + "enum": [ + "sidebar" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "headerView" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "sheet" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "windowBackground" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "hudWindow" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "fullScreenUI" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "tooltip" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "contentBackground" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "underWindowBackground" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "underPageBackground" + ] + }, + { + "description": "*Windows 11 Only**", + "type": "string", + "enum": [ + "mica" + ] + }, + { + "description": "**Windows 7/10/11(22H1) Only**\n\n## Notes\n\nThis effect has bad performance when resizing/dragging the window on Windows 11 build 22621.", + "type": "string", + "enum": [ + "blur" + ] + }, + { + "description": "**Windows 10/11 Only**\n\n## Notes\n\nThis effect has bad performance when resizing/dragging the window on Windows 10 v1903+ and Windows 11 build 22000.", + "type": "string", + "enum": [ + "acrylic" + ] + } + ] + }, + "WindowEffectState": { + "description": "Window effect state **macOS only**\n\n", + "oneOf": [ + { + "description": "Make window effect state follow the window's active state", + "type": "string", + "enum": [ + "followsWindowActiveState" + ] + }, + { + "description": "Make window effect state always active", + "type": "string", + "enum": [ + "active" + ] + }, + { + "description": "Make window effect state always inactive", + "type": "string", + "enum": [ + "inactive" + ] + } + ] + }, + "Color": { + "description": "a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 4, + "minItems": 4 + }, "BundleConfig": { "description": "Configuration for tauri-bundler.\n\nSee more: https://tauri.app/v1/api/config#bundleconfig", "type": "object", diff --git a/core/tauri-runtime/src/webview.rs b/core/tauri-runtime/src/webview.rs index 4c463afff..f3193e062 100644 --- a/core/tauri-runtime/src/webview.rs +++ b/core/tauri-runtime/src/webview.rs @@ -9,7 +9,7 @@ use crate::{menu::Menu, window::DetachedWindow, Icon}; #[cfg(target_os = "macos")] use tauri_utils::TitleBarStyle; use tauri_utils::{ - config::{WindowConfig, WindowUrl}, + config::{WindowConfig, WindowEffectsConfig, WindowUrl}, Theme, }; @@ -29,6 +29,7 @@ pub struct WebviewAttributes { pub clipboard: bool, pub accept_first_mouse: bool, pub additional_browser_args: Option, + pub window_effects: Option, } impl WebviewAttributes { @@ -43,6 +44,7 @@ impl WebviewAttributes { clipboard: false, accept_first_mouse: false, additional_browser_args: None, + window_effects: None, } } @@ -97,6 +99,13 @@ impl WebviewAttributes { self.additional_browser_args = Some(additional_args.to_string()); self } + + /// Sets window effects + #[must_use] + pub fn window_effects(mut self, effects: WindowEffectsConfig) -> Self { + self.window_effects = Some(effects); + self + } } /// Do **NOT** implement this trait except for use in a custom [`Runtime`](crate::Runtime). diff --git a/core/tauri-utils/src/config.rs b/core/tauri-utils/src/config.rs index 50aff9d48..3902372bc 100644 --- a/core/tauri-utils/src/config.rs +++ b/core/tauri-utils/src/config.rs @@ -34,7 +34,7 @@ use std::{ /// Items to help with parsing content into a [`Config`]. pub mod parse; -use crate::TitleBarStyle; +use crate::{TitleBarStyle, WindowEffect, WindowEffectState}; pub use self::parse::parse; @@ -747,6 +747,30 @@ pub struct BundleConfig { pub updater: UpdaterConfig, } +/// a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255. +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct Color(pub u8, pub u8, pub u8, pub u8); + +/// The window effects configuration object +#[skip_serializing_none] +#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, Default)] +#[cfg_attr(feature = "schema", derive(JsonSchema))] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +pub struct WindowEffectsConfig { + /// List of Window effects to apply to the Window. + /// Conflicting effects will apply the first one and ignore the rest. + pub effects: Vec, + /// Window effect state **macOS Only** + pub state: Option, + /// Window effect corner radius **macOS Only** + pub radius: Option, + /// Window effect color. Affects [`WindowEffects::Blur`] and [`WindowEffects::Acrylic`] only + /// on Windows 10 v1903+. Doesn't have any effect on Windows 7 or Windows 11. + pub color: Option, +} + /// The window configuration object. /// /// See more: https://tauri.app/v1/api/config#windowconfig @@ -864,6 +888,16 @@ pub struct WindowConfig { /// - **Linux:** Unsupported. #[serde(default = "default_true")] pub shadow: bool, + /// Window effects. + /// + /// Requires the window to be transparent. + /// + /// ## Platform-specific: + /// + /// - **Windows**: If using decorations or shadows, you may want to try this workaround https://github.com/tauri-apps/tao/issues/72#issuecomment-975607891 + /// - **Linux**: Unsupported + #[serde(default, alias = "window-effects")] + pub window_effects: Option, } impl Default for WindowConfig { @@ -900,6 +934,7 @@ impl Default for WindowConfig { tabbing_identifier: None, additional_browser_args: None, shadow: true, + window_effects: None, } } } @@ -1924,7 +1959,7 @@ mod build { ::tauri::utils::config::$struct { $($field: #$field),+ } - }); + }) }; } @@ -1956,6 +1991,23 @@ mod build { } } + impl ToTokens for Color { + fn to_tokens(&self, tokens: &mut TokenStream) { + let Color(r, g, b, a) = self; + tokens.append_all(quote! {::tauri::utils::Color(#r,#g,#b,#a)}); + } + } + impl ToTokens for WindowEffectsConfig { + fn to_tokens(&self, tokens: &mut TokenStream) { + let effects = vec_lit(self.effects.clone(), |d| d); + let state = opt_lit(self.state.as_ref()); + let radius = opt_lit(self.radius.as_ref()); + let color = opt_lit(self.color.as_ref()); + + literal_struct!(tokens, WindowEffectsConfig, effects, state, radius, color) + } + } + impl ToTokens for crate::TitleBarStyle { fn to_tokens(&self, tokens: &mut TokenStream) { let prefix = quote! { ::tauri::utils::TitleBarStyle }; @@ -1968,6 +2020,51 @@ mod build { } } + impl ToTokens for crate::WindowEffect { + fn to_tokens(&self, tokens: &mut TokenStream) { + let prefix = quote! { ::tauri::utils::WindowEffect }; + + #[allow(deprecated)] + tokens.append_all(match self { + WindowEffect::AppearanceBased => quote! { #prefix::AppearanceBased}, + WindowEffect::Light => quote! { #prefix::Light}, + WindowEffect::Dark => quote! { #prefix::Dark}, + WindowEffect::MediumLight => quote! { #prefix::MediumLight}, + WindowEffect::UltraDark => quote! { #prefix::UltraDark}, + WindowEffect::Titlebar => quote! { #prefix::Titlebar}, + WindowEffect::Selection => quote! { #prefix::Selection}, + WindowEffect::Menu => quote! { #prefix::Menu}, + WindowEffect::Popover => quote! { #prefix::Popover}, + WindowEffect::Sidebar => quote! { #prefix::Sidebar}, + WindowEffect::HeaderView => quote! { #prefix::HeaderView}, + WindowEffect::Sheet => quote! { #prefix::Sheet}, + WindowEffect::WindowBackground => quote! { #prefix::WindowBackground}, + WindowEffect::HudWindow => quote! { #prefix::HudWindow}, + WindowEffect::FullScreenUI => quote! { #prefix::FullScreenUI}, + WindowEffect::Tooltip => quote! { #prefix::Tooltip}, + WindowEffect::ContentBackground => quote! { #prefix::ContentBackground}, + WindowEffect::UnderWindowBackground => quote! { #prefix::UnderWindowBackground}, + WindowEffect::UnderPageBackground => quote! { #prefix::UnderPageBackground}, + WindowEffect::Mica => quote! { #prefix::Mica}, + WindowEffect::Blur => quote! { #prefix::Blur}, + WindowEffect::Acrylic => quote! { #prefix::Acrylic}, + }) + } + } + + impl ToTokens for crate::WindowEffectState { + fn to_tokens(&self, tokens: &mut TokenStream) { + let prefix = quote! { ::tauri::utils::WindowEffectState }; + + #[allow(deprecated)] + tokens.append_all(match self { + WindowEffectState::Active => quote! { #prefix::Active}, + WindowEffectState::FollowsWindowActiveState => quote! { #prefix::FollowsWindowActiveState}, + WindowEffectState::Inactive => quote! { #prefix::Inactive}, + }) + } + } + impl ToTokens for WindowConfig { fn to_tokens(&self, tokens: &mut TokenStream) { let label = str_lit(&self.label); @@ -2001,6 +2098,7 @@ mod build { let tabbing_identifier = opt_str_lit(self.tabbing_identifier.as_ref()); let additional_browser_args = opt_str_lit(self.additional_browser_args.as_ref()); let shadow = self.shadow; + let window_effects = opt_lit(self.window_effects.as_ref()); literal_struct!( tokens, @@ -2035,7 +2133,8 @@ mod build { accept_first_mouse, tabbing_identifier, additional_browser_args, - shadow + shadow, + window_effects ); } } diff --git a/core/tauri-utils/src/lib.rs b/core/tauri-utils/src/lib.rs index dec1ed7cc..7b22dc686 100644 --- a/core/tauri-utils/src/lib.rs +++ b/core/tauri-utils/src/lib.rs @@ -4,6 +4,7 @@ //! Tauri utility helpers #![warn(missing_docs, rust_2018_idioms)] +#![allow(clippy::deprecated_semver)] use std::{ fmt::Display, @@ -55,6 +56,95 @@ impl PackageInfo { } } +#[allow(deprecated)] +mod window_effects { + use super::*; + + #[derive(Debug, PartialEq, Eq, Clone, Copy, Deserialize, Serialize)] + #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] + #[serde(rename_all = "camelCase")] + /// Platform-specific window effects + pub enum WindowEffect { + /// A default material appropriate for the view's effectiveAppearance. **macOS 10.14-** + #[deprecated( + since = "macOS 10.14", + note = "You should instead choose an appropriate semantic material." + )] + AppearanceBased, + /// **macOS 10.14-** + #[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")] + Light, + /// **macOS 10.14-** + #[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")] + Dark, + /// **macOS 10.14-** + #[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")] + MediumLight, + /// **macOS 10.14-** + #[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")] + UltraDark, + /// **macOS 10.10+** + Titlebar, + /// **macOS 10.10+** + Selection, + /// **macOS 10.11+** + Menu, + /// **macOS 10.11+** + Popover, + /// **macOS 10.11+** + Sidebar, + /// **macOS 10.14+** + HeaderView, + /// **macOS 10.14+** + Sheet, + /// **macOS 10.14+** + WindowBackground, + /// **macOS 10.14+** + HudWindow, + /// **macOS 10.14+** + FullScreenUI, + /// **macOS 10.14+** + Tooltip, + /// **macOS 10.14+** + ContentBackground, + /// **macOS 10.14+** + UnderWindowBackground, + /// **macOS 10.14+** + UnderPageBackground, + /// **Windows 11 Only** + Mica, + /// **Windows 7/10/11(22H1) Only** + /// + /// ## Notes + /// + /// This effect has bad performance when resizing/dragging the window on Windows 11 build 22621. + Blur, + /// **Windows 10/11 Only** + /// + /// ## Notes + /// + /// This effect has bad performance when resizing/dragging the window on Windows 10 v1903+ and Windows 11 build 22000. + Acrylic, + } + + /// Window effect state **macOS only** + /// + /// + #[derive(Debug, PartialEq, Eq, Clone, Copy, Deserialize, Serialize)] + #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] + #[serde(rename_all = "camelCase")] + pub enum WindowEffectState { + /// Make window effect state follow the window's active state + FollowsWindowActiveState, + /// Make window effect state always active + Active, + /// Make window effect state always inactive + Inactive, + } +} + +pub use window_effects::{WindowEffect, WindowEffectState}; + /// How the window title bar should be displayed on macOS. #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] diff --git a/core/tauri-utils/src/platform.rs b/core/tauri-utils/src/platform.rs index 5e2e77192..0ca4fd617 100644 --- a/core/tauri-utils/src/platform.rs +++ b/core/tauri-utils/src/platform.rs @@ -204,7 +204,7 @@ pub fn resource_dir(package_info: &PackageInfo, env: &Env) -> crate::Result Option { + /// Helper function to dynamically load function pointer. + /// `library` and `function` must be null-terminated. + pub fn get_function_impl(library: &str, function: &str) -> Option { let library = encode_wide(library); assert_eq!(function.chars().last(), Some('\0')); let function = PCSTR::from_raw(function.as_ptr()); diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index 2cc10f3e2..791f2b147 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -1289,6 +1289,7 @@ impl Builder { for config in manager.config().tauri.windows.clone() { let url = config.url.clone(); let label = config.label.clone(); + let window_effects = config.window_effects.clone(); let mut webview_attributes = WebviewAttributes::new(url).accept_first_mouse(config.accept_first_mouse); @@ -1301,6 +1302,9 @@ impl Builder { if !config.file_drop_enabled { webview_attributes = webview_attributes.disable_file_drop_handler(); } + if let Some(effects) = window_effects { + webview_attributes = webview_attributes.window_effects(effects); + } self.pending_windows.push(PendingWindow::with_config( config, @@ -1430,13 +1434,18 @@ fn setup(app: &mut App) -> crate::Result<()> { app .manager .prepare_window(app.handle.clone(), pending, &window_labels, None)?; + let window_effects = pending.webview_attributes.window_effects.clone(); let detached = if let RuntimeOrDispatch::RuntimeHandle(runtime) = app.handle().runtime() { runtime.create_window(pending)? } else { // the AppHandle's runtime is always RuntimeOrDispatch::RuntimeHandle unreachable!() }; - let _window = app.manager.attach_window(app.handle(), detached); + let window = app.manager.attach_window(app.handle(), detached); + + if let Some(effects) = window_effects { + crate::vibrancy::set_window_effects(&window, Some(effects))?; + } } } diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index 15db364d4..bb59a2279 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -76,6 +76,7 @@ mod hooks; mod manager; mod pattern; pub mod plugin; +mod vibrancy; pub mod window; use tauri_runtime as runtime; #[cfg(target_os = "ios")] diff --git a/core/tauri/src/vibrancy/macos.rs b/core/tauri/src/vibrancy/macos.rs new file mode 100644 index 000000000..c60476938 --- /dev/null +++ b/core/tauri/src/vibrancy/macos.rs @@ -0,0 +1,300 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +#![cfg(target_os = "macos")] +#![allow(deprecated)] + +use crate::utils::config::WindowEffectsConfig; +use crate::window::{Effect, EffectState}; +use cocoa::{ + appkit::{ + NSAppKitVersionNumber, NSAppKitVersionNumber10_10, NSAppKitVersionNumber10_11, + NSAutoresizingMaskOptions, NSView, NSViewHeightSizable, NSViewWidthSizable, NSWindow, + NSWindowOrderingMode, + }, + base::{id, nil, BOOL}, + foundation::{NSAutoreleasePool, NSPoint, NSRect, NSSize}, +}; +use objc::{class, msg_send, sel, sel_impl}; + +pub fn apply_effects(window: id, effects: WindowEffectsConfig) { + let WindowEffectsConfig { + effects, + radius, + state, + .. + } = effects; + let mut appearance: NSVisualEffectMaterial = if let Some(effect) = effects.into_iter().find(|e| { + matches!( + e, + Effect::AppearanceBased + | Effect::Light + | Effect::Dark + | Effect::MediumLight + | Effect::UltraDark + | Effect::Titlebar + | Effect::Selection + | Effect::Menu + | Effect::Popover + | Effect::Sidebar + | Effect::HeaderView + | Effect::Sheet + | Effect::WindowBackground + | Effect::HudWindow + | Effect::FullScreenUI + | Effect::Tooltip + | Effect::ContentBackground + | Effect::UnderWindowBackground + | Effect::UnderPageBackground + ) + }) { + effect.into() + } else { + return; + }; + + unsafe { + if NSAppKitVersionNumber < NSAppKitVersionNumber10_10 { + return; + } + + if !msg_send![class!(NSThread), isMainThread] { + return; + } + + if appearance as u32 > 9 && NSAppKitVersionNumber < NSAppKitVersionNumber10_14 { + appearance = NSVisualEffectMaterial::AppearanceBased; + } else if appearance as u32 > 4 && NSAppKitVersionNumber < NSAppKitVersionNumber10_11 { + appearance = NSVisualEffectMaterial::AppearanceBased; + } + + let ns_view: id = window.contentView(); + let bounds = NSView::bounds(ns_view); + + let blurred_view = NSVisualEffectView::initWithFrame_(NSVisualEffectView::alloc(nil), bounds); + blurred_view.autorelease(); + + blurred_view.setMaterial_(appearance); + blurred_view.setCornerRadius_(radius.unwrap_or(0.0)); + blurred_view.setBlendingMode_(NSVisualEffectBlendingMode::BehindWindow); + blurred_view.setState_( + state + .map(Into::into) + .unwrap_or(NSVisualEffectState::FollowsWindowActiveState), + ); + NSVisualEffectView::setAutoresizingMask_( + blurred_view, + NSViewWidthSizable | NSViewHeightSizable, + ); + + let _: () = msg_send![ns_view, addSubview: blurred_view positioned: NSWindowOrderingMode::NSWindowBelow relativeTo: 0]; + } +} + +#[allow(non_upper_case_globals)] +const NSAppKitVersionNumber10_14: f64 = 1671.0; + +// https://developer.apple.com/documentation/appkit/nsvisualeffectview/blendingmode +#[allow(dead_code)] +#[repr(u64)] +#[derive(Clone, Copy, Debug, PartialEq)] +enum NSVisualEffectBlendingMode { + BehindWindow = 0, + WithinWindow = 1, +} + +// macos 10.10+ +// https://developer.apple.com/documentation/appkit/nsvisualeffectview +#[allow(non_snake_case)] +trait NSVisualEffectView: Sized { + unsafe fn alloc(_: Self) -> id { + msg_send![class!(NSVisualEffectView), alloc] + } + + unsafe fn init(self) -> id; + unsafe fn initWithFrame_(self, frameRect: NSRect) -> id; + unsafe fn bounds(self) -> NSRect; + unsafe fn frame(self) -> NSRect; + unsafe fn setFrameSize(self, frameSize: NSSize); + unsafe fn setFrameOrigin(self, frameOrigin: NSPoint); + + unsafe fn superview(self) -> id; + unsafe fn removeFromSuperview(self); + unsafe fn setAutoresizingMask_(self, autoresizingMask: NSAutoresizingMaskOptions); + + // API_AVAILABLE(macos(10.12)); + unsafe fn isEmphasized(self) -> BOOL; + // API_AVAILABLE(macos(10.12)); + unsafe fn setEmphasized_(self, emphasized: BOOL); + + unsafe fn setMaterial_(self, material: NSVisualEffectMaterial); + unsafe fn setCornerRadius_(self, radius: f64); + unsafe fn setState_(self, state: NSVisualEffectState); + unsafe fn setBlendingMode_(self, mode: NSVisualEffectBlendingMode); +} + +#[allow(non_snake_case)] +impl NSVisualEffectView for id { + unsafe fn init(self) -> id { + msg_send![self, init] + } + + unsafe fn initWithFrame_(self, frameRect: NSRect) -> id { + msg_send![self, initWithFrame: frameRect] + } + + unsafe fn bounds(self) -> NSRect { + msg_send![self, bounds] + } + + unsafe fn frame(self) -> NSRect { + msg_send![self, frame] + } + + unsafe fn setFrameSize(self, frameSize: NSSize) { + msg_send![self, setFrameSize: frameSize] + } + + unsafe fn setFrameOrigin(self, frameOrigin: NSPoint) { + msg_send![self, setFrameOrigin: frameOrigin] + } + + unsafe fn superview(self) -> id { + msg_send![self, superview] + } + + unsafe fn removeFromSuperview(self) { + msg_send![self, removeFromSuperview] + } + + unsafe fn setAutoresizingMask_(self, autoresizingMask: NSAutoresizingMaskOptions) { + msg_send![self, setAutoresizingMask: autoresizingMask] + } + + // API_AVAILABLE(macos(10.12)); + unsafe fn isEmphasized(self) -> BOOL { + msg_send![self, isEmphasized] + } + + // API_AVAILABLE(macos(10.12)); + unsafe fn setEmphasized_(self, emphasized: BOOL) { + msg_send![self, setEmphasized: emphasized] + } + + unsafe fn setMaterial_(self, material: NSVisualEffectMaterial) { + msg_send![self, setMaterial: material] + } + + unsafe fn setCornerRadius_(self, radius: f64) { + msg_send![self, setCornerRadius: radius] + } + + unsafe fn setState_(self, state: NSVisualEffectState) { + msg_send![self, setState: state] + } + + unsafe fn setBlendingMode_(self, mode: NSVisualEffectBlendingMode) { + msg_send![self, setBlendingMode: mode] + } +} + +/// +#[repr(u64)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum NSVisualEffectMaterial { + #[deprecated( + since = "macOS 10.14", + note = "A default material appropriate for the view's effectiveAppearance. You should instead choose an appropriate semantic material." + )] + AppearanceBased = 0, + #[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")] + Light = 1, + #[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")] + Dark = 2, + #[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")] + MediumLight = 8, + #[deprecated(since = "macOS 10.14", note = "Use a semantic material instead.")] + UltraDark = 9, + + /// macOS 10.10+ + Titlebar = 3, + /// macOS 10.10+ + Selection = 4, + + /// macOS 10.11+ + Menu = 5, + /// macOS 10.11+ + Popover = 6, + /// macOS 10.11+ + Sidebar = 7, + + /// macOS 10.14+ + HeaderView = 10, + /// macOS 10.14+ + Sheet = 11, + /// macOS 10.14+ + WindowBackground = 12, + /// macOS 10.14+ + HudWindow = 13, + /// macOS 10.14+ + FullScreenUI = 15, + /// macOS 10.14+ + Tooltip = 17, + /// macOS 10.14+ + ContentBackground = 18, + /// macOS 10.14+ + UnderWindowBackground = 21, + /// macOS 10.14+ + UnderPageBackground = 22, +} + +/// +#[allow(dead_code)] +#[repr(u64)] +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum NSVisualEffectState { + /// Make window vibrancy state follow the window's active state + FollowsWindowActiveState = 0, + /// Make window vibrancy state always active + Active = 1, + /// Make window vibrancy state always inactive + Inactive = 2, +} + +impl From for NSVisualEffectMaterial { + fn from(value: crate::window::Effect) -> Self { + match value { + Effect::AppearanceBased => NSVisualEffectMaterial::AppearanceBased, + Effect::Light => NSVisualEffectMaterial::Light, + Effect::Dark => NSVisualEffectMaterial::Dark, + Effect::MediumLight => NSVisualEffectMaterial::MediumLight, + Effect::UltraDark => NSVisualEffectMaterial::UltraDark, + Effect::Titlebar => NSVisualEffectMaterial::Titlebar, + Effect::Selection => NSVisualEffectMaterial::Selection, + Effect::Menu => NSVisualEffectMaterial::Menu, + Effect::Popover => NSVisualEffectMaterial::Popover, + Effect::Sidebar => NSVisualEffectMaterial::Sidebar, + Effect::HeaderView => NSVisualEffectMaterial::HeaderView, + Effect::Sheet => NSVisualEffectMaterial::Sheet, + Effect::WindowBackground => NSVisualEffectMaterial::WindowBackground, + Effect::HudWindow => NSVisualEffectMaterial::HudWindow, + Effect::FullScreenUI => NSVisualEffectMaterial::FullScreenUI, + Effect::Tooltip => NSVisualEffectMaterial::Tooltip, + Effect::ContentBackground => NSVisualEffectMaterial::ContentBackground, + Effect::UnderWindowBackground => NSVisualEffectMaterial::UnderWindowBackground, + Effect::UnderPageBackground => NSVisualEffectMaterial::UnderPageBackground, + Effect::Mica | Effect::Blur | Effect::Acrylic => unreachable!(), + } + } +} + +impl From for NSVisualEffectState { + fn from(value: crate::window::EffectState) -> Self { + match value { + EffectState::FollowsWindowActiveState => NSVisualEffectState::FollowsWindowActiveState, + EffectState::Active => NSVisualEffectState::Active, + EffectState::Inactive => NSVisualEffectState::Inactive, + } + } +} diff --git a/core/tauri/src/vibrancy/mod.rs b/core/tauri/src/vibrancy/mod.rs new file mode 100644 index 000000000..2ede80e97 --- /dev/null +++ b/core/tauri/src/vibrancy/mod.rs @@ -0,0 +1,39 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +#![allow(unused)] + +use tauri_utils::config::WindowEffectsConfig; + +use crate::{Runtime, Window}; + +#[cfg(target_os = "macos")] +mod macos; +#[cfg(windows)] +mod windows; + +pub fn set_window_effects( + window: &Window, + effects: Option, +) -> crate::Result<()> { + if let Some(_effects) = effects { + #[cfg(windows)] + { + let hwnd = window.hwnd()?; + windows::apply_effects(hwnd, _effects); + } + #[cfg(target_os = "macos")] + { + let ns_window = window.ns_window()?; + macos::apply_effects(ns_window as _, _effects); + } + } else { + #[cfg(windows)] + { + let hwnd = window.hwnd()?; + windows::clear_effects(hwnd); + } + } + Ok(()) +} diff --git a/core/tauri/src/vibrancy/windows.rs b/core/tauri/src/vibrancy/windows.rs new file mode 100644 index 000000000..bc3ac9926 --- /dev/null +++ b/core/tauri/src/vibrancy/windows.rs @@ -0,0 +1,249 @@ +// Copyright 2019-2023 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +#![cfg(windows)] +#![allow(non_snake_case)] +#![allow(non_camel_case_types)] +#![allow(clippy::upper_case_acronyms)] + +use std::ffi::c_void; + +use crate::utils::config::WindowEffectsConfig; +use crate::window::{Color, Effect}; +use tauri_utils::platform::{get_function_impl, is_windows_7, windows_version}; +use windows::Win32::Graphics::Dwm::{DwmSetWindowAttribute, DWMWINDOWATTRIBUTE}; +use windows::Win32::{ + Foundation::{BOOL, HWND}, + Graphics::{ + Dwm::{DwmEnableBlurBehindWindow, DWM_BB_ENABLE, DWM_BLURBEHIND}, + Gdi::HRGN, + }, +}; + +pub fn apply_effects(window: HWND, effects: WindowEffectsConfig) { + let WindowEffectsConfig { effects, color, .. } = effects; + let effect = if let Some(effect) = effects + .iter() + .find(|e| matches!(e, Effect::Mica | Effect::Acrylic | Effect::Blur)) + { + effect + } else { + return; + }; + + match effect { + Effect::Blur => apply_blur(window, color), + Effect::Acrylic => apply_acrylic(window, color), + Effect::Mica => apply_mica(window), + _ => unreachable!(), + } +} + +pub fn clear_effects(window: HWND) { + clear_blur(window); + clear_acrylic(window); + clear_mica(window); +} + +pub fn apply_blur(hwnd: HWND, color: Option) { + if is_windows_7() { + let bb = DWM_BLURBEHIND { + dwFlags: DWM_BB_ENABLE, + fEnable: true.into(), + hRgnBlur: HRGN::default(), + fTransitionOnMaximized: false.into(), + }; + let _ = unsafe { DwmEnableBlurBehindWindow(hwnd, &bb) }; + } else if is_swca_supported() { + unsafe { SetWindowCompositionAttribute(hwnd, ACCENT_STATE::ACCENT_ENABLE_BLURBEHIND, color) }; + } else { + return; + } +} + +fn clear_blur(hwnd: HWND) { + if is_windows_7() { + let bb = DWM_BLURBEHIND { + dwFlags: DWM_BB_ENABLE, + fEnable: false.into(), + hRgnBlur: HRGN::default(), + fTransitionOnMaximized: false.into(), + }; + let _ = unsafe { DwmEnableBlurBehindWindow(hwnd, &bb) }; + } else if is_swca_supported() { + unsafe { SetWindowCompositionAttribute(hwnd, ACCENT_STATE::ACCENT_DISABLED, None) }; + } else { + return; + } +} + +pub fn apply_acrylic(hwnd: HWND, color: Option) { + if is_backdroptype_supported() { + unsafe { + let _ = DwmSetWindowAttribute( + hwnd, + DWMWA_SYSTEMBACKDROP_TYPE, + &DWM_SYSTEMBACKDROP_TYPE::DWMSBT_TRANSIENTWINDOW as *const _ as _, + 4, + ); + } + } else if is_swca_supported() { + unsafe { + SetWindowCompositionAttribute(hwnd, ACCENT_STATE::ACCENT_ENABLE_ACRYLICBLURBEHIND, color); + } + } else { + return; + } +} + +pub fn clear_acrylic(hwnd: HWND) { + if is_backdroptype_supported() { + unsafe { + let _ = DwmSetWindowAttribute( + hwnd, + DWMWA_SYSTEMBACKDROP_TYPE, + &DWM_SYSTEMBACKDROP_TYPE::DWMSBT_DISABLE as *const _ as _, + 4, + ); + } + } else if is_swca_supported() { + unsafe { SetWindowCompositionAttribute(hwnd, ACCENT_STATE::ACCENT_DISABLED, None) }; + } else { + return; + } +} + +pub fn apply_mica(hwnd: HWND) { + if is_backdroptype_supported() { + unsafe { + let _ = DwmSetWindowAttribute( + hwnd, + DWMWA_SYSTEMBACKDROP_TYPE, + &DWM_SYSTEMBACKDROP_TYPE::DWMSBT_MAINWINDOW as *const _ as _, + 4, + ); + } + } else if is_undocumented_mica_supported() { + let _ = unsafe { DwmSetWindowAttribute(hwnd, DWMWA_MICA_EFFECT, &1 as *const _ as _, 4) }; + } else { + return; + } +} + +pub fn clear_mica(hwnd: HWND) { + if is_backdroptype_supported() { + unsafe { + let _ = DwmSetWindowAttribute( + hwnd, + DWMWA_SYSTEMBACKDROP_TYPE, + &DWM_SYSTEMBACKDROP_TYPE::DWMSBT_DISABLE as *const _ as _, + 4, + ); + } + } else if is_undocumented_mica_supported() { + let _ = unsafe { DwmSetWindowAttribute(hwnd, DWMWA_MICA_EFFECT, &0 as *const _ as _, 4) }; + } else { + return; + } +} + +const DWMWA_MICA_EFFECT: DWMWINDOWATTRIBUTE = DWMWINDOWATTRIBUTE(1029i32); +const DWMWA_SYSTEMBACKDROP_TYPE: DWMWINDOWATTRIBUTE = DWMWINDOWATTRIBUTE(38i32); + +#[repr(C)] +struct ACCENT_POLICY { + AccentState: u32, + AccentFlags: u32, + GradientColor: u32, + AnimationId: u32, +} + +type WINDOWCOMPOSITIONATTRIB = u32; + +#[repr(C)] +struct WINDOWCOMPOSITIONATTRIBDATA { + Attrib: WINDOWCOMPOSITIONATTRIB, + pvData: *mut c_void, + cbData: usize, +} + +#[derive(PartialEq)] +#[repr(C)] +enum ACCENT_STATE { + ACCENT_DISABLED = 0, + ACCENT_ENABLE_BLURBEHIND = 3, + ACCENT_ENABLE_ACRYLICBLURBEHIND = 4, +} + +macro_rules! get_function { + ($lib:expr, $func:ident) => { + get_function_impl(concat!($lib, '\0'), concat!(stringify!($func), '\0')) + .map(|f| unsafe { std::mem::transmute::(f) }) + }; +} + +unsafe fn SetWindowCompositionAttribute( + hwnd: HWND, + accent_state: ACCENT_STATE, + color: Option, +) { + type SetWindowCompositionAttribute = + unsafe extern "system" fn(HWND, *mut WINDOWCOMPOSITIONATTRIBDATA) -> BOOL; + + if let Some(set_window_composition_attribute) = + get_function!("user32.dll", SetWindowCompositionAttribute) + { + let mut color = color.unwrap_or_default(); + + let is_acrylic = accent_state == ACCENT_STATE::ACCENT_ENABLE_ACRYLICBLURBEHIND; + if is_acrylic && color.3 == 0 { + // acrylic doesn't like to have 0 alpha + color.3 = 1; + } + + let mut policy = ACCENT_POLICY { + AccentState: accent_state as _, + AccentFlags: if is_acrylic { 0 } else { 2 }, + GradientColor: (color.0 as u32) + | (color.1 as u32) << 8 + | (color.2 as u32) << 16 + | (color.3 as u32) << 24, + AnimationId: 0, + }; + + let mut data = WINDOWCOMPOSITIONATTRIBDATA { + Attrib: 0x13, + pvData: &mut policy as *mut _ as _, + cbData: std::mem::size_of_val(&policy), + }; + + set_window_composition_attribute(hwnd, &mut data as *mut _ as _); + } +} + +#[allow(unused)] +#[repr(C)] +enum DWM_SYSTEMBACKDROP_TYPE { + DWMSBT_DISABLE = 1, // None + DWMSBT_MAINWINDOW = 2, // Mica + DWMSBT_TRANSIENTWINDOW = 3, // Acrylic + DWMSBT_TABBEDWINDOW = 4, // Tabbed +} + +fn is_swca_supported() -> bool { + is_at_least_build(17763) +} + +fn is_undocumented_mica_supported() -> bool { + is_at_least_build(22000) +} + +fn is_backdroptype_supported() -> bool { + is_at_least_build(22523) +} + +fn is_at_least_build(build: u32) -> bool { + let v = windows_version().unwrap_or_default(); + v.2 >= build +} diff --git a/core/tauri/src/window.rs b/core/tauri/src/window.rs index 0bfab5ea4..2933a8044 100644 --- a/core/tauri/src/window.rs +++ b/core/tauri/src/window.rs @@ -7,6 +7,7 @@ pub(crate) mod menu; pub use menu::{MenuEvent, MenuHandle}; +pub use tauri_utils::{config::Color, WindowEffect as Effect, WindowEffectState as EffectState}; use url::Url; #[cfg(target_os = "macos")] @@ -30,7 +31,7 @@ use crate::{ }, sealed::ManagerBase, sealed::RuntimeOrDispatch, - utils::config::{WindowConfig, WindowUrl}, + utils::config::{WindowConfig, WindowEffectsConfig, WindowUrl}, EventLoopMessage, Invoke, InvokeError, InvokeMessage, InvokeResolver, Manager, PageLoadPayload, Runtime, Theme, WindowEvent, }; @@ -226,6 +227,10 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> { let app_handle = manager.app_handle(); let url = config.url.clone(); let file_drop_enabled = config.file_drop_enabled; + let mut webview_attributes = WebviewAttributes::new(url); + if let Some(effects) = config.window_effects.clone() { + webview_attributes = webview_attributes.window_effects(effects); + } let mut builder = Self { manager: manager.manager().clone(), runtime, @@ -234,7 +239,7 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> { window_builder: >::WindowBuilder::with_config( config, ), - webview_attributes: WebviewAttributes::new(url), + webview_attributes, web_resource_request_handler: None, navigation_handler: None, }; @@ -333,7 +338,7 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> { &labels, web_resource_request_handler, )?; - + let window_effects = pending.webview_attributes.window_effects.clone(); let window = match &mut self.runtime { RuntimeOrDispatch::Runtime(runtime) => runtime.create_window(pending), RuntimeOrDispatch::RuntimeHandle(handle) => handle.create_window(pending), @@ -341,6 +346,9 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> { } .map(|window| self.manager.attach_window(self.app_handle.clone(), window))?; + if let Some(effects) = window_effects { + crate::vibrancy::set_window_effects(&window, Some(effects))?; + } self.manager.eval_script_all(format!( "window.__TAURI_METADATA__.__windows = {window_labels_array}.map(function (label) {{ return {{ label: label }} }})", window_labels_array = serde_json::to_string(&self.manager.labels())?, @@ -604,6 +612,19 @@ impl<'a, R: Runtime> WindowBuilder<'a, R> { self.webview_attributes.accept_first_mouse = accept; self } + + /// Sets window effects. + /// + /// Requires the window to be transparent. + /// + /// ## Platform-specific: + /// + /// - **Windows**: If using decorations or shadows, you may want to try this workaround https://github.com/tauri-apps/tao/issues/72#issuecomment-975607891 + /// - **Linux**: Unsupported + pub fn effects(mut self, effects: WindowEffectsConfig) -> Self { + self.webview_attributes = self.webview_attributes.window_effects(effects); + self + } } /// Webview attributes. @@ -1301,6 +1322,42 @@ impl Window { .map_err(Into::into) } + /// Sets window effects, pass [`None`] to clear any effects applied if possible. + /// + /// Requires the window to be transparent. + /// + /// See [`EffectsBuilder`] for a convenient builder for [`WindowEffectsConfig`]. + /// + /// + /// ```rust,no_run + /// use tauri::{Manager, window::{Color, Effect, EffectState, EffectsBuilder}}; + /// tauri::Builder::default() + /// .setup(|app| { + /// let window = app.get_window("main").unwrap(); + /// window.set_effects( + /// EffectsBuilder::new() + /// .effect(Effect::Popover) + /// .state(EffectState::Active) + /// .radius(5.) + /// .color(Color(0, 0, 0, 255)) + /// .build(), + /// )?; + /// Ok(()) + /// }); + /// ``` + /// + /// ## Platform-specific: + /// + /// - **Windows**: If using decorations or shadows, you may want to try this workaround https://github.com/tauri-apps/tao/issues/72#issuecomment-975607891 + /// - **Linux**: Unsupported + pub fn set_effects>>(&self, effects: E) -> crate::Result<()> { + let effects = effects.into(); + let window = self.clone(); + self.run_on_main_thread(move || { + let _ = crate::vibrancy::set_window_effects(&window, effects); + }) + } + /// Determines if this window should always be on top of other windows. pub fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()> { self @@ -1898,6 +1955,61 @@ impl Window { } } +/// The [`WindowEffectsConfig`] object builder +#[derive(Default)] +pub struct EffectsBuilder(WindowEffectsConfig); +impl EffectsBuilder { + /// Create a new [`WindowEffectsConfig`] builder + pub fn new() -> Self { + Self(WindowEffectsConfig::default()) + } + + /// Adds effect to the [`WindowEffectsConfig`] `effects` field + pub fn effect(mut self, effect: Effect) -> Self { + self.0.effects.push(effect); + self + } + + /// Adds effects to the [`WindowEffectsConfig`] `effects` field + pub fn effects>(mut self, effects: I) -> Self { + self.0.effects.extend(effects); + self + } + + /// Clears the [`WindowEffectsConfig`] `effects` field + pub fn clear_effects(mut self) -> Self { + self.0.effects.clear(); + self + } + + /// Sets `state` field for the [`WindowEffectsConfig`] **macOS Only** + pub fn state(mut self, state: EffectState) -> Self { + self.0.state = Some(state); + self + } + /// Sets `radius` field fo the [`WindowEffectsConfig`] **macOS Only** + pub fn radius(mut self, radius: f64) -> Self { + self.0.radius = Some(radius); + self + } + /// Sets `color` field fo the [`WindowEffectsConfig`] **Windows Only** + pub fn color(mut self, color: Color) -> Self { + self.0.color = Some(color); + self + } + + /// Builds a [`WindowEffectsConfig`] + pub fn build(self) -> WindowEffectsConfig { + self.0 + } +} + +impl From for EffectsBuilder { + fn from(value: WindowEffectsConfig) -> Self { + Self(value) + } +} + pub(crate) const IPC_SCOPE_DOES_NOT_ALLOW: &str = "Not allowed by the scope"; pub(crate) fn ipc_scope_not_found_error_message(label: &str, url: &str) -> String { diff --git a/examples/api/src-tauri/Cargo.lock b/examples/api/src-tauri/Cargo.lock index ce325e31e..480f87dbe 100644 --- a/examples/api/src-tauri/Cargo.lock +++ b/examples/api/src-tauri/Cargo.lock @@ -2967,7 +2967,7 @@ checksum = "fd1ba337640d60c3e96bc6f0638a939b9c9a7f2c316a1598c279828b3d1dc8c5" [[package]] name = "tauri" -version = "2.0.0-alpha.8" +version = "2.0.0-alpha.9" dependencies = [ "anyhow", "bytes", @@ -3016,7 +3016,7 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "anyhow", "cargo_toml", @@ -3035,7 +3035,7 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "base64 0.21.0", "brotli", @@ -3059,7 +3059,7 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "heck", "proc-macro2", @@ -3115,7 +3115,7 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "0.13.0-alpha.4" +version = "0.13.0-alpha.5" dependencies = [ "gtk", "http", @@ -3134,7 +3134,7 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "0.13.0-alpha.4" +version = "0.13.0-alpha.5" dependencies = [ "cocoa", "gtk", @@ -3153,7 +3153,7 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.0.0-alpha.4" +version = "2.0.0-alpha.5" dependencies = [ "aes-gcm", "brotli", diff --git a/tooling/api/docs/js-api.json b/tooling/api/docs/js-api.json index 4641c4414..9715719eb 100644 --- a/tooling/api/docs/js-api.json +++ b/tooling/api/docs/js-api.json @@ -1 +1 @@ -{"id":0,"name":"@tauri-apps/api","kind":1,"flags":{},"originalName":"","children":[{"id":1,"name":"event","kind":2,"kindString":"Module","flags":{},"comment":{"summary":[{"kind":"text","text":"The event system allows you to emit events to the backend and listen to events from it.\n\nThis package is also accessible with "},{"kind":"code","text":"`window.__TAURI__.event`"},{"kind":"text","text":" when ["},{"kind":"code","text":"`build.withGlobalTauri`"},{"kind":"text","text":"](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in "},{"kind":"code","text":"`tauri.conf.json`"},{"kind":"text","text":" is set to "},{"kind":"code","text":"`true`"},{"kind":"text","text":"."}]},"children":[{"id":3,"name":"TauriEvent","kind":8,"kindString":"Enumeration","flags":{},"comment":{"summary":[],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.1.0"}]}]},"children":[{"id":16,"name":"MENU","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":33,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L33"}],"type":{"type":"literal","value":"tauri://menu"}},{"id":10,"name":"WINDOW_BLUR","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":27,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L27"}],"type":{"type":"literal","value":"tauri://blur"}},{"id":6,"name":"WINDOW_CLOSE_REQUESTED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":23,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L23"}],"type":{"type":"literal","value":"tauri://close-requested"}},{"id":7,"name":"WINDOW_CREATED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":24,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L24"}],"type":{"type":"literal","value":"tauri://window-created"}},{"id":8,"name":"WINDOW_DESTROYED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":25,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L25"}],"type":{"type":"literal","value":"tauri://destroyed"}},{"id":13,"name":"WINDOW_FILE_DROP","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":30,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L30"}],"type":{"type":"literal","value":"tauri://file-drop"}},{"id":15,"name":"WINDOW_FILE_DROP_CANCELLED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":32,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L32"}],"type":{"type":"literal","value":"tauri://file-drop-cancelled"}},{"id":14,"name":"WINDOW_FILE_DROP_HOVER","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":31,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L31"}],"type":{"type":"literal","value":"tauri://file-drop-hover"}},{"id":9,"name":"WINDOW_FOCUS","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":26,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L26"}],"type":{"type":"literal","value":"tauri://focus"}},{"id":5,"name":"WINDOW_MOVED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":22,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L22"}],"type":{"type":"literal","value":"tauri://move"}},{"id":4,"name":"WINDOW_RESIZED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":21,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L21"}],"type":{"type":"literal","value":"tauri://resize"}},{"id":11,"name":"WINDOW_SCALE_FACTOR_CHANGED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":28,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L28"}],"type":{"type":"literal","value":"tauri://scale-change"}},{"id":12,"name":"WINDOW_THEME_CHANGED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":29,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L29"}],"type":{"type":"literal","value":"tauri://theme-changed"}}],"groups":[{"title":"Enumeration Members","children":[16,10,6,7,8,13,15,14,9,5,4,11,12]}],"sources":[{"fileName":"event.ts","line":20,"character":12,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L20"}]},{"id":106,"name":"Event","kind":256,"kindString":"Interface","flags":{},"children":[{"id":107,"name":"event","kind":1024,"kindString":"Property","flags":{},"comment":{"summary":[{"kind":"text","text":"Event name"}]},"sources":[{"fileName":"helpers/event.ts","line":10,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L10"}],"type":{"type":"reference","id":2,"name":"EventName"}},{"id":109,"name":"id","kind":1024,"kindString":"Property","flags":{},"comment":{"summary":[{"kind":"text","text":"Event identifier used to unlisten"}]},"sources":[{"fileName":"helpers/event.ts","line":14,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L14"}],"type":{"type":"intrinsic","name":"number"}},{"id":110,"name":"payload","kind":1024,"kindString":"Property","flags":{},"comment":{"summary":[{"kind":"text","text":"Event payload"}]},"sources":[{"fileName":"helpers/event.ts","line":16,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L16"}],"type":{"type":"reference","id":111,"name":"T"}},{"id":108,"name":"windowLabel","kind":1024,"kindString":"Property","flags":{},"comment":{"summary":[{"kind":"text","text":"The label of the window that emitted this event."}]},"sources":[{"fileName":"helpers/event.ts","line":12,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L12"}],"type":{"type":"intrinsic","name":"string"}}],"groups":[{"title":"Properties","children":[107,109,110,108]}],"sources":[{"fileName":"helpers/event.ts","line":8,"character":17,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L8"}],"typeParameters":[{"id":111,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}]},{"id":112,"name":"EventCallback","kind":4194304,"kindString":"Type alias","flags":{},"sources":[{"fileName":"helpers/event.ts","line":19,"character":12,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L19"}],"typeParameters":[{"id":116,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"type":{"type":"reflection","declaration":{"id":113,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"helpers/event.ts","line":19,"character":31,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L19"}],"signatures":[{"id":114,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":115,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":106,"typeArguments":[{"type":"reference","id":116,"name":"T"}],"name":"Event"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"id":2,"name":"EventName","kind":4194304,"kindString":"Type alias","flags":{},"sources":[{"fileName":"event.ts","line":15,"character":12,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L15"}],"type":{"type":"union","types":[{"type":"template-literal","head":"","tail":[[{"type":"reference","id":3,"name":"TauriEvent"},""]]},{"type":"intersection","types":[{"type":"intrinsic","name":"string"},{"type":"reference","typeArguments":[{"type":"intrinsic","name":"never"},{"type":"intrinsic","name":"never"}],"name":"Record","qualifiedName":"Record","package":"typescript"}]}]}},{"id":117,"name":"UnlistenFn","kind":4194304,"kindString":"Type alias","flags":{},"sources":[{"fileName":"helpers/event.ts","line":21,"character":12,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L21"}],"type":{"type":"reflection","declaration":{"id":118,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"helpers/event.ts","line":21,"character":25,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/helpers/event.ts#L21"}],"signatures":[{"id":119,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}]}}},{"id":27,"name":"emit","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"event.ts","line":107,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L107"}],"signatures":[{"id":28,"name":"emit","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Emits an event to the backend."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { emit } from '@tauri-apps/api/event';\nawait emit('frontend-loaded', { loggedIn: true, token: 'authToken' });\n```"}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":29,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Event name. Must include only alphanumeric characters, "},{"kind":"code","text":"`-`"},{"kind":"text","text":", "},{"kind":"code","text":"`/`"},{"kind":"text","text":", "},{"kind":"code","text":"`:`"},{"kind":"text","text":" and "},{"kind":"code","text":"`_`"},{"kind":"text","text":"."}]},"type":{"type":"intrinsic","name":"string"}},{"id":30,"name":"payload","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"unknown"}}],"type":{"type":"reference","typeArguments":[{"type":"intrinsic","name":"void"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]},{"id":17,"name":"listen","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"event.ts","line":57,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L57"}],"signatures":[{"id":18,"name":"listen","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Listen to an event from the backend."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { listen } from '@tauri-apps/api/event';\nconst unlisten = await listen('error', (event) => {\n console.log(`Got error in window ${event.windowLabel}, payload: ${event.payload}`);\n});\n\n// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\nunlisten();\n```"}]},{"tag":"@returns","content":[{"kind":"text","text":"A promise resolving to a function to unlisten to the event.\nNote that removing the listener is required if your listener goes out of scope e.g. the component is unmounted."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"typeParameter":[{"id":19,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":20,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Event name. Must include only alphanumeric characters, "},{"kind":"code","text":"`-`"},{"kind":"text","text":", "},{"kind":"code","text":"`/`"},{"kind":"text","text":", "},{"kind":"code","text":"`:`"},{"kind":"text","text":" and "},{"kind":"code","text":"`_`"},{"kind":"text","text":"."}]},"type":{"type":"reference","id":2,"name":"EventName"}},{"id":21,"name":"handler","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Event handler callback."}]},"type":{"type":"reference","id":112,"typeArguments":[{"type":"reference","id":19,"name":"T"}],"name":"EventCallback"}}],"type":{"type":"reference","typeArguments":[{"type":"reference","id":117,"name":"UnlistenFn"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]},{"id":22,"name":"once","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"event.ts","line":88,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L88"}],"signatures":[{"id":23,"name":"once","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Listen to an one-off event from the backend."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { once } from '@tauri-apps/api/event';\ninterface LoadedPayload {\n loggedIn: boolean,\n token: string\n}\nconst unlisten = await once('loaded', (event) => {\n console.log(`App is loaded, loggedIn: ${event.payload.loggedIn}, token: ${event.payload.token}`);\n});\n\n// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\nunlisten();\n```"}]},{"tag":"@returns","content":[{"kind":"text","text":"A promise resolving to a function to unlisten to the event.\nNote that removing the listener is required if your listener goes out of scope e.g. the component is unmounted."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"typeParameter":[{"id":24,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":25,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Event name. Must include only alphanumeric characters, "},{"kind":"code","text":"`-`"},{"kind":"text","text":", "},{"kind":"code","text":"`/`"},{"kind":"text","text":", "},{"kind":"code","text":"`:`"},{"kind":"text","text":" and "},{"kind":"code","text":"`_`"},{"kind":"text","text":"."}]},"type":{"type":"reference","id":2,"name":"EventName"}},{"id":26,"name":"handler","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":112,"typeArguments":[{"type":"reference","id":24,"name":"T"}],"name":"EventCallback"}}],"type":{"type":"reference","typeArguments":[{"type":"reference","id":117,"name":"UnlistenFn"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]}],"groups":[{"title":"Enumerations","children":[3]},{"title":"Interfaces","children":[106]},{"title":"Type Aliases","children":[112,2,117]},{"title":"Functions","children":[27,17,22]}],"sources":[{"fileName":"event.ts","line":12,"character":0,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/event.ts#L12"}]},{"id":31,"name":"mocks","kind":2,"kindString":"Module","flags":{},"children":[{"id":43,"name":"clearMocks","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"mocks.ts","line":186,"character":16,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/mocks.ts#L186"}],"signatures":[{"id":44,"name":"clearMocks","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Clears mocked functions/data injected by the other functions in this module.\nWhen using a test runner that doesn't provide a fresh window object for each test, calling this function will reset tauri specific properties.\n\n# Example\n\n"},{"kind":"code","text":"```js\nimport { mockWindows, clearMocks } from \"@tauri-apps/api/mocks\"\n\nafterEach(() => {\n clearMocks()\n})\n\ntest(\"mocked windows\", () => {\n mockWindows(\"main\", \"second\", \"third\");\n\n expect(window).toHaveProperty(\"__TAURI_METADATA__\")\n})\n\ntest(\"no mocked windows\", () => {\n expect(window).not.toHaveProperty(\"__TAURI_METADATA__\")\n})\n```"}],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"type":{"type":"intrinsic","name":"void"}}]},{"id":32,"name":"mockIPC","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"mocks.ts","line":80,"character":16,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/mocks.ts#L80"}],"signatures":[{"id":33,"name":"mockIPC","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Intercepts all IPC requests with the given mock handler.\n\nThis function can be used when testing tauri frontend applications or when running the frontend in a Node.js context during static site generation.\n\n# Examples\n\nTesting setup using vitest:\n"},{"kind":"code","text":"```js\nimport { mockIPC, clearMocks } from \"@tauri-apps/api/mocks\"\nimport { invoke } from \"@tauri-apps/api/tauri\"\n\nafterEach(() => {\n clearMocks()\n})\n\ntest(\"mocked command\", () => {\n mockIPC((cmd, args) => {\n switch (cmd) {\n case \"add\":\n return (args.a as number) + (args.b as number);\n default:\n break;\n }\n });\n\n expect(invoke('add', { a: 12, b: 15 })).resolves.toBe(27);\n})\n```"},{"kind":"text","text":"\n\nThe callback function can also return a Promise:\n"},{"kind":"code","text":"```js\nimport { mockIPC, clearMocks } from \"@tauri-apps/api/mocks\"\nimport { invoke } from \"@tauri-apps/api/tauri\"\n\nafterEach(() => {\n clearMocks()\n})\n\ntest(\"mocked command\", () => {\n mockIPC((cmd, args) => {\n if(cmd === \"get_data\") {\n return fetch(\"https://example.com/data.json\")\n .then((response) => response.json())\n }\n });\n\n expect(invoke('get_data')).resolves.toBe({ foo: 'bar' });\n})\n```"}],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":34,"name":"cb","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":35,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"mocks.ts","line":81,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/mocks.ts#L81"}],"signatures":[{"id":36,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":37,"name":"cmd","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":38,"name":"args","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","typeArguments":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"unknown"}],"name":"Record","qualifiedName":"Record","package":"typescript"}}],"type":{"type":"intrinsic","name":"any"}}]}}}],"type":{"type":"intrinsic","name":"void"}}]},{"id":39,"name":"mockWindows","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"mocks.ts","line":150,"character":16,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/mocks.ts#L150"}],"signatures":[{"id":40,"name":"mockWindows","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Mocks one or many window labels.\nIn non-tauri context it is required to call this function *before* using the "},{"kind":"code","text":"`@tauri-apps/api/window`"},{"kind":"text","text":" module.\n\nThis function only mocks the *presence* of windows,\nwindow properties (e.g. width and height) can be mocked like regular IPC calls using the "},{"kind":"code","text":"`mockIPC`"},{"kind":"text","text":" function.\n\n# Examples\n\n"},{"kind":"code","text":"```js\nimport { mockWindows } from \"@tauri-apps/api/mocks\";\nimport { getCurrent } from \"@tauri-apps/api/window\";\n\nmockWindows(\"main\", \"second\", \"third\");\n\nconst win = getCurrent();\n\nwin.label // \"main\"\n```"},{"kind":"text","text":"\n\n"},{"kind":"code","text":"```js\nimport { mockWindows } from \"@tauri-apps/api/mocks\";\n\nmockWindows(\"main\", \"second\", \"third\");\n\nmockIPC((cmd, args) => {\n if (cmd === \"tauri\") {\n if (\n args?.__tauriModule === \"Window\" &&\n args?.message?.cmd === \"manage\" &&\n args?.message?.data?.cmd?.type === \"close\"\n ) {\n console.log('closing window!');\n }\n }\n});\n\nconst { getCurrent } = await import(\"@tauri-apps/api/window\");\n\nconst win = getCurrent();\nawait win.close(); // this will cause the mocked IPC handler to log to the console.\n```"}],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":41,"name":"current","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Label of window this JavaScript context is running in."}]},"type":{"type":"intrinsic","name":"string"}},{"id":42,"name":"additionalWindows","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"comment":{"summary":[{"kind":"text","text":"Label of additional windows the app has."}]},"type":{"type":"array","elementType":{"type":"intrinsic","name":"string"}}}],"type":{"type":"intrinsic","name":"void"}}]}],"groups":[{"title":"Functions","children":[43,32,39]}],"sources":[{"fileName":"mocks.ts","line":6,"character":0,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/mocks.ts#L6"}]},{"id":45,"name":"tauri","kind":2,"kindString":"Module","flags":{},"comment":{"summary":[{"kind":"text","text":"Invoke your custom commands.\n\nThis package is also accessible with "},{"kind":"code","text":"`window.__TAURI__.tauri`"},{"kind":"text","text":" when ["},{"kind":"code","text":"`build.withGlobalTauri`"},{"kind":"text","text":"](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in "},{"kind":"code","text":"`tauri.conf.json`"},{"kind":"text","text":" is set to "},{"kind":"code","text":"`true`"},{"kind":"text","text":"."}]},"children":[{"id":54,"name":"Channel","kind":128,"kindString":"Class","flags":{},"children":[{"id":55,"name":"constructor","kind":512,"kindString":"Constructor","flags":{},"sources":[{"fileName":"tauri.ts","line":66,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L66"}],"signatures":[{"id":56,"name":"new Channel","kind":16384,"kindString":"Constructor signature","flags":{},"typeParameter":[{"id":57,"name":"T","kind":131072,"kindString":"Type parameter","flags":{},"default":{"type":"intrinsic","name":"unknown"}}],"type":{"type":"reference","id":54,"typeArguments":[{"type":"reference","id":57,"name":"T"}],"name":"Channel"}}]},{"id":60,"name":"#onmessage","kind":1024,"kindString":"Property","flags":{"isPrivate":true},"sources":[{"fileName":"tauri.ts","line":62,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L62"}],"type":{"type":"reflection","declaration":{"id":61,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":62,"character":14,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L62"}],"signatures":[{"id":62,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":63,"name":"response","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":57,"name":"T"}}],"type":{"type":"intrinsic","name":"void"}}]}},"defaultValue":"..."},{"id":59,"name":"__TAURI_CHANNEL_MARKER__","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isReadonly":true},"sources":[{"fileName":"tauri.ts","line":61,"character":19,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L61"}],"type":{"type":"literal","value":true},"defaultValue":"true"},{"id":58,"name":"id","kind":1024,"kindString":"Property","flags":{},"sources":[{"fileName":"tauri.ts","line":59,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L59"}],"type":{"type":"intrinsic","name":"number"}},{"id":64,"name":"onmessage","kind":262144,"kindString":"Accessor","flags":{},"sources":[{"fileName":"tauri.ts","line":72,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L72"},{"fileName":"tauri.ts","line":76,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L76"}],"getSignature":{"id":65,"name":"onmessage","kind":524288,"kindString":"Get signature","flags":{},"type":{"type":"reflection","declaration":{"id":66,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":76,"character":19,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L76"}],"signatures":[{"id":67,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":68,"name":"response","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":57,"name":"T"}}],"type":{"type":"intrinsic","name":"void"}}]}}},"setSignature":{"id":69,"name":"onmessage","kind":1048576,"kindString":"Set signature","flags":{},"parameters":[{"id":70,"name":"handler","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":71,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":72,"character":25,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L72"}],"signatures":[{"id":72,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":73,"name":"response","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":57,"name":"T"}}],"type":{"type":"intrinsic","name":"void"}}]}}}],"type":{"type":"intrinsic","name":"void"}}},{"id":74,"name":"toJSON","kind":2048,"kindString":"Method","flags":{},"sources":[{"fileName":"tauri.ts","line":80,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L80"}],"signatures":[{"id":75,"name":"toJSON","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"string"}}]}],"groups":[{"title":"Constructors","children":[55]},{"title":"Properties","children":[60,59,58]},{"title":"Accessors","children":[64]},{"title":"Methods","children":[74]}],"sources":[{"fileName":"tauri.ts","line":58,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L58"}],"typeParameters":[{"id":76,"name":"T","kind":131072,"kindString":"Type parameter","flags":{},"default":{"type":"intrinsic","name":"unknown"}}]},{"id":77,"name":"PluginListener","kind":128,"kindString":"Class","flags":{},"children":[{"id":78,"name":"constructor","kind":512,"kindString":"Constructor","flags":{},"sources":[{"fileName":"tauri.ts","line":90,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L90"}],"signatures":[{"id":79,"name":"new PluginListener","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":80,"name":"plugin","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":81,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":82,"name":"channelId","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","id":77,"name":"PluginListener"}}]},{"id":85,"name":"channelId","kind":1024,"kindString":"Property","flags":{},"sources":[{"fileName":"tauri.ts","line":88,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L88"}],"type":{"type":"intrinsic","name":"number"}},{"id":84,"name":"event","kind":1024,"kindString":"Property","flags":{},"sources":[{"fileName":"tauri.ts","line":87,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L87"}],"type":{"type":"intrinsic","name":"string"}},{"id":83,"name":"plugin","kind":1024,"kindString":"Property","flags":{},"sources":[{"fileName":"tauri.ts","line":86,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L86"}],"type":{"type":"intrinsic","name":"string"}},{"id":86,"name":"unregister","kind":2048,"kindString":"Method","flags":{},"sources":[{"fileName":"tauri.ts","line":96,"character":8,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L96"}],"signatures":[{"id":87,"name":"unregister","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","typeArguments":[{"type":"intrinsic","name":"void"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]}],"groups":[{"title":"Constructors","children":[78]},{"title":"Properties","children":[85,84,83]},{"title":"Methods","children":[86]}],"sources":[{"fileName":"tauri.ts","line":85,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L85"}]},{"id":46,"name":"InvokeArgs","kind":4194304,"kindString":"Type alias","flags":{},"comment":{"summary":[{"kind":"text","text":"Command arguments."}],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"sources":[{"fileName":"tauri.ts","line":128,"character":5,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L128"}],"type":{"type":"reference","typeArguments":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"unknown"}],"name":"Record","qualifiedName":"Record","package":"typescript"}},{"id":88,"name":"addPluginListener","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"tauri.ts","line":111,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L111"}],"signatures":[{"id":89,"name":"addPluginListener","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Adds a listener to a plugin event."}],"blockTags":[{"tag":"@returns","content":[{"kind":"text","text":"The listener object to stop listening to the events."}]},{"tag":"@since","content":[{"kind":"text","text":"2.0.0"}]}]},"typeParameter":[{"id":90,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":91,"name":"plugin","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":92,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":93,"name":"cb","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":94,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":114,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L114"}],"signatures":[{"id":95,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":96,"name":"payload","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":90,"name":"T"}}],"type":{"type":"intrinsic","name":"void"}}]}}}],"type":{"type":"reference","typeArguments":[{"type":"reference","id":77,"name":"PluginListener"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]},{"id":102,"name":"convertFileSrc","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"tauri.ts","line":194,"character":9,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L194"}],"signatures":[{"id":103,"name":"convertFileSrc","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Convert a device file path to an URL that can be loaded by the webview.\nNote that "},{"kind":"code","text":"`asset:`"},{"kind":"text","text":" and "},{"kind":"code","text":"`https://asset.localhost`"},{"kind":"text","text":" must be added to ["},{"kind":"code","text":"`tauri.security.csp`"},{"kind":"text","text":"](https://tauri.app/v1/api/config/#securityconfig.csp) in "},{"kind":"code","text":"`tauri.conf.json`"},{"kind":"text","text":".\nExample CSP value: "},{"kind":"code","text":"`\"csp\": \"default-src 'self'; img-src 'self' asset: https://asset.localhost\"`"},{"kind":"text","text":" to use the asset protocol on image sources.\n\nAdditionally, "},{"kind":"code","text":"`asset`"},{"kind":"text","text":" must be added to ["},{"kind":"code","text":"`tauri.allowlist.protocol`"},{"kind":"text","text":"](https://tauri.app/v1/api/config/#allowlistconfig.protocol)\nin "},{"kind":"code","text":"`tauri.conf.json`"},{"kind":"text","text":" and its access scope must be defined on the "},{"kind":"code","text":"`assetScope`"},{"kind":"text","text":" array on the same "},{"kind":"code","text":"`protocol`"},{"kind":"text","text":" object."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { appDataDir, join } from '@tauri-apps/api/path';\nimport { convertFileSrc } from '@tauri-apps/api/tauri';\nconst appDataDirPath = await appDataDir();\nconst filePath = await join(appDataDirPath, 'assets/video.mp4');\nconst assetUrl = convertFileSrc(filePath);\n\nconst video = document.getElementById('my-video');\nconst source = document.createElement('source');\nsource.type = 'video/mp4';\nsource.src = assetUrl;\nvideo.appendChild(source);\nvideo.load();\n```"}]},{"tag":"@returns","content":[{"kind":"text","text":"the URL that can be used as source on the webview."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":104,"name":"filePath","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"The file path."}]},"type":{"type":"intrinsic","name":"string"}},{"id":105,"name":"protocol","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"The protocol to use. Defaults to "},{"kind":"code","text":"`asset`"},{"kind":"text","text":". You only need to set this when using a custom protocol."}]},"type":{"type":"intrinsic","name":"string"},"defaultValue":"'asset'"}],"type":{"type":"intrinsic","name":"string"}}]},{"id":97,"name":"invoke","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"tauri.ts","line":144,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L144"}],"signatures":[{"id":98,"name":"invoke","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Sends a message to the backend."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { invoke } from '@tauri-apps/api/tauri';\nawait invoke('login', { user: 'tauri', password: 'poiwe3h4r5ip3yrhtew9ty' });\n```"}]},{"tag":"@returns","content":[{"kind":"text","text":"A promise resolving or rejecting to the backend response."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"typeParameter":[{"id":99,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":100,"name":"cmd","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"The command name."}]},"type":{"type":"intrinsic","name":"string"}},{"id":101,"name":"args","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"The optional arguments to pass to the command."}]},"type":{"type":"reference","id":46,"name":"InvokeArgs"},"defaultValue":"{}"}],"type":{"type":"reference","typeArguments":[{"type":"reference","id":99,"name":"T"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]},{"id":47,"name":"transformCallback","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"tauri.ts","line":36,"character":9,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L36"}],"signatures":[{"id":48,"name":"transformCallback","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Transforms a callback function to a string identifier that can be passed to the backend.\nThe backend uses the identifier to "},{"kind":"code","text":"`eval()`"},{"kind":"text","text":" the callback."}],"blockTags":[{"tag":"@returns","content":[{"kind":"text","text":"A unique identifier associated with the callback function."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":49,"name":"callback","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reflection","declaration":{"id":50,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":37,"character":13,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L37"}],"signatures":[{"id":51,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":52,"name":"response","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"id":53,"name":"once","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"boolean"},"defaultValue":"false"}],"type":{"type":"intrinsic","name":"number"}}]}],"groups":[{"title":"Classes","children":[54,77]},{"title":"Type Aliases","children":[46]},{"title":"Functions","children":[88,102,97,47]}],"sources":[{"fileName":"tauri.ts","line":13,"character":0,"url":"https://github.com/tauri-apps/tauri/blob/89ecb84c5/tooling/api/src/tauri.ts#L13"}]}],"groups":[{"title":"Modules","children":[1,31,45]}]} \ No newline at end of file +{"id":0,"name":"@tauri-apps/api","kind":1,"flags":{},"originalName":"","children":[{"id":1,"name":"event","kind":2,"kindString":"Module","flags":{},"comment":{"summary":[{"kind":"text","text":"The event system allows you to emit events to the backend and listen to events from it.\n\nThis package is also accessible with "},{"kind":"code","text":"`window.__TAURI__.event`"},{"kind":"text","text":" when ["},{"kind":"code","text":"`build.withGlobalTauri`"},{"kind":"text","text":"](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in "},{"kind":"code","text":"`tauri.conf.json`"},{"kind":"text","text":" is set to "},{"kind":"code","text":"`true`"},{"kind":"text","text":"."}]},"children":[{"id":3,"name":"TauriEvent","kind":8,"kindString":"Enumeration","flags":{},"comment":{"summary":[],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.1.0"}]}]},"children":[{"id":16,"name":"MENU","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":33,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L33"}],"type":{"type":"literal","value":"tauri://menu"}},{"id":10,"name":"WINDOW_BLUR","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":27,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L27"}],"type":{"type":"literal","value":"tauri://blur"}},{"id":6,"name":"WINDOW_CLOSE_REQUESTED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":23,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L23"}],"type":{"type":"literal","value":"tauri://close-requested"}},{"id":7,"name":"WINDOW_CREATED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":24,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L24"}],"type":{"type":"literal","value":"tauri://window-created"}},{"id":8,"name":"WINDOW_DESTROYED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":25,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L25"}],"type":{"type":"literal","value":"tauri://destroyed"}},{"id":13,"name":"WINDOW_FILE_DROP","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":30,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L30"}],"type":{"type":"literal","value":"tauri://file-drop"}},{"id":15,"name":"WINDOW_FILE_DROP_CANCELLED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":32,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L32"}],"type":{"type":"literal","value":"tauri://file-drop-cancelled"}},{"id":14,"name":"WINDOW_FILE_DROP_HOVER","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":31,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L31"}],"type":{"type":"literal","value":"tauri://file-drop-hover"}},{"id":9,"name":"WINDOW_FOCUS","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":26,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L26"}],"type":{"type":"literal","value":"tauri://focus"}},{"id":5,"name":"WINDOW_MOVED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":22,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L22"}],"type":{"type":"literal","value":"tauri://move"}},{"id":4,"name":"WINDOW_RESIZED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":21,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L21"}],"type":{"type":"literal","value":"tauri://resize"}},{"id":11,"name":"WINDOW_SCALE_FACTOR_CHANGED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":28,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L28"}],"type":{"type":"literal","value":"tauri://scale-change"}},{"id":12,"name":"WINDOW_THEME_CHANGED","kind":16,"kindString":"Enumeration Member","flags":{},"sources":[{"fileName":"event.ts","line":29,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L29"}],"type":{"type":"literal","value":"tauri://theme-changed"}}],"groups":[{"title":"Enumeration Members","children":[16,10,6,7,8,13,15,14,9,5,4,11,12]}],"sources":[{"fileName":"event.ts","line":20,"character":12,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L20"}]},{"id":106,"name":"Event","kind":256,"kindString":"Interface","flags":{},"children":[{"id":107,"name":"event","kind":1024,"kindString":"Property","flags":{},"comment":{"summary":[{"kind":"text","text":"Event name"}]},"sources":[{"fileName":"helpers/event.ts","line":10,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L10"}],"type":{"type":"reference","id":2,"name":"EventName"}},{"id":109,"name":"id","kind":1024,"kindString":"Property","flags":{},"comment":{"summary":[{"kind":"text","text":"Event identifier used to unlisten"}]},"sources":[{"fileName":"helpers/event.ts","line":14,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L14"}],"type":{"type":"intrinsic","name":"number"}},{"id":110,"name":"payload","kind":1024,"kindString":"Property","flags":{},"comment":{"summary":[{"kind":"text","text":"Event payload"}]},"sources":[{"fileName":"helpers/event.ts","line":16,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L16"}],"type":{"type":"reference","id":111,"name":"T"}},{"id":108,"name":"windowLabel","kind":1024,"kindString":"Property","flags":{},"comment":{"summary":[{"kind":"text","text":"The label of the window that emitted this event."}]},"sources":[{"fileName":"helpers/event.ts","line":12,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L12"}],"type":{"type":"intrinsic","name":"string"}}],"groups":[{"title":"Properties","children":[107,109,110,108]}],"sources":[{"fileName":"helpers/event.ts","line":8,"character":17,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L8"}],"typeParameters":[{"id":111,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}]},{"id":112,"name":"EventCallback","kind":4194304,"kindString":"Type alias","flags":{},"sources":[{"fileName":"helpers/event.ts","line":19,"character":12,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L19"}],"typeParameters":[{"id":116,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"type":{"type":"reflection","declaration":{"id":113,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"helpers/event.ts","line":19,"character":31,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L19"}],"signatures":[{"id":114,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":115,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":106,"typeArguments":[{"type":"reference","id":116,"name":"T"}],"name":"Event"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"id":2,"name":"EventName","kind":4194304,"kindString":"Type alias","flags":{},"sources":[{"fileName":"event.ts","line":15,"character":12,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L15"}],"type":{"type":"union","types":[{"type":"template-literal","head":"","tail":[[{"type":"reference","id":3,"name":"TauriEvent"},""]]},{"type":"intersection","types":[{"type":"intrinsic","name":"string"},{"type":"reference","typeArguments":[{"type":"intrinsic","name":"never"},{"type":"intrinsic","name":"never"}],"name":"Record","qualifiedName":"Record","package":"typescript"}]}]}},{"id":117,"name":"UnlistenFn","kind":4194304,"kindString":"Type alias","flags":{},"sources":[{"fileName":"helpers/event.ts","line":21,"character":12,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L21"}],"type":{"type":"reflection","declaration":{"id":118,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"helpers/event.ts","line":21,"character":25,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/helpers/event.ts#L21"}],"signatures":[{"id":119,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"void"}}]}}},{"id":27,"name":"emit","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"event.ts","line":107,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L107"}],"signatures":[{"id":28,"name":"emit","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Emits an event to the backend."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { emit } from '@tauri-apps/api/event';\nawait emit('frontend-loaded', { loggedIn: true, token: 'authToken' });\n```"}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":29,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Event name. Must include only alphanumeric characters, "},{"kind":"code","text":"`-`"},{"kind":"text","text":", "},{"kind":"code","text":"`/`"},{"kind":"text","text":", "},{"kind":"code","text":"`:`"},{"kind":"text","text":" and "},{"kind":"code","text":"`_`"},{"kind":"text","text":"."}]},"type":{"type":"intrinsic","name":"string"}},{"id":30,"name":"payload","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"intrinsic","name":"unknown"}}],"type":{"type":"reference","typeArguments":[{"type":"intrinsic","name":"void"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]},{"id":17,"name":"listen","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"event.ts","line":57,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L57"}],"signatures":[{"id":18,"name":"listen","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Listen to an event from the backend."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { listen } from '@tauri-apps/api/event';\nconst unlisten = await listen('error', (event) => {\n console.log(`Got error in window ${event.windowLabel}, payload: ${event.payload}`);\n});\n\n// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\nunlisten();\n```"}]},{"tag":"@returns","content":[{"kind":"text","text":"A promise resolving to a function to unlisten to the event.\nNote that removing the listener is required if your listener goes out of scope e.g. the component is unmounted."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"typeParameter":[{"id":19,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":20,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Event name. Must include only alphanumeric characters, "},{"kind":"code","text":"`-`"},{"kind":"text","text":", "},{"kind":"code","text":"`/`"},{"kind":"text","text":", "},{"kind":"code","text":"`:`"},{"kind":"text","text":" and "},{"kind":"code","text":"`_`"},{"kind":"text","text":"."}]},"type":{"type":"reference","id":2,"name":"EventName"}},{"id":21,"name":"handler","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Event handler callback."}]},"type":{"type":"reference","id":112,"typeArguments":[{"type":"reference","id":19,"name":"T"}],"name":"EventCallback"}}],"type":{"type":"reference","typeArguments":[{"type":"reference","id":117,"name":"UnlistenFn"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]},{"id":22,"name":"once","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"event.ts","line":88,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L88"}],"signatures":[{"id":23,"name":"once","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Listen to an one-off event from the backend."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { once } from '@tauri-apps/api/event';\ninterface LoadedPayload {\n loggedIn: boolean,\n token: string\n}\nconst unlisten = await once('loaded', (event) => {\n console.log(`App is loaded, loggedIn: ${event.payload.loggedIn}, token: ${event.payload.token}`);\n});\n\n// you need to call unlisten if your handler goes out of scope e.g. the component is unmounted\nunlisten();\n```"}]},{"tag":"@returns","content":[{"kind":"text","text":"A promise resolving to a function to unlisten to the event.\nNote that removing the listener is required if your listener goes out of scope e.g. the component is unmounted."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"typeParameter":[{"id":24,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":25,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Event name. Must include only alphanumeric characters, "},{"kind":"code","text":"`-`"},{"kind":"text","text":", "},{"kind":"code","text":"`/`"},{"kind":"text","text":", "},{"kind":"code","text":"`:`"},{"kind":"text","text":" and "},{"kind":"code","text":"`_`"},{"kind":"text","text":"."}]},"type":{"type":"reference","id":2,"name":"EventName"}},{"id":26,"name":"handler","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":112,"typeArguments":[{"type":"reference","id":24,"name":"T"}],"name":"EventCallback"}}],"type":{"type":"reference","typeArguments":[{"type":"reference","id":117,"name":"UnlistenFn"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]}],"groups":[{"title":"Enumerations","children":[3]},{"title":"Interfaces","children":[106]},{"title":"Type Aliases","children":[112,2,117]},{"title":"Functions","children":[27,17,22]}],"sources":[{"fileName":"event.ts","line":12,"character":0,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/event.ts#L12"}]},{"id":31,"name":"mocks","kind":2,"kindString":"Module","flags":{},"children":[{"id":43,"name":"clearMocks","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"mocks.ts","line":186,"character":16,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/mocks.ts#L186"}],"signatures":[{"id":44,"name":"clearMocks","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Clears mocked functions/data injected by the other functions in this module.\nWhen using a test runner that doesn't provide a fresh window object for each test, calling this function will reset tauri specific properties.\n\n# Example\n\n"},{"kind":"code","text":"```js\nimport { mockWindows, clearMocks } from \"@tauri-apps/api/mocks\"\n\nafterEach(() => {\n clearMocks()\n})\n\ntest(\"mocked windows\", () => {\n mockWindows(\"main\", \"second\", \"third\");\n\n expect(window).toHaveProperty(\"__TAURI_METADATA__\")\n})\n\ntest(\"no mocked windows\", () => {\n expect(window).not.toHaveProperty(\"__TAURI_METADATA__\")\n})\n```"}],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"type":{"type":"intrinsic","name":"void"}}]},{"id":32,"name":"mockIPC","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"mocks.ts","line":80,"character":16,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/mocks.ts#L80"}],"signatures":[{"id":33,"name":"mockIPC","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Intercepts all IPC requests with the given mock handler.\n\nThis function can be used when testing tauri frontend applications or when running the frontend in a Node.js context during static site generation.\n\n# Examples\n\nTesting setup using vitest:\n"},{"kind":"code","text":"```js\nimport { mockIPC, clearMocks } from \"@tauri-apps/api/mocks\"\nimport { invoke } from \"@tauri-apps/api/tauri\"\n\nafterEach(() => {\n clearMocks()\n})\n\ntest(\"mocked command\", () => {\n mockIPC((cmd, args) => {\n switch (cmd) {\n case \"add\":\n return (args.a as number) + (args.b as number);\n default:\n break;\n }\n });\n\n expect(invoke('add', { a: 12, b: 15 })).resolves.toBe(27);\n})\n```"},{"kind":"text","text":"\n\nThe callback function can also return a Promise:\n"},{"kind":"code","text":"```js\nimport { mockIPC, clearMocks } from \"@tauri-apps/api/mocks\"\nimport { invoke } from \"@tauri-apps/api/tauri\"\n\nafterEach(() => {\n clearMocks()\n})\n\ntest(\"mocked command\", () => {\n mockIPC((cmd, args) => {\n if(cmd === \"get_data\") {\n return fetch(\"https://example.com/data.json\")\n .then((response) => response.json())\n }\n });\n\n expect(invoke('get_data')).resolves.toBe({ foo: 'bar' });\n})\n```"}],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":34,"name":"cb","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":35,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"mocks.ts","line":81,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/mocks.ts#L81"}],"signatures":[{"id":36,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":37,"name":"cmd","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":38,"name":"args","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","typeArguments":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"unknown"}],"name":"Record","qualifiedName":"Record","package":"typescript"}}],"type":{"type":"intrinsic","name":"any"}}]}}}],"type":{"type":"intrinsic","name":"void"}}]},{"id":39,"name":"mockWindows","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"mocks.ts","line":150,"character":16,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/mocks.ts#L150"}],"signatures":[{"id":40,"name":"mockWindows","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Mocks one or many window labels.\nIn non-tauri context it is required to call this function *before* using the "},{"kind":"code","text":"`@tauri-apps/api/window`"},{"kind":"text","text":" module.\n\nThis function only mocks the *presence* of windows,\nwindow properties (e.g. width and height) can be mocked like regular IPC calls using the "},{"kind":"code","text":"`mockIPC`"},{"kind":"text","text":" function.\n\n# Examples\n\n"},{"kind":"code","text":"```js\nimport { mockWindows } from \"@tauri-apps/api/mocks\";\nimport { getCurrent } from \"@tauri-apps/api/window\";\n\nmockWindows(\"main\", \"second\", \"third\");\n\nconst win = getCurrent();\n\nwin.label // \"main\"\n```"},{"kind":"text","text":"\n\n"},{"kind":"code","text":"```js\nimport { mockWindows } from \"@tauri-apps/api/mocks\";\n\nmockWindows(\"main\", \"second\", \"third\");\n\nmockIPC((cmd, args) => {\n if (cmd === \"tauri\") {\n if (\n args?.__tauriModule === \"Window\" &&\n args?.message?.cmd === \"manage\" &&\n args?.message?.data?.cmd?.type === \"close\"\n ) {\n console.log('closing window!');\n }\n }\n});\n\nconst { getCurrent } = await import(\"@tauri-apps/api/window\");\n\nconst win = getCurrent();\nawait win.close(); // this will cause the mocked IPC handler to log to the console.\n```"}],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":41,"name":"current","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"Label of window this JavaScript context is running in."}]},"type":{"type":"intrinsic","name":"string"}},{"id":42,"name":"additionalWindows","kind":32768,"kindString":"Parameter","flags":{"isRest":true},"comment":{"summary":[{"kind":"text","text":"Label of additional windows the app has."}]},"type":{"type":"array","elementType":{"type":"intrinsic","name":"string"}}}],"type":{"type":"intrinsic","name":"void"}}]}],"groups":[{"title":"Functions","children":[43,32,39]}],"sources":[{"fileName":"mocks.ts","line":6,"character":0,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/mocks.ts#L6"}]},{"id":45,"name":"tauri","kind":2,"kindString":"Module","flags":{},"comment":{"summary":[{"kind":"text","text":"Invoke your custom commands.\n\nThis package is also accessible with "},{"kind":"code","text":"`window.__TAURI__.tauri`"},{"kind":"text","text":" when ["},{"kind":"code","text":"`build.withGlobalTauri`"},{"kind":"text","text":"](https://tauri.app/v1/api/config/#buildconfig.withglobaltauri) in "},{"kind":"code","text":"`tauri.conf.json`"},{"kind":"text","text":" is set to "},{"kind":"code","text":"`true`"},{"kind":"text","text":"."}]},"children":[{"id":54,"name":"Channel","kind":128,"kindString":"Class","flags":{},"children":[{"id":55,"name":"constructor","kind":512,"kindString":"Constructor","flags":{},"sources":[{"fileName":"tauri.ts","line":66,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L66"}],"signatures":[{"id":56,"name":"new Channel","kind":16384,"kindString":"Constructor signature","flags":{},"typeParameter":[{"id":57,"name":"T","kind":131072,"kindString":"Type parameter","flags":{},"default":{"type":"intrinsic","name":"unknown"}}],"type":{"type":"reference","id":54,"typeArguments":[{"type":"reference","id":57,"name":"T"}],"name":"Channel"}}]},{"id":60,"name":"#onmessage","kind":1024,"kindString":"Property","flags":{"isPrivate":true},"sources":[{"fileName":"tauri.ts","line":62,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L62"}],"type":{"type":"reflection","declaration":{"id":61,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":62,"character":14,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L62"}],"signatures":[{"id":62,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":63,"name":"response","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":57,"name":"T"}}],"type":{"type":"intrinsic","name":"void"}}]}},"defaultValue":"..."},{"id":59,"name":"__TAURI_CHANNEL_MARKER__","kind":1024,"kindString":"Property","flags":{"isPrivate":true,"isReadonly":true},"sources":[{"fileName":"tauri.ts","line":61,"character":19,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L61"}],"type":{"type":"literal","value":true},"defaultValue":"true"},{"id":58,"name":"id","kind":1024,"kindString":"Property","flags":{},"sources":[{"fileName":"tauri.ts","line":59,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L59"}],"type":{"type":"intrinsic","name":"number"}},{"id":64,"name":"onmessage","kind":262144,"kindString":"Accessor","flags":{},"sources":[{"fileName":"tauri.ts","line":72,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L72"},{"fileName":"tauri.ts","line":76,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L76"}],"getSignature":{"id":65,"name":"onmessage","kind":524288,"kindString":"Get signature","flags":{},"type":{"type":"reflection","declaration":{"id":66,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":76,"character":19,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L76"}],"signatures":[{"id":67,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":68,"name":"response","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":57,"name":"T"}}],"type":{"type":"intrinsic","name":"void"}}]}}},"setSignature":{"id":69,"name":"onmessage","kind":1048576,"kindString":"Set signature","flags":{},"parameters":[{"id":70,"name":"handler","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":71,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":72,"character":25,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L72"}],"signatures":[{"id":72,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":73,"name":"response","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":57,"name":"T"}}],"type":{"type":"intrinsic","name":"void"}}]}}}],"type":{"type":"intrinsic","name":"void"}}},{"id":74,"name":"toJSON","kind":2048,"kindString":"Method","flags":{},"sources":[{"fileName":"tauri.ts","line":80,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L80"}],"signatures":[{"id":75,"name":"toJSON","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"intrinsic","name":"string"}}]}],"groups":[{"title":"Constructors","children":[55]},{"title":"Properties","children":[60,59,58]},{"title":"Accessors","children":[64]},{"title":"Methods","children":[74]}],"sources":[{"fileName":"tauri.ts","line":58,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L58"}],"typeParameters":[{"id":76,"name":"T","kind":131072,"kindString":"Type parameter","flags":{},"default":{"type":"intrinsic","name":"unknown"}}]},{"id":77,"name":"PluginListener","kind":128,"kindString":"Class","flags":{},"children":[{"id":78,"name":"constructor","kind":512,"kindString":"Constructor","flags":{},"sources":[{"fileName":"tauri.ts","line":90,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L90"}],"signatures":[{"id":79,"name":"new PluginListener","kind":16384,"kindString":"Constructor signature","flags":{},"parameters":[{"id":80,"name":"plugin","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":81,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":82,"name":"channelId","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"number"}}],"type":{"type":"reference","id":77,"name":"PluginListener"}}]},{"id":85,"name":"channelId","kind":1024,"kindString":"Property","flags":{},"sources":[{"fileName":"tauri.ts","line":88,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L88"}],"type":{"type":"intrinsic","name":"number"}},{"id":84,"name":"event","kind":1024,"kindString":"Property","flags":{},"sources":[{"fileName":"tauri.ts","line":87,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L87"}],"type":{"type":"intrinsic","name":"string"}},{"id":83,"name":"plugin","kind":1024,"kindString":"Property","flags":{},"sources":[{"fileName":"tauri.ts","line":86,"character":2,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L86"}],"type":{"type":"intrinsic","name":"string"}},{"id":86,"name":"unregister","kind":2048,"kindString":"Method","flags":{},"sources":[{"fileName":"tauri.ts","line":96,"character":8,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L96"}],"signatures":[{"id":87,"name":"unregister","kind":4096,"kindString":"Call signature","flags":{},"type":{"type":"reference","typeArguments":[{"type":"intrinsic","name":"void"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]}],"groups":[{"title":"Constructors","children":[78]},{"title":"Properties","children":[85,84,83]},{"title":"Methods","children":[86]}],"sources":[{"fileName":"tauri.ts","line":85,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L85"}]},{"id":46,"name":"InvokeArgs","kind":4194304,"kindString":"Type alias","flags":{},"comment":{"summary":[{"kind":"text","text":"Command arguments."}],"blockTags":[{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"sources":[{"fileName":"tauri.ts","line":128,"character":5,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L128"}],"type":{"type":"reference","typeArguments":[{"type":"intrinsic","name":"string"},{"type":"intrinsic","name":"unknown"}],"name":"Record","qualifiedName":"Record","package":"typescript"}},{"id":88,"name":"addPluginListener","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"tauri.ts","line":111,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L111"}],"signatures":[{"id":89,"name":"addPluginListener","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Adds a listener to a plugin event."}],"blockTags":[{"tag":"@returns","content":[{"kind":"text","text":"The listener object to stop listening to the events."}]},{"tag":"@since","content":[{"kind":"text","text":"2.0.0"}]}]},"typeParameter":[{"id":90,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":91,"name":"plugin","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":92,"name":"event","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"string"}},{"id":93,"name":"cb","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reflection","declaration":{"id":94,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":114,"character":6,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L114"}],"signatures":[{"id":95,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":96,"name":"payload","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"reference","id":90,"name":"T"}}],"type":{"type":"intrinsic","name":"void"}}]}}}],"type":{"type":"reference","typeArguments":[{"type":"reference","id":77,"name":"PluginListener"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]},{"id":102,"name":"convertFileSrc","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"tauri.ts","line":194,"character":9,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L194"}],"signatures":[{"id":103,"name":"convertFileSrc","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Convert a device file path to an URL that can be loaded by the webview.\nNote that "},{"kind":"code","text":"`asset:`"},{"kind":"text","text":" and "},{"kind":"code","text":"`https://asset.localhost`"},{"kind":"text","text":" must be added to ["},{"kind":"code","text":"`tauri.security.csp`"},{"kind":"text","text":"](https://tauri.app/v1/api/config/#securityconfig.csp) in "},{"kind":"code","text":"`tauri.conf.json`"},{"kind":"text","text":".\nExample CSP value: "},{"kind":"code","text":"`\"csp\": \"default-src 'self'; img-src 'self' asset: https://asset.localhost\"`"},{"kind":"text","text":" to use the asset protocol on image sources.\n\nAdditionally, "},{"kind":"code","text":"`asset`"},{"kind":"text","text":" must be added to ["},{"kind":"code","text":"`tauri.allowlist.protocol`"},{"kind":"text","text":"](https://tauri.app/v1/api/config/#allowlistconfig.protocol)\nin "},{"kind":"code","text":"`tauri.conf.json`"},{"kind":"text","text":" and its access scope must be defined on the "},{"kind":"code","text":"`assetScope`"},{"kind":"text","text":" array on the same "},{"kind":"code","text":"`protocol`"},{"kind":"text","text":" object."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { appDataDir, join } from '@tauri-apps/api/path';\nimport { convertFileSrc } from '@tauri-apps/api/tauri';\nconst appDataDirPath = await appDataDir();\nconst filePath = await join(appDataDirPath, 'assets/video.mp4');\nconst assetUrl = convertFileSrc(filePath);\n\nconst video = document.getElementById('my-video');\nconst source = document.createElement('source');\nsource.type = 'video/mp4';\nsource.src = assetUrl;\nvideo.appendChild(source);\nvideo.load();\n```"}]},{"tag":"@returns","content":[{"kind":"text","text":"the URL that can be used as source on the webview."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":104,"name":"filePath","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"The file path."}]},"type":{"type":"intrinsic","name":"string"}},{"id":105,"name":"protocol","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"The protocol to use. Defaults to "},{"kind":"code","text":"`asset`"},{"kind":"text","text":". You only need to set this when using a custom protocol."}]},"type":{"type":"intrinsic","name":"string"},"defaultValue":"'asset'"}],"type":{"type":"intrinsic","name":"string"}}]},{"id":97,"name":"invoke","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"tauri.ts","line":144,"character":15,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L144"}],"signatures":[{"id":98,"name":"invoke","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Sends a message to the backend."}],"blockTags":[{"tag":"@example","content":[{"kind":"code","text":"```typescript\nimport { invoke } from '@tauri-apps/api/tauri';\nawait invoke('login', { user: 'tauri', password: 'poiwe3h4r5ip3yrhtew9ty' });\n```"}]},{"tag":"@returns","content":[{"kind":"text","text":"A promise resolving or rejecting to the backend response."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"typeParameter":[{"id":99,"name":"T","kind":131072,"kindString":"Type parameter","flags":{}}],"parameters":[{"id":100,"name":"cmd","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"The command name."}]},"type":{"type":"intrinsic","name":"string"}},{"id":101,"name":"args","kind":32768,"kindString":"Parameter","flags":{},"comment":{"summary":[{"kind":"text","text":"The optional arguments to pass to the command."}]},"type":{"type":"reference","id":46,"name":"InvokeArgs"},"defaultValue":"{}"}],"type":{"type":"reference","typeArguments":[{"type":"reference","id":99,"name":"T"}],"name":"Promise","externalUrl":"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise","qualifiedName":"Promise","package":"typescript"}}]},{"id":47,"name":"transformCallback","kind":64,"kindString":"Function","flags":{},"sources":[{"fileName":"tauri.ts","line":36,"character":9,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L36"}],"signatures":[{"id":48,"name":"transformCallback","kind":4096,"kindString":"Call signature","flags":{},"comment":{"summary":[{"kind":"text","text":"Transforms a callback function to a string identifier that can be passed to the backend.\nThe backend uses the identifier to "},{"kind":"code","text":"`eval()`"},{"kind":"text","text":" the callback."}],"blockTags":[{"tag":"@returns","content":[{"kind":"text","text":"A unique identifier associated with the callback function."}]},{"tag":"@since","content":[{"kind":"text","text":"1.0.0"}]}]},"parameters":[{"id":49,"name":"callback","kind":32768,"kindString":"Parameter","flags":{"isOptional":true},"type":{"type":"reflection","declaration":{"id":50,"name":"__type","kind":65536,"kindString":"Type literal","flags":{},"sources":[{"fileName":"tauri.ts","line":37,"character":13,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L37"}],"signatures":[{"id":51,"name":"__type","kind":4096,"kindString":"Call signature","flags":{},"parameters":[{"id":52,"name":"response","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"any"}}],"type":{"type":"intrinsic","name":"void"}}]}}},{"id":53,"name":"once","kind":32768,"kindString":"Parameter","flags":{},"type":{"type":"intrinsic","name":"boolean"},"defaultValue":"false"}],"type":{"type":"intrinsic","name":"number"}}]}],"groups":[{"title":"Classes","children":[54,77]},{"title":"Type Aliases","children":[46]},{"title":"Functions","children":[88,102,97,47]}],"sources":[{"fileName":"tauri.ts","line":13,"character":0,"url":"https://github.com/tauri-apps/tauri/blob/eb4a00240/tooling/api/src/tauri.ts#L13"}]}],"groups":[{"title":"Modules","children":[1,31,45]}]} \ No newline at end of file diff --git a/tooling/cli/schema.json b/tooling/cli/schema.json index b5f5da379..24e4c6283 100644 --- a/tooling/cli/schema.json +++ b/tooling/cli/schema.json @@ -488,6 +488,17 @@ "description": "Whether or not the window has shadow.\n\n## Platform-specific\n\n- **Windows:** - `false` has no effect on decorated window, shadow are always ON. - `true` will make ndecorated window have a 1px white border, and on Windows 11, it will have a rounded corners. - **Linux:** Unsupported.", "default": true, "type": "boolean" + }, + "windowEffects": { + "description": "Window effects.\n\nRequires the window to be transparent.\n\n## Platform-specific:\n\n- **Windows**: If using decorations or shadows, you may want to try this workaround https://github.com/tauri-apps/tao/issues/72#issuecomment-975607891 - **Linux**: Unsupported", + "anyOf": [ + { + "$ref": "#/definitions/WindowEffectsConfig" + }, + { + "type": "null" + } + ] } }, "additionalProperties": false @@ -551,6 +562,271 @@ } ] }, + "WindowEffectsConfig": { + "description": "The window effects configuration object", + "type": "object", + "required": [ + "effects" + ], + "properties": { + "effects": { + "description": "List of Window effects to apply to the Window. Conflicting effects will apply the first one and ignore the rest.", + "type": "array", + "items": { + "$ref": "#/definitions/WindowEffect" + } + }, + "state": { + "description": "Window effect state **macOS Only**", + "anyOf": [ + { + "$ref": "#/definitions/WindowEffectState" + }, + { + "type": "null" + } + ] + }, + "radius": { + "description": "Window effect corner radius **macOS Only**", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "color": { + "description": "Window effect color. Affects [`WindowEffects::Blur`] and [`WindowEffects::Acrylic`] only on Windows 10 v1903+. Doesn't have any effect on Windows 7 or Windows 11.", + "anyOf": [ + { + "$ref": "#/definitions/Color" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "WindowEffect": { + "description": "Platform-specific window effects", + "oneOf": [ + { + "description": "A default material appropriate for the view's effectiveAppearance. **macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "appearanceBased" + ] + }, + { + "description": "*macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "light" + ] + }, + { + "description": "*macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "dark" + ] + }, + { + "description": "*macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "mediumLight" + ] + }, + { + "description": "*macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "ultraDark" + ] + }, + { + "description": "*macOS 10.10+**", + "type": "string", + "enum": [ + "titlebar" + ] + }, + { + "description": "*macOS 10.10+**", + "type": "string", + "enum": [ + "selection" + ] + }, + { + "description": "*macOS 10.11+**", + "type": "string", + "enum": [ + "menu" + ] + }, + { + "description": "*macOS 10.11+**", + "type": "string", + "enum": [ + "popover" + ] + }, + { + "description": "*macOS 10.11+**", + "type": "string", + "enum": [ + "sidebar" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "headerView" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "sheet" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "windowBackground" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "hudWindow" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "fullScreenUI" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "tooltip" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "contentBackground" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "underWindowBackground" + ] + }, + { + "description": "*macOS 10.14+**", + "type": "string", + "enum": [ + "underPageBackground" + ] + }, + { + "description": "*Windows 11 Only**", + "type": "string", + "enum": [ + "mica" + ] + }, + { + "description": "**Windows 7/10/11(22H1) Only**\n\n## Notes\n\nThis effect has bad performance when resizing/dragging the window on Windows 11 build 22621.", + "type": "string", + "enum": [ + "blur" + ] + }, + { + "description": "**Windows 10/11 Only**\n\n## Notes\n\nThis effect has bad performance when resizing/dragging the window on Windows 10 v1903+ and Windows 11 build 22000.", + "type": "string", + "enum": [ + "acrylic" + ] + } + ] + }, + "WindowEffectState": { + "description": "Window effect state **macOS only**\n\n", + "oneOf": [ + { + "description": "Make window effect state follow the window's active state", + "type": "string", + "enum": [ + "followsWindowActiveState" + ] + }, + { + "description": "Make window effect state always active", + "type": "string", + "enum": [ + "active" + ] + }, + { + "description": "Make window effect state always inactive", + "type": "string", + "enum": [ + "inactive" + ] + } + ] + }, + "Color": { + "description": "a tuple struct of RGBA colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 4, + "minItems": 4 + }, "BundleConfig": { "description": "Configuration for tauri-bundler.\n\nSee more: https://tauri.app/v1/api/config#bundleconfig", "type": "object",