#![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, Serialize};
use std::{borrow::Cow, fmt::Debug, sync::mpsc::Sender};
use tauri_utils::Theme;
use url::Url;
use webview::{DetachedWebview, PendingWebview};
pub mod monitor;
pub mod webview;
pub mod window;
use dpi::{PhysicalPosition, PhysicalSize, Position, 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 dpi;
pub type WindowEventId = u32;
pub type WebviewEventId = u32;
#[derive(Clone, Copy, Debug, Serialize)]
pub struct Rect {
pub position: dpi::Position,
pub size: dpi::Size,
}
impl Default for Rect {
fn default() -> Self {
Self {
position: Position::Logical((0, 0).into()),
size: Size::Logical((0, 0).into()),
}
}
}
#[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(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(tag = "type")]
pub enum DeviceEventFilter {
Always,
Unfocused,
Never,
}
impl Default for DeviceEventFilter {
fn default() -> Self {
Self::Unfocused
}
}
#[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")]
CreateWindow,
#[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,
}
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,
}
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,
#[cfg(any(target_os = "macos", target_os = "ios"))]
Opened { urls: Vec<url::Url> },
#[cfg(target_os = "macos")]
Reopen {
has_visible_windows: bool,
},
UserEvent(T),
}
#[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<()>;
fn request_exit(&self, code: i32) -> Result<()>;
fn create_window<F: Fn(RawWindow) + Send + 'static>(
&self,
pending: PendingWindow<T, Self::Runtime>,
before_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) -> 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>>;
#[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<()>;
#[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;
}
pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
fn send_event(&self, event: T) -> Result<()>;
}
#[derive(Default)]
pub struct RuntimeInitArgs {
#[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 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>;
fn new(args: RuntimeInitArgs) -> Result<Self>;
#[cfg(any(windows, target_os = "linux"))]
#[cfg_attr(docsrs, doc(cfg(any(windows, target_os = "linux"))))]
fn new_any_thread(args: RuntimeInitArgs) -> 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>>;
#[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 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<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(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()>;
#[cfg(any(debug_assertions, feature = "devtools"))]
fn open_devtools(&self);
#[cfg(any(debug_assertions, feature = "devtools"))]
fn close_devtools(&self);
#[cfg(any(debug_assertions, feature = "devtools"))]
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 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 eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
fn reparent(&self, window_id: WindowId) -> Result<()>;
fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
fn set_zoom(&self, scale_factor: f64) -> 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 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<gtk::ApplicationWindow>;
#[cfg(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
))]
fn default_vbox(&self) -> Result<gtk::Box>;
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_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_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_focus(&self) -> 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_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
}