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"))]
227 Opened { urls: Vec<url::Url> },
228 #[cfg(target_os = "macos")]
230 Reopen {
231 has_visible_windows: bool,
233 },
234 UserEvent(T),
236}
237
238#[derive(Debug)]
240pub enum ExitRequestedEventAction {
241 Prevent,
243}
244
245#[cfg(target_os = "macos")]
247#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
248#[non_exhaustive]
249pub enum ActivationPolicy {
250 Regular,
252 Accessory,
254 Prohibited,
256}
257
258pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
260 type Runtime: Runtime<T, Handle = Self>;
261
262 fn create_proxy(&self) -> <Self::Runtime as Runtime<T>>::EventLoopProxy;
264
265 #[cfg(target_os = "macos")]
267 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
268 fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;
269
270 #[cfg(target_os = "macos")]
272 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
273 fn set_dock_visibility(&self, visible: bool) -> Result<()>;
274
275 fn request_exit(&self, code: i32) -> Result<()>;
277
278 fn create_window<F: Fn(RawWindow) + Send + 'static>(
280 &self,
281 pending: PendingWindow<T, Self::Runtime>,
282 after_window_creation: Option<F>,
283 ) -> Result<DetachedWindow<T, Self::Runtime>>;
284
285 fn create_webview(
287 &self,
288 window_id: WindowId,
289 pending: PendingWebview<T, Self::Runtime>,
290 ) -> Result<DetachedWebview<T, Self::Runtime>>;
291
292 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
294
295 fn display_handle(
297 &self,
298 ) -> std::result::Result<DisplayHandle<'_>, raw_window_handle::HandleError>;
299
300 fn primary_monitor(&self) -> Option<Monitor>;
304
305 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
307
308 fn available_monitors(&self) -> Vec<Monitor>;
310
311 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
313
314 fn set_theme(&self, theme: Option<Theme>);
316
317 #[cfg(target_os = "macos")]
319 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
320 fn show(&self) -> Result<()>;
321
322 #[cfg(target_os = "macos")]
324 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
325 fn hide(&self) -> Result<()>;
326
327 fn set_device_event_filter(&self, filter: DeviceEventFilter);
335
336 #[cfg(target_os = "android")]
338 fn find_class<'a>(
339 &self,
340 env: &mut jni::JNIEnv<'a>,
341 activity: &jni::objects::JObject<'_>,
342 name: impl Into<String>,
343 ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
344
345 #[cfg(target_os = "android")]
349 fn run_on_android_context<F>(&self, f: F)
350 where
351 F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
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 fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
356 &self,
357 cb: F,
358 ) -> Result<()>;
359
360 #[cfg(any(target_os = "macos", target_os = "ios"))]
361 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
362 fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
363 &self,
364 uuid: [u8; 16],
365 cb: F,
366 ) -> Result<()>;
367}
368
369pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
370 fn send_event(&self, event: T) -> Result<()>;
371}
372
373#[derive(Default)]
374pub struct RuntimeInitArgs {
375 #[cfg(any(
376 target_os = "linux",
377 target_os = "dragonfly",
378 target_os = "freebsd",
379 target_os = "netbsd",
380 target_os = "openbsd"
381 ))]
382 pub app_id: Option<String>,
383 #[cfg(windows)]
384 pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
385}
386
387pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
389 type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
391 type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
393 type Handle: RuntimeHandle<T, Runtime = Self>;
395 type EventLoopProxy: EventLoopProxy<T>;
397
398 fn new(args: RuntimeInitArgs) -> Result<Self>;
400
401 #[cfg(any(
403 windows,
404 target_os = "linux",
405 target_os = "dragonfly",
406 target_os = "freebsd",
407 target_os = "netbsd",
408 target_os = "openbsd"
409 ))]
410 #[cfg_attr(
411 docsrs,
412 doc(cfg(any(
413 windows,
414 target_os = "linux",
415 target_os = "dragonfly",
416 target_os = "freebsd",
417 target_os = "netbsd",
418 target_os = "openbsd"
419 )))
420 )]
421 fn new_any_thread(args: RuntimeInitArgs) -> Result<Self>;
422
423 fn create_proxy(&self) -> Self::EventLoopProxy;
425
426 fn handle(&self) -> Self::Handle;
428
429 fn create_window<F: Fn(RawWindow) + Send + 'static>(
431 &self,
432 pending: PendingWindow<T, Self>,
433 after_window_creation: Option<F>,
434 ) -> Result<DetachedWindow<T, Self>>;
435
436 fn create_webview(
438 &self,
439 window_id: WindowId,
440 pending: PendingWebview<T, Self>,
441 ) -> Result<DetachedWebview<T, Self>>;
442
443 fn primary_monitor(&self) -> Option<Monitor>;
447
448 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
450
451 fn available_monitors(&self) -> Vec<Monitor>;
453
454 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
456
457 fn set_theme(&self, theme: Option<Theme>);
459
460 #[cfg(target_os = "macos")]
462 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
463 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
464
465 #[cfg(target_os = "macos")]
467 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
468 fn set_dock_visibility(&mut self, visible: bool);
469
470 #[cfg(target_os = "macos")]
472 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
473 fn show(&self);
474
475 #[cfg(target_os = "macos")]
477 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
478 fn hide(&self);
479
480 fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
492
493 #[cfg(desktop)]
495 fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
496
497 fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32;
499
500 fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
502}
503
504pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
506 type Runtime: Runtime<T>;
508
509 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
511
512 fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
514
515 fn with_webview<F: FnOnce(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()>;
517
518 #[cfg(any(debug_assertions, feature = "devtools"))]
520 fn open_devtools(&self);
521
522 #[cfg(any(debug_assertions, feature = "devtools"))]
524 fn close_devtools(&self);
525
526 #[cfg(any(debug_assertions, feature = "devtools"))]
528 fn is_devtools_open(&self) -> Result<bool>;
529
530 fn url(&self) -> Result<String>;
534
535 fn bounds(&self) -> Result<Rect>;
537
538 fn position(&self) -> Result<PhysicalPosition<i32>>;
540
541 fn size(&self) -> Result<PhysicalSize<u32>>;
543
544 fn navigate(&self, url: Url) -> Result<()>;
548
549 fn reload(&self) -> Result<()>;
551
552 fn print(&self) -> Result<()>;
554
555 fn close(&self) -> Result<()>;
557
558 fn set_bounds(&self, bounds: Rect) -> Result<()>;
560
561 fn set_size(&self, size: Size) -> Result<()>;
563
564 fn set_position(&self, position: Position) -> Result<()>;
566
567 fn set_focus(&self) -> Result<()>;
569
570 fn hide(&self) -> Result<()>;
572
573 fn show(&self) -> Result<()>;
575
576 fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
578
579 fn reparent(&self, window_id: WindowId) -> Result<()>;
581
582 fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
588
589 fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
596
597 fn set_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
603
604 fn delete_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
610
611 fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
613
614 fn set_zoom(&self, scale_factor: f64) -> Result<()>;
616
617 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
619
620 fn clear_all_browsing_data(&self) -> Result<()>;
622}
623
624pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
626 type Runtime: Runtime<T>;
628
629 type WindowBuilder: WindowBuilder;
631
632 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
634
635 fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
637
638 fn scale_factor(&self) -> Result<f64>;
642
643 fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
645
646 fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
648
649 fn inner_size(&self) -> Result<PhysicalSize<u32>>;
653
654 fn outer_size(&self) -> Result<PhysicalSize<u32>>;
658
659 fn is_fullscreen(&self) -> Result<bool>;
661
662 fn is_minimized(&self) -> Result<bool>;
664
665 fn is_maximized(&self) -> Result<bool>;
667
668 fn is_focused(&self) -> Result<bool>;
670
671 fn is_decorated(&self) -> Result<bool>;
673
674 fn is_resizable(&self) -> Result<bool>;
676
677 fn is_maximizable(&self) -> Result<bool>;
683
684 fn is_minimizable(&self) -> Result<bool>;
690
691 fn is_closable(&self) -> Result<bool>;
697
698 fn is_visible(&self) -> Result<bool>;
700
701 fn is_enabled(&self) -> Result<bool>;
703
704 fn is_always_on_top(&self) -> Result<bool>;
710
711 fn title(&self) -> Result<String>;
713
714 fn current_monitor(&self) -> Result<Option<Monitor>>;
718
719 fn primary_monitor(&self) -> Result<Option<Monitor>>;
723
724 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
726
727 fn available_monitors(&self) -> Result<Vec<Monitor>>;
729
730 #[cfg(any(
732 target_os = "linux",
733 target_os = "dragonfly",
734 target_os = "freebsd",
735 target_os = "netbsd",
736 target_os = "openbsd"
737 ))]
738 fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;
739
740 #[cfg(any(
742 target_os = "linux",
743 target_os = "dragonfly",
744 target_os = "freebsd",
745 target_os = "netbsd",
746 target_os = "openbsd"
747 ))]
748 fn default_vbox(&self) -> Result<gtk::Box>;
749
750 fn window_handle(
752 &self,
753 ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
754
755 fn theme(&self) -> Result<Theme>;
757
758 fn center(&self) -> Result<()>;
762
763 fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
767
768 fn create_window<F: Fn(RawWindow) + Send + 'static>(
770 &mut self,
771 pending: PendingWindow<T, Self::Runtime>,
772 after_window_creation: Option<F>,
773 ) -> Result<DetachedWindow<T, Self::Runtime>>;
774
775 fn create_webview(
777 &mut self,
778 pending: PendingWebview<T, Self::Runtime>,
779 ) -> Result<DetachedWebview<T, Self::Runtime>>;
780
781 fn set_resizable(&self, resizable: bool) -> Result<()>;
783
784 fn set_enabled(&self, enabled: bool) -> Result<()>;
790
791 fn set_maximizable(&self, maximizable: bool) -> Result<()>;
798
799 fn set_minimizable(&self, minimizable: bool) -> Result<()>;
805
806 fn set_closable(&self, closable: bool) -> Result<()>;
814
815 fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
817
818 fn maximize(&self) -> Result<()>;
820
821 fn unmaximize(&self) -> Result<()>;
823
824 fn minimize(&self) -> Result<()>;
826
827 fn unminimize(&self) -> Result<()>;
829
830 fn show(&self) -> Result<()>;
832
833 fn hide(&self) -> Result<()>;
835
836 fn close(&self) -> Result<()>;
838
839 fn destroy(&self) -> Result<()>;
841
842 fn set_decorations(&self, decorations: bool) -> Result<()>;
844
845 fn set_shadow(&self, enable: bool) -> Result<()>;
847
848 fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
850
851 fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
853
854 fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
856
857 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
859
860 fn set_content_protected(&self, protected: bool) -> Result<()>;
862
863 fn set_size(&self, size: Size) -> Result<()>;
865
866 fn set_min_size(&self, size: Option<Size>) -> Result<()>;
868
869 fn set_max_size(&self, size: Option<Size>) -> Result<()>;
871
872 fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
874
875 fn set_position(&self, position: Position) -> Result<()>;
877
878 fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
880
881 #[cfg(target_os = "macos")]
882 fn set_simple_fullscreen(&self, enable: bool) -> Result<()>;
883
884 fn set_focus(&self) -> Result<()>;
886
887 fn set_focusable(&self, focusable: bool) -> Result<()>;
889
890 fn set_icon(&self, icon: Icon) -> Result<()>;
892
893 fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
895
896 fn set_cursor_grab(&self, grab: bool) -> Result<()>;
901
902 fn set_cursor_visible(&self, visible: bool) -> Result<()>;
906
907 fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
909
910 fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
912
913 fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
915
916 fn start_dragging(&self) -> Result<()>;
918
919 fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
921
922 fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
931
932 fn set_badge_label(&self, label: Option<String>) -> Result<()>;
934
935 fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
939
940 fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
947
948 fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
954
955 fn set_traffic_light_position(&self, position: Position) -> Result<()>;
963
964 fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
971}