1#![doc(
11 html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png",
12 html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png"
13)]
14#![cfg_attr(docsrs, feature(doc_cfg))]
15
16use raw_window_handle::DisplayHandle;
17use serde::Deserialize;
18use std::{borrow::Cow, fmt::Debug, sync::mpsc::Sender};
19use tauri_utils::config::Color;
20use tauri_utils::Theme;
21use url::Url;
22use webview::{DetachedWebview, PendingWebview};
23
24pub mod dpi;
26pub mod monitor;
28pub mod webview;
29pub mod window;
30
31use dpi::{PhysicalPosition, PhysicalSize, Position, Rect, Size};
32use monitor::Monitor;
33use window::{
34 CursorIcon, DetachedWindow, PendingWindow, RawWindow, WebviewEvent, WindowEvent,
35 WindowSizeConstraints,
36};
37use window::{WindowBuilder, WindowId};
38
39use http::{
40 header::{InvalidHeaderName, InvalidHeaderValue},
41 method::InvalidMethod,
42 status::InvalidStatusCode,
43};
44
45pub use cookie::Cookie;
47
48pub type WindowEventId = u32;
49pub type WebviewEventId = u32;
50
51#[derive(Debug, Clone, Copy, Deserialize)]
53#[serde(rename_all = "camelCase")]
54pub enum ProgressBarStatus {
55 None,
57 Normal,
59 Indeterminate,
61 Paused,
63 Error,
65}
66
67#[derive(Debug, Deserialize)]
69#[serde(rename_all = "camelCase")]
70pub struct ProgressBarState {
71 pub status: Option<ProgressBarStatus>,
73 pub progress: Option<u64>,
75 pub desktop_filename: Option<String>,
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
81#[serde(tag = "type")]
82pub enum UserAttentionType {
83 Critical,
87 Informational,
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
94#[serde(tag = "type")]
95pub enum DeviceEventFilter {
96 Always,
98 Unfocused,
100 Never,
102}
103
104impl Default for DeviceEventFilter {
105 fn default() -> Self {
106 Self::Unfocused
107 }
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
112pub enum ResizeDirection {
113 East,
114 North,
115 NorthEast,
116 NorthWest,
117 South,
118 SouthEast,
119 SouthWest,
120 West,
121}
122
123#[derive(Debug, thiserror::Error)]
124#[non_exhaustive]
125pub enum Error {
126 #[error("failed to create webview: {0}")]
128 CreateWebview(Box<dyn std::error::Error + Send + Sync>),
129 #[error("failed to create window")]
131 CreateWindow,
132 #[error("Window labels must only include alphanumeric characters, `-`, `/`, `:` and `_`.")]
134 InvalidWindowLabel,
135 #[error("failed to send message to the webview")]
137 FailedToSendMessage,
138 #[error("failed to receive message from webview")]
140 FailedToReceiveMessage,
141 #[error("JSON error: {0}")]
143 Json(#[from] serde_json::Error),
144 #[error("invalid icon: {0}")]
146 InvalidIcon(Box<dyn std::error::Error + Send + Sync>),
147 #[error("failed to get monitor")]
149 FailedToGetMonitor,
150 #[error("failed to get cursor position")]
152 FailedToGetCursorPosition,
153 #[error("Invalid header name: {0}")]
154 InvalidHeaderName(#[from] InvalidHeaderName),
155 #[error("Invalid header value: {0}")]
156 InvalidHeaderValue(#[from] InvalidHeaderValue),
157 #[error("Invalid status code: {0}")]
158 InvalidStatusCode(#[from] InvalidStatusCode),
159 #[error("Invalid method: {0}")]
160 InvalidMethod(#[from] InvalidMethod),
161 #[error("Infallible error, something went really wrong: {0}")]
162 Infallible(#[from] std::convert::Infallible),
163 #[error("the event loop has been closed")]
164 EventLoopClosed,
165 #[error("Invalid proxy url")]
166 InvalidProxyUrl,
167 #[error("window not found")]
168 WindowNotFound,
169 #[cfg(any(target_os = "macos", target_os = "ios"))]
170 #[error("failed to remove data store")]
171 FailedToRemoveDataStore,
172 #[error("Could not find the webview runtime, make sure it is installed")]
173 WebviewRuntimeNotInstalled,
174}
175
176pub type Result<T> = std::result::Result<T, Error>;
178
179#[derive(Debug, Clone)]
181pub struct Icon<'a> {
182 pub rgba: Cow<'a, [u8]>,
184 pub width: u32,
186 pub height: u32,
188}
189
190pub trait UserEvent: Debug + Clone + Send + 'static {}
192
193impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
194
195#[derive(Debug)]
197#[non_exhaustive]
198pub enum RunEvent<T: UserEvent> {
199 Exit,
201 ExitRequested {
203 code: Option<i32>,
205 tx: Sender<ExitRequestedEventAction>,
206 },
207 WindowEvent {
209 label: String,
211 event: WindowEvent,
213 },
214 WebviewEvent {
216 label: String,
218 event: WebviewEvent,
220 },
221 Ready,
223 Resumed,
225 MainEventsCleared,
229 #[cfg(any(target_os = "macos", target_os = "ios"))]
231 Opened { urls: Vec<url::Url> },
232 #[cfg(target_os = "macos")]
234 Reopen {
235 has_visible_windows: bool,
237 },
238 UserEvent(T),
240}
241
242#[derive(Debug)]
244pub enum ExitRequestedEventAction {
245 Prevent,
247}
248
249#[cfg(target_os = "macos")]
251#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
252#[non_exhaustive]
253pub enum ActivationPolicy {
254 Regular,
256 Accessory,
258 Prohibited,
260}
261
262pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
264 type Runtime: Runtime<T, Handle = Self>;
265
266 fn create_proxy(&self) -> <Self::Runtime as Runtime<T>>::EventLoopProxy;
268
269 #[cfg(target_os = "macos")]
271 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
272 fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;
273
274 #[cfg(target_os = "macos")]
276 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
277 fn set_dock_visibility(&self, visible: bool) -> Result<()>;
278
279 fn request_exit(&self, code: i32) -> Result<()>;
281
282 fn create_window<F: Fn(RawWindow) + Send + 'static>(
284 &self,
285 pending: PendingWindow<T, Self::Runtime>,
286 after_window_creation: Option<F>,
287 ) -> Result<DetachedWindow<T, Self::Runtime>>;
288
289 fn create_webview(
291 &self,
292 window_id: WindowId,
293 pending: PendingWebview<T, Self::Runtime>,
294 ) -> Result<DetachedWebview<T, Self::Runtime>>;
295
296 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
298
299 fn display_handle(&self) -> std::result::Result<DisplayHandle, raw_window_handle::HandleError>;
301
302 fn primary_monitor(&self) -> Option<Monitor>;
306
307 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
309
310 fn available_monitors(&self) -> Vec<Monitor>;
312
313 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
315
316 fn set_theme(&self, theme: Option<Theme>);
318
319 #[cfg(target_os = "macos")]
321 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
322 fn show(&self) -> Result<()>;
323
324 #[cfg(target_os = "macos")]
326 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
327 fn hide(&self) -> Result<()>;
328
329 #[cfg(target_os = "android")]
331 fn find_class<'a>(
332 &self,
333 env: &mut jni::JNIEnv<'a>,
334 activity: &jni::objects::JObject<'_>,
335 name: impl Into<String>,
336 ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
337
338 #[cfg(target_os = "android")]
342 fn run_on_android_context<F>(&self, f: F)
343 where
344 F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
345
346 #[cfg(any(target_os = "macos", target_os = "ios"))]
347 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
348 fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
349 &self,
350 cb: F,
351 ) -> Result<()>;
352
353 #[cfg(any(target_os = "macos", target_os = "ios"))]
354 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
355 fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
356 &self,
357 uuid: [u8; 16],
358 cb: F,
359 ) -> Result<()>;
360}
361
362pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
363 fn send_event(&self, event: T) -> Result<()>;
364}
365
366#[derive(Default)]
367pub struct RuntimeInitArgs {
368 #[cfg(any(
369 target_os = "linux",
370 target_os = "dragonfly",
371 target_os = "freebsd",
372 target_os = "netbsd",
373 target_os = "openbsd"
374 ))]
375 pub app_id: Option<String>,
376 #[cfg(windows)]
377 pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
378}
379
380pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
382 type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
384 type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
386 type Handle: RuntimeHandle<T, Runtime = Self>;
388 type EventLoopProxy: EventLoopProxy<T>;
390
391 fn new(args: RuntimeInitArgs) -> Result<Self>;
393
394 #[cfg(any(windows, target_os = "linux"))]
396 #[cfg_attr(docsrs, doc(cfg(any(windows, target_os = "linux"))))]
397 fn new_any_thread(args: RuntimeInitArgs) -> Result<Self>;
398
399 fn create_proxy(&self) -> Self::EventLoopProxy;
401
402 fn handle(&self) -> Self::Handle;
404
405 fn create_window<F: Fn(RawWindow) + Send + 'static>(
407 &self,
408 pending: PendingWindow<T, Self>,
409 after_window_creation: Option<F>,
410 ) -> Result<DetachedWindow<T, Self>>;
411
412 fn create_webview(
414 &self,
415 window_id: WindowId,
416 pending: PendingWebview<T, Self>,
417 ) -> Result<DetachedWebview<T, Self>>;
418
419 fn primary_monitor(&self) -> Option<Monitor>;
423
424 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
426
427 fn available_monitors(&self) -> Vec<Monitor>;
429
430 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
432
433 fn set_theme(&self, theme: Option<Theme>);
435
436 #[cfg(target_os = "macos")]
438 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
439 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
440
441 #[cfg(target_os = "macos")]
443 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
444 fn set_dock_visibility(&mut self, visible: bool);
445
446 #[cfg(target_os = "macos")]
448 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
449 fn show(&self);
450
451 #[cfg(target_os = "macos")]
453 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
454 fn hide(&self);
455
456 fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
468
469 #[cfg(desktop)]
471 fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
472
473 fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32;
475
476 fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
478}
479
480pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
482 type Runtime: Runtime<T>;
484
485 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
487
488 fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
490
491 fn with_webview<F: FnOnce(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()>;
493
494 #[cfg(any(debug_assertions, feature = "devtools"))]
496 fn open_devtools(&self);
497
498 #[cfg(any(debug_assertions, feature = "devtools"))]
500 fn close_devtools(&self);
501
502 #[cfg(any(debug_assertions, feature = "devtools"))]
504 fn is_devtools_open(&self) -> Result<bool>;
505
506 fn url(&self) -> Result<String>;
510
511 fn bounds(&self) -> Result<Rect>;
513
514 fn position(&self) -> Result<PhysicalPosition<i32>>;
516
517 fn size(&self) -> Result<PhysicalSize<u32>>;
519
520 fn navigate(&self, url: Url) -> Result<()>;
524
525 fn reload(&self) -> Result<()>;
527
528 fn print(&self) -> Result<()>;
530
531 fn close(&self) -> Result<()>;
533
534 fn set_bounds(&self, bounds: Rect) -> Result<()>;
536
537 fn set_size(&self, size: Size) -> Result<()>;
539
540 fn set_position(&self, position: Position) -> Result<()>;
542
543 fn set_focus(&self) -> Result<()>;
545
546 fn hide(&self) -> Result<()>;
548
549 fn show(&self) -> Result<()>;
551
552 fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
554
555 fn reparent(&self, window_id: WindowId) -> Result<()>;
557
558 fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
565
566 fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
573
574 fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
576
577 fn set_zoom(&self, scale_factor: f64) -> Result<()>;
579
580 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
582
583 fn clear_all_browsing_data(&self) -> Result<()>;
585}
586
587pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
589 type Runtime: Runtime<T>;
591
592 type WindowBuilder: WindowBuilder;
594
595 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
597
598 fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
600
601 fn scale_factor(&self) -> Result<f64>;
605
606 fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
608
609 fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
611
612 fn inner_size(&self) -> Result<PhysicalSize<u32>>;
616
617 fn outer_size(&self) -> Result<PhysicalSize<u32>>;
621
622 fn is_fullscreen(&self) -> Result<bool>;
624
625 fn is_minimized(&self) -> Result<bool>;
627
628 fn is_maximized(&self) -> Result<bool>;
630
631 fn is_focused(&self) -> Result<bool>;
633
634 fn is_decorated(&self) -> Result<bool>;
636
637 fn is_resizable(&self) -> Result<bool>;
639
640 fn is_maximizable(&self) -> Result<bool>;
646
647 fn is_minimizable(&self) -> Result<bool>;
653
654 fn is_closable(&self) -> Result<bool>;
660
661 fn is_visible(&self) -> Result<bool>;
663
664 fn is_enabled(&self) -> Result<bool>;
666
667 fn is_always_on_top(&self) -> Result<bool>;
673
674 fn title(&self) -> Result<String>;
676
677 fn current_monitor(&self) -> Result<Option<Monitor>>;
681
682 fn primary_monitor(&self) -> Result<Option<Monitor>>;
686
687 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
689
690 fn available_monitors(&self) -> Result<Vec<Monitor>>;
692
693 #[cfg(any(
695 target_os = "linux",
696 target_os = "dragonfly",
697 target_os = "freebsd",
698 target_os = "netbsd",
699 target_os = "openbsd"
700 ))]
701 fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;
702
703 #[cfg(any(
705 target_os = "linux",
706 target_os = "dragonfly",
707 target_os = "freebsd",
708 target_os = "netbsd",
709 target_os = "openbsd"
710 ))]
711 fn default_vbox(&self) -> Result<gtk::Box>;
712
713 fn window_handle(
715 &self,
716 ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
717
718 fn theme(&self) -> Result<Theme>;
720
721 fn center(&self) -> Result<()>;
725
726 fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
730
731 fn create_window<F: Fn(RawWindow) + Send + 'static>(
733 &mut self,
734 pending: PendingWindow<T, Self::Runtime>,
735 after_window_creation: Option<F>,
736 ) -> Result<DetachedWindow<T, Self::Runtime>>;
737
738 fn create_webview(
740 &mut self,
741 pending: PendingWebview<T, Self::Runtime>,
742 ) -> Result<DetachedWebview<T, Self::Runtime>>;
743
744 fn set_resizable(&self, resizable: bool) -> Result<()>;
746
747 fn set_enabled(&self, enabled: bool) -> Result<()>;
753
754 fn set_maximizable(&self, maximizable: bool) -> Result<()>;
761
762 fn set_minimizable(&self, minimizable: bool) -> Result<()>;
768
769 fn set_closable(&self, closable: bool) -> Result<()>;
777
778 fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
780
781 fn maximize(&self) -> Result<()>;
783
784 fn unmaximize(&self) -> Result<()>;
786
787 fn minimize(&self) -> Result<()>;
789
790 fn unminimize(&self) -> Result<()>;
792
793 fn show(&self) -> Result<()>;
795
796 fn hide(&self) -> Result<()>;
798
799 fn close(&self) -> Result<()>;
801
802 fn destroy(&self) -> Result<()>;
804
805 fn set_decorations(&self, decorations: bool) -> Result<()>;
807
808 fn set_shadow(&self, enable: bool) -> Result<()>;
810
811 fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
813
814 fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
816
817 fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
819
820 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
822
823 fn set_content_protected(&self, protected: bool) -> Result<()>;
825
826 fn set_size(&self, size: Size) -> Result<()>;
828
829 fn set_min_size(&self, size: Option<Size>) -> Result<()>;
831
832 fn set_max_size(&self, size: Option<Size>) -> Result<()>;
834
835 fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
837
838 fn set_position(&self, position: Position) -> Result<()>;
840
841 fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
843
844 fn set_focus(&self) -> Result<()>;
846
847 fn set_icon(&self, icon: Icon) -> Result<()>;
849
850 fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
852
853 fn set_cursor_grab(&self, grab: bool) -> Result<()>;
858
859 fn set_cursor_visible(&self, visible: bool) -> Result<()>;
863
864 fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
866
867 fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
869
870 fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
872
873 fn start_dragging(&self) -> Result<()>;
875
876 fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
878
879 fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
888
889 fn set_badge_label(&self, label: Option<String>) -> Result<()>;
891
892 fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
896
897 fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
904
905 fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
911
912 fn set_traffic_light_position(&self, position: Position) -> Result<()>;
920
921 fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
928}