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(Default, Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
94#[serde(tag = "type")]
95pub enum DeviceEventFilter {
96 Always,
98 #[default]
100 Unfocused,
101 Never,
103}
104
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
107pub enum ResizeDirection {
108 East,
109 North,
110 NorthEast,
111 NorthWest,
112 South,
113 SouthEast,
114 SouthWest,
115 West,
116}
117
118#[derive(Debug, thiserror::Error)]
119#[non_exhaustive]
120pub enum Error {
121 #[error("failed to create webview: {0}")]
123 CreateWebview(Box<dyn std::error::Error + Send + Sync>),
124 #[error("failed to create window")]
127 CreateWindow,
128 #[error("Window labels must only include alphanumeric characters, `-`, `/`, `:` and `_`.")]
130 InvalidWindowLabel,
131 #[error("failed to send message to the webview")]
133 FailedToSendMessage,
134 #[error("failed to receive message from webview")]
136 FailedToReceiveMessage,
137 #[error("JSON error: {0}")]
139 Json(#[from] serde_json::Error),
140 #[error("invalid icon: {0}")]
142 InvalidIcon(Box<dyn std::error::Error + Send + Sync>),
143 #[error("failed to get monitor")]
145 FailedToGetMonitor,
146 #[error("failed to get cursor position")]
148 FailedToGetCursorPosition,
149 #[error("Invalid header name: {0}")]
150 InvalidHeaderName(#[from] InvalidHeaderName),
151 #[error("Invalid header value: {0}")]
152 InvalidHeaderValue(#[from] InvalidHeaderValue),
153 #[error("Invalid status code: {0}")]
154 InvalidStatusCode(#[from] InvalidStatusCode),
155 #[error("Invalid method: {0}")]
156 InvalidMethod(#[from] InvalidMethod),
157 #[error("Infallible error, something went really wrong: {0}")]
158 Infallible(#[from] std::convert::Infallible),
159 #[error("the event loop has been closed")]
160 EventLoopClosed,
161 #[error("Invalid proxy url")]
162 InvalidProxyUrl,
163 #[error("window not found")]
164 WindowNotFound,
165 #[cfg(any(target_os = "macos", target_os = "ios"))]
166 #[error("failed to remove data store")]
167 FailedToRemoveDataStore,
168 #[error("Could not find the webview runtime, make sure it is installed")]
169 WebviewRuntimeNotInstalled,
170}
171
172pub type Result<T> = std::result::Result<T, Error>;
174
175#[derive(Debug, Clone)]
177pub struct Icon<'a> {
178 pub rgba: Cow<'a, [u8]>,
180 pub width: u32,
182 pub height: u32,
184}
185
186pub trait UserEvent: Debug + Clone + Send + 'static {}
188
189impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
190
191#[derive(Debug)]
193#[non_exhaustive]
194pub enum RunEvent<T: UserEvent> {
195 Exit,
197 ExitRequested {
199 code: Option<i32>,
201 tx: Sender<ExitRequestedEventAction>,
202 },
203 WindowEvent {
205 label: String,
207 event: WindowEvent,
209 },
210 WebviewEvent {
212 label: String,
214 event: WebviewEvent,
216 },
217 Ready,
219 Resumed,
221 MainEventsCleared,
225 #[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
227 Opened { urls: Vec<url::Url> },
228 #[cfg(target_os = "macos")]
230 Reopen {
231 has_visible_windows: bool,
233 },
234 UserEvent(T),
236 #[cfg(target_os = "ios")]
242 SceneRequested {
243 scene: objc2::rc::Retained<objc2_ui_kit::UIScene>,
245 options: objc2::rc::Retained<objc2_ui_kit::UISceneConnectionOptions>,
249 },
250}
251
252#[derive(Debug)]
254pub enum ExitRequestedEventAction {
255 Prevent,
257}
258
259#[cfg(target_os = "macos")]
261#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
262#[non_exhaustive]
263pub enum ActivationPolicy {
264 Regular,
266 Accessory,
268 Prohibited,
270}
271
272pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
274 type Runtime: Runtime<T, Handle = Self>;
275
276 fn create_proxy(&self) -> <Self::Runtime as Runtime<T>>::EventLoopProxy;
278
279 #[cfg(target_os = "macos")]
281 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
282 fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;
283
284 #[cfg(target_os = "macos")]
286 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
287 fn set_dock_visibility(&self, visible: bool) -> Result<()>;
288
289 fn request_exit(&self, code: i32) -> Result<()>;
291
292 fn create_window<F: Fn(RawWindow) + Send + 'static>(
294 &self,
295 pending: PendingWindow<T, Self::Runtime>,
296 after_window_creation: Option<F>,
297 ) -> Result<DetachedWindow<T, Self::Runtime>>;
298
299 fn create_webview(
301 &self,
302 window_id: WindowId,
303 pending: PendingWebview<T, Self::Runtime>,
304 ) -> Result<DetachedWebview<T, Self::Runtime>>;
305
306 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
308
309 fn display_handle(
311 &self,
312 ) -> std::result::Result<DisplayHandle<'_>, raw_window_handle::HandleError>;
313
314 fn primary_monitor(&self) -> Option<Monitor>;
318
319 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
321
322 fn available_monitors(&self) -> Vec<Monitor>;
324
325 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
327
328 fn set_theme(&self, theme: Option<Theme>);
330
331 #[cfg(target_os = "macos")]
333 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
334 fn show(&self) -> Result<()>;
335
336 #[cfg(target_os = "macos")]
338 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
339 fn hide(&self) -> Result<()>;
340
341 fn set_device_event_filter(&self, filter: DeviceEventFilter);
349
350 #[cfg(target_os = "android")]
352 fn find_class<'a>(
353 &self,
354 env: &mut jni::JNIEnv<'a>,
355 activity: &jni::objects::JObject<'_>,
356 name: impl Into<String>,
357 ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
358
359 #[cfg(target_os = "android")]
363 fn run_on_android_context<F>(&self, f: F)
364 where
365 F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
366
367 #[cfg(any(target_os = "macos", target_os = "ios"))]
368 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
369 fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
370 &self,
371 cb: F,
372 ) -> Result<()>;
373
374 #[cfg(any(target_os = "macos", target_os = "ios"))]
375 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
376 fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
377 &self,
378 uuid: [u8; 16],
379 cb: F,
380 ) -> Result<()>;
381}
382
383pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
384 fn send_event(&self, event: T) -> Result<()>;
385}
386
387#[derive(Default)]
388pub struct RuntimeInitArgs {
389 #[cfg(any(
390 target_os = "linux",
391 target_os = "dragonfly",
392 target_os = "freebsd",
393 target_os = "netbsd",
394 target_os = "openbsd"
395 ))]
396 pub app_id: Option<String>,
397 #[cfg(windows)]
398 pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
399}
400
401pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
403 type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
405 type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
407 type Handle: RuntimeHandle<T, Runtime = Self>;
409 type EventLoopProxy: EventLoopProxy<T>;
411
412 fn new(args: RuntimeInitArgs) -> Result<Self>;
414
415 #[cfg(any(
417 windows,
418 target_os = "linux",
419 target_os = "dragonfly",
420 target_os = "freebsd",
421 target_os = "netbsd",
422 target_os = "openbsd"
423 ))]
424 #[cfg_attr(
425 docsrs,
426 doc(cfg(any(
427 windows,
428 target_os = "linux",
429 target_os = "dragonfly",
430 target_os = "freebsd",
431 target_os = "netbsd",
432 target_os = "openbsd"
433 )))
434 )]
435 fn new_any_thread(args: RuntimeInitArgs) -> Result<Self>;
436
437 fn create_proxy(&self) -> Self::EventLoopProxy;
439
440 fn handle(&self) -> Self::Handle;
442
443 fn create_window<F: Fn(RawWindow) + Send + 'static>(
445 &self,
446 pending: PendingWindow<T, Self>,
447 after_window_creation: Option<F>,
448 ) -> Result<DetachedWindow<T, Self>>;
449
450 fn create_webview(
452 &self,
453 window_id: WindowId,
454 pending: PendingWebview<T, Self>,
455 ) -> Result<DetachedWebview<T, Self>>;
456
457 fn primary_monitor(&self) -> Option<Monitor>;
461
462 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
464
465 fn available_monitors(&self) -> Vec<Monitor>;
467
468 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
470
471 fn set_theme(&self, theme: Option<Theme>);
473
474 #[cfg(target_os = "macos")]
476 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
477 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
478
479 #[cfg(target_os = "macos")]
481 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
482 fn set_dock_visibility(&mut self, visible: bool);
483
484 #[cfg(target_os = "macos")]
486 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
487 fn show(&self);
488
489 #[cfg(target_os = "macos")]
491 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
492 fn hide(&self);
493
494 fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
506
507 #[cfg(desktop)]
509 fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
510
511 fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32;
513
514 fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
516}
517
518pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
520 type Runtime: Runtime<T>;
522
523 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
525
526 fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
528
529 fn with_webview<F: FnOnce(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()>;
531
532 #[cfg(any(debug_assertions, feature = "devtools"))]
534 fn open_devtools(&self);
535
536 #[cfg(any(debug_assertions, feature = "devtools"))]
538 fn close_devtools(&self);
539
540 #[cfg(any(debug_assertions, feature = "devtools"))]
542 fn is_devtools_open(&self) -> Result<bool>;
543
544 fn url(&self) -> Result<String>;
548
549 fn bounds(&self) -> Result<Rect>;
551
552 fn position(&self) -> Result<PhysicalPosition<i32>>;
554
555 fn size(&self) -> Result<PhysicalSize<u32>>;
557
558 fn navigate(&self, url: Url) -> Result<()>;
562
563 fn reload(&self) -> Result<()>;
565
566 fn print(&self) -> Result<()>;
568
569 fn close(&self) -> Result<()>;
571
572 fn set_bounds(&self, bounds: Rect) -> Result<()>;
574
575 fn set_size(&self, size: Size) -> Result<()>;
577
578 fn set_position(&self, position: Position) -> Result<()>;
580
581 fn set_focus(&self) -> Result<()>;
583
584 fn hide(&self) -> Result<()>;
586
587 fn show(&self) -> Result<()>;
589
590 fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
592
593 fn eval_script_with_callback<S: Into<String>>(
598 &self,
599 script: S,
600 callback: impl Fn(String) + Send + 'static,
601 ) -> Result<()>;
602
603 fn reparent(&self, window_id: WindowId) -> Result<()>;
605
606 fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
612
613 fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
620
621 fn set_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
627
628 fn delete_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
634
635 fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
637
638 fn set_zoom(&self, scale_factor: f64) -> Result<()>;
640
641 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
643
644 fn clear_all_browsing_data(&self) -> Result<()>;
646}
647
648pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
650 type Runtime: Runtime<T>;
652
653 type WindowBuilder: WindowBuilder;
655
656 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
658
659 fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
661
662 fn scale_factor(&self) -> Result<f64>;
666
667 fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
669
670 fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
672
673 fn inner_size(&self) -> Result<PhysicalSize<u32>>;
677
678 fn outer_size(&self) -> Result<PhysicalSize<u32>>;
682
683 fn is_fullscreen(&self) -> Result<bool>;
685
686 fn is_minimized(&self) -> Result<bool>;
688
689 fn is_maximized(&self) -> Result<bool>;
691
692 fn is_focused(&self) -> Result<bool>;
694
695 fn is_decorated(&self) -> Result<bool>;
697
698 fn is_resizable(&self) -> Result<bool>;
700
701 fn is_maximizable(&self) -> Result<bool>;
707
708 fn is_minimizable(&self) -> Result<bool>;
714
715 fn is_closable(&self) -> Result<bool>;
721
722 fn is_visible(&self) -> Result<bool>;
724
725 fn is_enabled(&self) -> Result<bool>;
727
728 fn is_always_on_top(&self) -> Result<bool>;
734
735 fn title(&self) -> Result<String>;
737
738 fn current_monitor(&self) -> Result<Option<Monitor>>;
742
743 fn primary_monitor(&self) -> Result<Option<Monitor>>;
747
748 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
750
751 fn available_monitors(&self) -> Result<Vec<Monitor>>;
753
754 #[cfg(any(
756 target_os = "linux",
757 target_os = "dragonfly",
758 target_os = "freebsd",
759 target_os = "netbsd",
760 target_os = "openbsd"
761 ))]
762 fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;
763
764 #[cfg(any(
766 target_os = "linux",
767 target_os = "dragonfly",
768 target_os = "freebsd",
769 target_os = "netbsd",
770 target_os = "openbsd"
771 ))]
772 fn default_vbox(&self) -> Result<gtk::Box>;
773
774 #[cfg(target_os = "android")]
776 fn activity_name(&self) -> Result<String>;
777
778 #[cfg(target_os = "ios")]
780 fn scene_identifier(&self) -> Result<String>;
781
782 fn window_handle(
784 &self,
785 ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
786
787 fn theme(&self) -> Result<Theme>;
789
790 fn center(&self) -> Result<()>;
794
795 fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
799
800 fn create_window<F: Fn(RawWindow) + Send + 'static>(
802 &mut self,
803 pending: PendingWindow<T, Self::Runtime>,
804 after_window_creation: Option<F>,
805 ) -> Result<DetachedWindow<T, Self::Runtime>>;
806
807 fn create_webview(
809 &mut self,
810 pending: PendingWebview<T, Self::Runtime>,
811 ) -> Result<DetachedWebview<T, Self::Runtime>>;
812
813 fn set_resizable(&self, resizable: bool) -> Result<()>;
815
816 fn set_enabled(&self, enabled: bool) -> Result<()>;
822
823 fn set_maximizable(&self, maximizable: bool) -> Result<()>;
830
831 fn set_minimizable(&self, minimizable: bool) -> Result<()>;
837
838 fn set_closable(&self, closable: bool) -> Result<()>;
846
847 fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
849
850 fn maximize(&self) -> Result<()>;
852
853 fn unmaximize(&self) -> Result<()>;
855
856 fn minimize(&self) -> Result<()>;
858
859 fn unminimize(&self) -> Result<()>;
861
862 fn show(&self) -> Result<()>;
864
865 fn hide(&self) -> Result<()>;
867
868 fn close(&self) -> Result<()>;
870
871 fn destroy(&self) -> Result<()>;
873
874 fn set_decorations(&self, decorations: bool) -> Result<()>;
876
877 fn set_shadow(&self, enable: bool) -> Result<()>;
879
880 fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
882
883 fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
885
886 fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
888
889 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
891
892 fn set_content_protected(&self, protected: bool) -> Result<()>;
894
895 fn set_size(&self, size: Size) -> Result<()>;
897
898 fn set_min_size(&self, size: Option<Size>) -> Result<()>;
900
901 fn set_max_size(&self, size: Option<Size>) -> Result<()>;
903
904 fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
906
907 fn set_position(&self, position: Position) -> Result<()>;
909
910 fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
912
913 #[cfg(target_os = "macos")]
914 fn set_simple_fullscreen(&self, enable: bool) -> Result<()>;
915
916 fn set_focus(&self) -> Result<()>;
918
919 fn set_focusable(&self, focusable: bool) -> Result<()>;
921
922 fn set_icon(&self, icon: Icon) -> Result<()>;
924
925 fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
927
928 fn set_cursor_grab(&self, grab: bool) -> Result<()>;
933
934 fn set_cursor_visible(&self, visible: bool) -> Result<()>;
938
939 fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
941
942 fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
944
945 fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
947
948 fn start_dragging(&self) -> Result<()>;
950
951 fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
953
954 fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
963
964 fn set_badge_label(&self, label: Option<String>) -> Result<()>;
966
967 fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
971
972 fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
979
980 fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
986
987 fn set_traffic_light_position(&self, position: Position) -> Result<()>;
995
996 fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
1003}