#![doc(
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png",
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png"
)]
#![cfg_attr(docsrs, feature(doc_cfg))]
use raw_window_handle::DisplayHandle;
use serde::Deserialize;
use std::{borrow::Cow, fmt::Debug, sync::mpsc::Sender};
use tauri_utils::Theme;
use tauri_utils::config::Color;
use url::Url;
use webview::{DetachedWebview, PendingWebview};
pub mod dpi;
pub mod dynamic;
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
pub mod gtk;
pub mod monitor;
pub mod webview;
mod webview_permissions;
pub mod window;
use dpi::{PhysicalPosition, PhysicalSize, Position, Rect, Size};
use monitor::Monitor;
use window::{
CursorIcon, DetachedWindow, PendingWindow, RawWindow, WebviewEvent, WindowEvent,
WindowSizeConstraints,
};
use window::{WindowBuilder, WindowId};
use http::{
header::{InvalidHeaderName, InvalidHeaderValue},
method::InvalidMethod,
status::InvalidStatusCode,
};
pub use cookie::Cookie;
pub type WindowEventId = u32;
pub type WebviewEventId = u32;
#[derive(Debug, Clone, Copy, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum ProgressBarStatus {
None,
Normal,
Indeterminate,
Paused,
Error,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ProgressBarState {
pub status: Option<ProgressBarStatus>,
pub progress: Option<u64>,
pub desktop_filename: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(tag = "type")]
pub enum UserAttentionType {
Critical,
Informational,
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(tag = "type")]
pub enum DeviceEventFilter {
Always,
#[default]
Unfocused,
Never,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
pub enum ResizeDirection {
East,
North,
NorthEast,
NorthWest,
South,
SouthEast,
SouthWest,
West,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
#[error("failed to create webview: {0}")]
CreateWebview(Box<dyn std::error::Error + Send + Sync>),
#[error("failed to create window: {0}")]
CreateWindow(Box<dyn std::error::Error + Send + Sync>),
#[error("Window labels must only include alphanumeric characters, `-`, `/`, `:` and `_`.")]
InvalidWindowLabel,
#[error("failed to send message to the webview")]
FailedToSendMessage,
#[error("failed to receive message from webview")]
FailedToReceiveMessage,
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("invalid icon: {0}")]
InvalidIcon(Box<dyn std::error::Error + Send + Sync>),
#[error("failed to get monitor")]
FailedToGetMonitor,
#[error("failed to get cursor position")]
FailedToGetCursorPosition,
#[error("Invalid header name: {0}")]
InvalidHeaderName(#[from] InvalidHeaderName),
#[error("Invalid header value: {0}")]
InvalidHeaderValue(#[from] InvalidHeaderValue),
#[error("Invalid status code: {0}")]
InvalidStatusCode(#[from] InvalidStatusCode),
#[error("Invalid method: {0}")]
InvalidMethod(#[from] InvalidMethod),
#[error("Infallible error, something went really wrong: {0}")]
Infallible(#[from] std::convert::Infallible),
#[error("the event loop has been closed")]
EventLoopClosed,
#[error("Invalid proxy url")]
InvalidProxyUrl,
#[error("window not found")]
WindowNotFound,
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[error("failed to remove data store")]
FailedToRemoveDataStore,
#[error("Could not find the webview runtime, make sure it is installed")]
WebviewRuntimeNotInstalled,
#[error(
"no runtime was configured; select one with e.g. `tauri::Builder::default().runtime(tauri_runtime_wry::Wry::default())`"
)]
RuntimeNotConfigured,
#[error("runtime type mismatch: {0}")]
RuntimeTypeMismatch(String),
#[error("failed to get the webview version: {0}")]
WebviewVersion(Box<dyn std::error::Error + Send + Sync>),
}
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug, Clone)]
pub struct Icon<'a> {
pub rgba: Cow<'a, [u8]>,
pub width: u32,
pub height: u32,
}
impl<'a> Icon<'a> {
pub fn into_owned(self) -> Icon<'static> {
Icon {
rgba: std::borrow::Cow::Owned(self.rgba.into_owned()),
width: self.width,
height: self.height,
}
}
}
pub trait UserEvent: Debug + Clone + Send + 'static {}
impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
#[derive(Debug)]
#[non_exhaustive]
pub enum RunEvent<T: UserEvent> {
Exit,
ExitRequested {
code: Option<i32>,
tx: Sender<ExitRequestedEventAction>,
},
WindowEvent {
label: String,
event: WindowEvent,
},
WebviewEvent {
label: String,
event: WebviewEvent,
},
Ready,
Resumed,
MainEventsCleared,
Opened { urls: Vec<url::Url> },
#[cfg(target_os = "macos")]
Reopen {
has_visible_windows: bool,
},
UserEvent(T),
#[cfg(target_os = "ios")]
SceneRequested {
scene: objc2::rc::Retained<objc2_ui_kit::UIScene>,
options: objc2::rc::Retained<objc2_ui_kit::UISceneConnectionOptions>,
},
}
#[derive(Debug)]
pub enum ExitRequestedEventAction {
Prevent,
}
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
#[non_exhaustive]
pub enum ActivationPolicy {
Regular,
Accessory,
Prohibited,
}
pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
type Runtime: Runtime<T, Handle = Self>;
fn create_proxy(&self) -> <Self::Runtime as Runtime<T>>::EventLoopProxy;
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_dock_visibility(&self, visible: bool) -> Result<()>;
fn request_exit(&self, code: i32) -> Result<()>;
fn create_window<F: Fn(RawWindow) + Send + 'static>(
&self,
pending: PendingWindow<T, Self::Runtime>,
after_window_creation: Option<F>,
) -> Result<DetachedWindow<T, Self::Runtime>>;
fn create_webview(
&self,
window_id: WindowId,
pending: PendingWebview<T, Self::Runtime>,
) -> Result<DetachedWebview<T, Self::Runtime>>;
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
fn display_handle(
&self,
) -> std::result::Result<DisplayHandle<'_>, raw_window_handle::HandleError>;
fn primary_monitor(&self) -> Result<Option<Monitor>>;
fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
fn available_monitors(&self) -> Result<Vec<Monitor>>;
fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
fn set_theme(&self, theme: Option<Theme>);
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn show(&self) -> Result<()>;
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn hide(&self) -> Result<()>;
fn set_device_event_filter(&self, filter: DeviceEventFilter);
fn custom_scheme_url(&self, scheme: &str, https: bool) -> String;
fn webview_version(&self) -> Result<String>;
#[cfg(target_os = "android")]
fn find_class<'a>(
&self,
env: &mut jni::JNIEnv<'a>,
activity: &jni::objects::JObject<'_>,
name: impl Into<String>,
) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
#[cfg(target_os = "android")]
fn run_on_android_context<F>(&self, f: F)
where
F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
&self,
cb: F,
) -> Result<()>;
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
&self,
uuid: [u8; 16],
cb: F,
) -> Result<()>;
}
pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
fn send_event(&self, event: T) -> Result<()>;
}
#[derive(Default)]
pub struct RuntimeInitArgs<A> {
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
pub app_id: Option<String>,
#[cfg(windows)]
pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
pub identifier: String,
pub custom_schemes: Vec<String>,
pub runtime_init_attrs: A,
}
impl<A> RuntimeInitArgs<A> {
pub(crate) fn with_attrs<B>(self, runtime_init_attrs: B) -> (RuntimeInitArgs<B>, A) {
let RuntimeInitArgs {
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
app_id,
#[cfg(windows)]
msg_hook,
identifier,
custom_schemes,
runtime_init_attrs: previous,
} = self;
(
RuntimeInitArgs {
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
app_id,
#[cfg(windows)]
msg_hook,
identifier,
custom_schemes,
runtime_init_attrs,
},
previous,
)
}
}
pub trait RuntimeInitAttrs<T: UserEvent>: Default + Send + Sync + 'static {
type Runtime: Runtime<T, RuntimeInitAttrs = Self>;
fn apply_config(&mut self, _config: &tauri_utils::config::Config) -> Result<()> {
Ok(())
}
}
pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
type Handle: RuntimeHandle<T, Runtime = Self>;
type EventLoopProxy: EventLoopProxy<T>;
type RuntimeWebviewAttributes: Default + Send + Sync + 'static;
type Webview: 'static;
type RuntimeInitAttrs: RuntimeInitAttrs<T, Runtime = Self>;
type WindowOpener: Send + Sync + Debug + 'static;
fn new(args: RuntimeInitArgs<Self::RuntimeInitAttrs>) -> Result<Self>;
#[cfg(any(
windows,
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
#[cfg_attr(
docsrs,
doc(cfg(any(
windows,
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
)))
)]
fn new_any_thread(args: RuntimeInitArgs<Self::RuntimeInitAttrs>) -> Result<Self>;
fn create_proxy(&self) -> Self::EventLoopProxy;
fn handle(&self) -> Self::Handle;
fn create_window<F: Fn(RawWindow) + Send + 'static>(
&self,
pending: PendingWindow<T, Self>,
after_window_creation: Option<F>,
) -> Result<DetachedWindow<T, Self>>;
fn create_webview(
&self,
window_id: WindowId,
pending: PendingWebview<T, Self>,
) -> Result<DetachedWebview<T, Self>>;
fn primary_monitor(&self) -> Option<Monitor>;
fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
fn available_monitors(&self) -> Vec<Monitor>;
fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
fn set_theme(&self, theme: Option<Theme>);
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_activate_ignoring_other_apps(&mut self, ignore: bool);
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn set_dock_visibility(&mut self, visible: bool);
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn show(&self);
#[cfg(target_os = "macos")]
#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
fn hide(&self);
fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
#[cfg(desktop)]
fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32;
fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
}
pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
type Runtime: Runtime<T>;
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
fn with_webview<F: FnOnce(<Self::Runtime as Runtime<T>>::Webview) + Send + 'static>(
&self,
f: F,
) -> Result<()>;
#[cfg(target_os = "ios")]
fn with_ios_webview<F: FnOnce(webview::IosWebviewHandle) + Send + 'static>(
&self,
f: F,
) -> Result<()>;
fn open_devtools(&self);
fn close_devtools(&self);
fn is_devtools_open(&self) -> Result<bool>;
fn url(&self) -> Result<String>;
fn bounds(&self) -> Result<Rect>;
fn position(&self) -> Result<PhysicalPosition<i32>>;
fn size(&self) -> Result<PhysicalSize<u32>>;
fn navigate(&self, url: Url) -> Result<()>;
fn reload(&self) -> Result<()>;
fn go_back(&self) -> Result<()>;
fn can_go_back(&self) -> Result<bool>;
fn go_forward(&self) -> Result<()>;
fn can_go_forward(&self) -> Result<bool>;
fn print(&self) -> Result<()>;
fn close(&self) -> Result<()>;
fn set_bounds(&self, bounds: Rect) -> Result<()>;
fn set_size(&self, size: Size) -> Result<()>;
fn set_position(&self, position: Position) -> Result<()>;
fn set_focus(&self) -> Result<()>;
fn hide(&self) -> Result<()>;
fn show(&self) -> Result<()>;
fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
fn eval_script_with_callback<S: Into<String>>(
&self,
script: S,
callback: impl Fn(String) + Send + 'static,
) -> Result<()>;
fn reparent(&self, window_id: WindowId) -> Result<()>;
fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
fn set_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
fn delete_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
fn set_zoom(&self, scale_factor: f64) -> Result<()>;
fn set_background_color(&self, color: Option<Color>) -> Result<()>;
fn clear_all_browsing_data(&self) -> Result<()>;
}
pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
type Runtime: Runtime<T>;
type WindowBuilder: WindowBuilder;
fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
fn scale_factor(&self) -> Result<f64>;
fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
fn inner_size(&self) -> Result<PhysicalSize<u32>>;
fn outer_size(&self) -> Result<PhysicalSize<u32>>;
fn is_fullscreen(&self) -> Result<bool>;
fn is_minimized(&self) -> Result<bool>;
fn is_maximized(&self) -> Result<bool>;
fn is_focused(&self) -> Result<bool>;
fn is_decorated(&self) -> Result<bool>;
fn is_resizable(&self) -> Result<bool>;
fn is_maximizable(&self) -> Result<bool>;
fn is_minimizable(&self) -> Result<bool>;
fn is_closable(&self) -> Result<bool>;
fn is_visible(&self) -> Result<bool>;
fn is_enabled(&self) -> Result<bool>;
fn is_always_on_top(&self) -> Result<bool>;
fn title(&self) -> Result<String>;
fn current_monitor(&self) -> Result<Option<Monitor>>;
fn primary_monitor(&self) -> Result<Option<Monitor>>;
fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
fn available_monitors(&self) -> Result<Vec<Monitor>>;
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
fn gtk_window(&self) -> Result<*mut std::ffi::c_void>;
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
fn default_vbox(&self) -> Result<*mut std::ffi::c_void>;
#[cfg(target_os = "android")]
fn activity_name(&self) -> Result<String>;
#[cfg(target_os = "ios")]
fn scene_identifier(&self) -> Result<String>;
fn window_handle(
&self,
) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
fn theme(&self) -> Result<Theme>;
fn center(&self) -> Result<()>;
fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
fn create_window<F: Fn(RawWindow) + Send + 'static>(
&mut self,
pending: PendingWindow<T, Self::Runtime>,
after_window_creation: Option<F>,
) -> Result<DetachedWindow<T, Self::Runtime>>;
fn create_webview(
&mut self,
pending: PendingWebview<T, Self::Runtime>,
) -> Result<DetachedWebview<T, Self::Runtime>>;
fn set_resizable(&self, resizable: bool) -> Result<()>;
fn set_enabled(&self, enabled: bool) -> Result<()>;
fn set_maximizable(&self, maximizable: bool) -> Result<()>;
fn set_minimizable(&self, minimizable: bool) -> Result<()>;
fn set_closable(&self, closable: bool) -> Result<()>;
fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
fn maximize(&self) -> Result<()>;
fn unmaximize(&self) -> Result<()>;
fn minimize(&self) -> Result<()>;
fn unminimize(&self) -> Result<()>;
fn show(&self) -> Result<()>;
fn hide(&self) -> Result<()>;
fn close(&self) -> Result<()>;
fn destroy(&self) -> Result<()>;
fn set_decorations(&self, decorations: bool) -> Result<()>;
fn set_shadow(&self, enable: bool) -> Result<()>;
fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
fn set_background_color(&self, color: Option<Color>) -> Result<()>;
fn set_content_protected(&self, protected: bool) -> Result<()>;
fn set_size(&self, size: Size) -> Result<()>;
fn set_min_size(&self, size: Option<Size>) -> Result<()>;
fn set_max_size(&self, size: Option<Size>) -> Result<()>;
fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
fn set_position(&self, position: Position) -> Result<()>;
fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
fn set_fullscreen_on_monitor(&self, position: PhysicalPosition<f64>) -> Result<()>;
#[cfg(target_os = "macos")]
fn set_simple_fullscreen(&self, enable: bool) -> Result<()>;
fn set_focus(&self) -> Result<()>;
fn set_focusable(&self, focusable: bool) -> Result<()>;
fn set_icon(&self, icon: Icon) -> Result<()>;
fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
fn set_cursor_grab(&self, grab: bool) -> Result<()>;
fn set_cursor_visible(&self, visible: bool) -> Result<()>;
fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
fn start_dragging(&self) -> Result<()>;
fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
fn set_badge_label(&self, label: Option<String>) -> Result<()>;
fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
fn set_traffic_light_position(&self, position: Position) -> Result<()>;
fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
}