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")]
132 CreateWindow,
133 #[error("Window labels must only include alphanumeric characters, `-`, `/`, `:` and `_`.")]
135 InvalidWindowLabel,
136 #[error("failed to send message to the webview")]
138 FailedToSendMessage,
139 #[error("failed to receive message from webview")]
141 FailedToReceiveMessage,
142 #[error("JSON error: {0}")]
144 Json(#[from] serde_json::Error),
145 #[error("invalid icon: {0}")]
147 InvalidIcon(Box<dyn std::error::Error + Send + Sync>),
148 #[error("failed to get monitor")]
150 FailedToGetMonitor,
151 #[error("failed to get cursor position")]
153 FailedToGetCursorPosition,
154 #[error("Invalid header name: {0}")]
155 InvalidHeaderName(#[from] InvalidHeaderName),
156 #[error("Invalid header value: {0}")]
157 InvalidHeaderValue(#[from] InvalidHeaderValue),
158 #[error("Invalid status code: {0}")]
159 InvalidStatusCode(#[from] InvalidStatusCode),
160 #[error("Invalid method: {0}")]
161 InvalidMethod(#[from] InvalidMethod),
162 #[error("Infallible error, something went really wrong: {0}")]
163 Infallible(#[from] std::convert::Infallible),
164 #[error("the event loop has been closed")]
165 EventLoopClosed,
166 #[error("Invalid proxy url")]
167 InvalidProxyUrl,
168 #[error("window not found")]
169 WindowNotFound,
170 #[cfg(any(target_os = "macos", target_os = "ios"))]
171 #[error("failed to remove data store")]
172 FailedToRemoveDataStore,
173 #[error("Could not find the webview runtime, make sure it is installed")]
174 WebviewRuntimeNotInstalled,
175}
176
177pub type Result<T> = std::result::Result<T, Error>;
179
180#[derive(Debug, Clone)]
182pub struct Icon<'a> {
183 pub rgba: Cow<'a, [u8]>,
185 pub width: u32,
187 pub height: u32,
189}
190
191pub trait UserEvent: Debug + Clone + Send + 'static {}
193
194impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
195
196#[derive(Debug)]
198#[non_exhaustive]
199pub enum RunEvent<T: UserEvent> {
200 Exit,
202 ExitRequested {
204 code: Option<i32>,
206 tx: Sender<ExitRequestedEventAction>,
207 },
208 WindowEvent {
210 label: String,
212 event: WindowEvent,
214 },
215 WebviewEvent {
217 label: String,
219 event: WebviewEvent,
221 },
222 Ready,
224 Resumed,
226 MainEventsCleared,
230 #[cfg(any(target_os = "macos", target_os = "ios"))]
232 Opened { urls: Vec<url::Url> },
233 #[cfg(target_os = "macos")]
235 Reopen {
236 has_visible_windows: bool,
238 },
239 UserEvent(T),
241}
242
243#[derive(Debug)]
245pub enum ExitRequestedEventAction {
246 Prevent,
248}
249
250#[cfg(target_os = "macos")]
252#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
253#[non_exhaustive]
254pub enum ActivationPolicy {
255 Regular,
257 Accessory,
259 Prohibited,
261}
262
263pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
265 type Runtime: Runtime<T, Handle = Self>;
266
267 fn create_proxy(&self) -> <Self::Runtime as Runtime<T>>::EventLoopProxy;
269
270 #[cfg(target_os = "macos")]
272 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
273 fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;
274
275 #[cfg(target_os = "macos")]
277 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
278 fn set_dock_visibility(&self, visible: bool) -> Result<()>;
279
280 fn request_exit(&self, code: i32) -> Result<()>;
282
283 fn create_window<F: Fn(RawWindow) + Send + 'static>(
285 &self,
286 pending: PendingWindow<T, Self::Runtime>,
287 after_window_creation: Option<F>,
288 ) -> Result<DetachedWindow<T, Self::Runtime>>;
289
290 fn create_webview(
292 &self,
293 window_id: WindowId,
294 pending: PendingWebview<T, Self::Runtime>,
295 ) -> Result<DetachedWebview<T, Self::Runtime>>;
296
297 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
299
300 fn display_handle(
302 &self,
303 ) -> std::result::Result<DisplayHandle<'_>, raw_window_handle::HandleError>;
304
305 fn primary_monitor(&self) -> Option<Monitor>;
309
310 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
312
313 fn available_monitors(&self) -> Vec<Monitor>;
315
316 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
318
319 fn set_theme(&self, theme: Option<Theme>);
321
322 #[cfg(target_os = "macos")]
324 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
325 fn show(&self) -> Result<()>;
326
327 #[cfg(target_os = "macos")]
329 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
330 fn hide(&self) -> Result<()>;
331
332 fn set_device_event_filter(&self, filter: DeviceEventFilter);
340
341 #[cfg(target_os = "android")]
343 fn find_class<'a>(
344 &self,
345 env: &mut jni::JNIEnv<'a>,
346 activity: &jni::objects::JObject<'_>,
347 name: impl Into<String>,
348 ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
349
350 #[cfg(target_os = "android")]
354 fn run_on_android_context<F>(&self, f: F)
355 where
356 F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
357
358 #[cfg(any(target_os = "macos", target_os = "ios"))]
359 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
360 fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
361 &self,
362 cb: F,
363 ) -> Result<()>;
364
365 #[cfg(any(target_os = "macos", target_os = "ios"))]
366 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
367 fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
368 &self,
369 uuid: [u8; 16],
370 cb: F,
371 ) -> Result<()>;
372}
373
374pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
375 fn send_event(&self, event: T) -> Result<()>;
376}
377
378#[derive(Default)]
379pub struct RuntimeInitArgs {
380 #[cfg(any(
381 target_os = "linux",
382 target_os = "dragonfly",
383 target_os = "freebsd",
384 target_os = "netbsd",
385 target_os = "openbsd"
386 ))]
387 pub app_id: Option<String>,
388 #[cfg(windows)]
389 pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
390}
391
392pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
394 type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
396 type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
398 type Handle: RuntimeHandle<T, Runtime = Self>;
400 type EventLoopProxy: EventLoopProxy<T>;
402
403 fn new(args: RuntimeInitArgs) -> Result<Self>;
405
406 #[cfg(any(windows, target_os = "linux"))]
408 #[cfg_attr(docsrs, doc(cfg(any(windows, target_os = "linux"))))]
409 fn new_any_thread(args: RuntimeInitArgs) -> Result<Self>;
410
411 fn create_proxy(&self) -> Self::EventLoopProxy;
413
414 fn handle(&self) -> Self::Handle;
416
417 fn create_window<F: Fn(RawWindow) + Send + 'static>(
419 &self,
420 pending: PendingWindow<T, Self>,
421 after_window_creation: Option<F>,
422 ) -> Result<DetachedWindow<T, Self>>;
423
424 fn create_webview(
426 &self,
427 window_id: WindowId,
428 pending: PendingWebview<T, Self>,
429 ) -> Result<DetachedWebview<T, Self>>;
430
431 fn primary_monitor(&self) -> Option<Monitor>;
435
436 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
438
439 fn available_monitors(&self) -> Vec<Monitor>;
441
442 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
444
445 fn set_theme(&self, theme: Option<Theme>);
447
448 #[cfg(target_os = "macos")]
450 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
451 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
452
453 #[cfg(target_os = "macos")]
455 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
456 fn set_dock_visibility(&mut self, visible: bool);
457
458 #[cfg(target_os = "macos")]
460 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
461 fn show(&self);
462
463 #[cfg(target_os = "macos")]
465 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
466 fn hide(&self);
467
468 fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
480
481 #[cfg(desktop)]
483 fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
484
485 fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32;
487
488 fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
490}
491
492pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
494 type Runtime: Runtime<T>;
496
497 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
499
500 fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
502
503 fn with_webview<F: FnOnce(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()>;
505
506 #[cfg(any(debug_assertions, feature = "devtools"))]
508 fn open_devtools(&self);
509
510 #[cfg(any(debug_assertions, feature = "devtools"))]
512 fn close_devtools(&self);
513
514 #[cfg(any(debug_assertions, feature = "devtools"))]
516 fn is_devtools_open(&self) -> Result<bool>;
517
518 fn url(&self) -> Result<String>;
522
523 fn bounds(&self) -> Result<Rect>;
525
526 fn position(&self) -> Result<PhysicalPosition<i32>>;
528
529 fn size(&self) -> Result<PhysicalSize<u32>>;
531
532 fn navigate(&self, url: Url) -> Result<()>;
536
537 fn reload(&self) -> Result<()>;
539
540 fn print(&self) -> Result<()>;
542
543 fn close(&self) -> Result<()>;
545
546 fn set_bounds(&self, bounds: Rect) -> Result<()>;
548
549 fn set_size(&self, size: Size) -> Result<()>;
551
552 fn set_position(&self, position: Position) -> Result<()>;
554
555 fn set_focus(&self) -> Result<()>;
557
558 fn hide(&self) -> Result<()>;
560
561 fn show(&self) -> Result<()>;
563
564 fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
566
567 fn reparent(&self, window_id: WindowId) -> Result<()>;
569
570 fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
576
577 fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
584
585 fn set_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
591
592 fn delete_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
598
599 fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
601
602 fn set_zoom(&self, scale_factor: f64) -> Result<()>;
604
605 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
607
608 fn clear_all_browsing_data(&self) -> Result<()>;
610}
611
612pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
614 type Runtime: Runtime<T>;
616
617 type WindowBuilder: WindowBuilder;
619
620 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
622
623 fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
625
626 fn scale_factor(&self) -> Result<f64>;
630
631 fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
633
634 fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
636
637 fn inner_size(&self) -> Result<PhysicalSize<u32>>;
641
642 fn outer_size(&self) -> Result<PhysicalSize<u32>>;
646
647 fn is_fullscreen(&self) -> Result<bool>;
649
650 fn is_minimized(&self) -> Result<bool>;
652
653 fn is_maximized(&self) -> Result<bool>;
655
656 fn is_focused(&self) -> Result<bool>;
658
659 fn is_decorated(&self) -> Result<bool>;
661
662 fn is_resizable(&self) -> Result<bool>;
664
665 fn is_maximizable(&self) -> Result<bool>;
671
672 fn is_minimizable(&self) -> Result<bool>;
678
679 fn is_closable(&self) -> Result<bool>;
685
686 fn is_visible(&self) -> Result<bool>;
688
689 fn is_enabled(&self) -> Result<bool>;
691
692 fn is_always_on_top(&self) -> Result<bool>;
698
699 fn title(&self) -> Result<String>;
701
702 fn current_monitor(&self) -> Result<Option<Monitor>>;
706
707 fn primary_monitor(&self) -> Result<Option<Monitor>>;
711
712 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
714
715 fn available_monitors(&self) -> Result<Vec<Monitor>>;
717
718 #[cfg(any(
720 target_os = "linux",
721 target_os = "dragonfly",
722 target_os = "freebsd",
723 target_os = "netbsd",
724 target_os = "openbsd"
725 ))]
726 fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;
727
728 #[cfg(any(
730 target_os = "linux",
731 target_os = "dragonfly",
732 target_os = "freebsd",
733 target_os = "netbsd",
734 target_os = "openbsd"
735 ))]
736 fn default_vbox(&self) -> Result<gtk::Box>;
737
738 fn window_handle(
740 &self,
741 ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
742
743 fn theme(&self) -> Result<Theme>;
745
746 fn center(&self) -> Result<()>;
750
751 fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
755
756 fn create_window<F: Fn(RawWindow) + Send + 'static>(
758 &mut self,
759 pending: PendingWindow<T, Self::Runtime>,
760 after_window_creation: Option<F>,
761 ) -> Result<DetachedWindow<T, Self::Runtime>>;
762
763 fn create_webview(
765 &mut self,
766 pending: PendingWebview<T, Self::Runtime>,
767 ) -> Result<DetachedWebview<T, Self::Runtime>>;
768
769 fn set_resizable(&self, resizable: bool) -> Result<()>;
771
772 fn set_enabled(&self, enabled: bool) -> Result<()>;
778
779 fn set_maximizable(&self, maximizable: bool) -> Result<()>;
786
787 fn set_minimizable(&self, minimizable: bool) -> Result<()>;
793
794 fn set_closable(&self, closable: bool) -> Result<()>;
802
803 fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
805
806 fn maximize(&self) -> Result<()>;
808
809 fn unmaximize(&self) -> Result<()>;
811
812 fn minimize(&self) -> Result<()>;
814
815 fn unminimize(&self) -> Result<()>;
817
818 fn show(&self) -> Result<()>;
820
821 fn hide(&self) -> Result<()>;
823
824 fn close(&self) -> Result<()>;
826
827 fn destroy(&self) -> Result<()>;
829
830 fn set_decorations(&self, decorations: bool) -> Result<()>;
832
833 fn set_shadow(&self, enable: bool) -> Result<()>;
835
836 fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
838
839 fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
841
842 fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
844
845 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
847
848 fn set_content_protected(&self, protected: bool) -> Result<()>;
850
851 fn set_size(&self, size: Size) -> Result<()>;
853
854 fn set_min_size(&self, size: Option<Size>) -> Result<()>;
856
857 fn set_max_size(&self, size: Option<Size>) -> Result<()>;
859
860 fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
862
863 fn set_position(&self, position: Position) -> Result<()>;
865
866 fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
868
869 #[cfg(target_os = "macos")]
870 fn set_simple_fullscreen(&self, enable: bool) -> Result<()>;
871
872 fn set_focus(&self) -> Result<()>;
874
875 fn set_focusable(&self, focusable: bool) -> Result<()>;
877
878 fn set_icon(&self, icon: Icon) -> Result<()>;
880
881 fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
883
884 fn set_cursor_grab(&self, grab: bool) -> Result<()>;
889
890 fn set_cursor_visible(&self, visible: bool) -> Result<()>;
894
895 fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
897
898 fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
900
901 fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
903
904 fn start_dragging(&self) -> Result<()>;
906
907 fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
909
910 fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
919
920 fn set_badge_label(&self, label: Option<String>) -> Result<()>;
922
923 fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
927
928 fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
935
936 fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
942
943 fn set_traffic_light_position(&self, position: Position) -> Result<()>;
951
952 fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
959}