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(windows, target_os = "linux"))]
403 #[cfg_attr(docsrs, doc(cfg(any(windows, target_os = "linux"))))]
404 fn new_any_thread(args: RuntimeInitArgs) -> Result<Self>;
405
406 fn create_proxy(&self) -> Self::EventLoopProxy;
408
409 fn handle(&self) -> Self::Handle;
411
412 fn create_window<F: Fn(RawWindow) + Send + 'static>(
414 &self,
415 pending: PendingWindow<T, Self>,
416 after_window_creation: Option<F>,
417 ) -> Result<DetachedWindow<T, Self>>;
418
419 fn create_webview(
421 &self,
422 window_id: WindowId,
423 pending: PendingWebview<T, Self>,
424 ) -> Result<DetachedWebview<T, Self>>;
425
426 fn primary_monitor(&self) -> Option<Monitor>;
430
431 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
433
434 fn available_monitors(&self) -> Vec<Monitor>;
436
437 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
439
440 fn set_theme(&self, theme: Option<Theme>);
442
443 #[cfg(target_os = "macos")]
445 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
446 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
447
448 #[cfg(target_os = "macos")]
450 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
451 fn set_dock_visibility(&mut self, visible: bool);
452
453 #[cfg(target_os = "macos")]
455 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
456 fn show(&self);
457
458 #[cfg(target_os = "macos")]
460 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
461 fn hide(&self);
462
463 fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
475
476 #[cfg(desktop)]
478 fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
479
480 fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32;
482
483 fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
485}
486
487pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
489 type Runtime: Runtime<T>;
491
492 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
494
495 fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
497
498 fn with_webview<F: FnOnce(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()>;
500
501 #[cfg(any(debug_assertions, feature = "devtools"))]
503 fn open_devtools(&self);
504
505 #[cfg(any(debug_assertions, feature = "devtools"))]
507 fn close_devtools(&self);
508
509 #[cfg(any(debug_assertions, feature = "devtools"))]
511 fn is_devtools_open(&self) -> Result<bool>;
512
513 fn url(&self) -> Result<String>;
517
518 fn bounds(&self) -> Result<Rect>;
520
521 fn position(&self) -> Result<PhysicalPosition<i32>>;
523
524 fn size(&self) -> Result<PhysicalSize<u32>>;
526
527 fn navigate(&self, url: Url) -> Result<()>;
531
532 fn reload(&self) -> Result<()>;
534
535 fn print(&self) -> Result<()>;
537
538 fn close(&self) -> Result<()>;
540
541 fn set_bounds(&self, bounds: Rect) -> Result<()>;
543
544 fn set_size(&self, size: Size) -> Result<()>;
546
547 fn set_position(&self, position: Position) -> Result<()>;
549
550 fn set_focus(&self) -> Result<()>;
552
553 fn hide(&self) -> Result<()>;
555
556 fn show(&self) -> Result<()>;
558
559 fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
561
562 fn reparent(&self, window_id: WindowId) -> Result<()>;
564
565 fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
571
572 fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
579
580 fn set_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
586
587 fn delete_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
593
594 fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
596
597 fn set_zoom(&self, scale_factor: f64) -> Result<()>;
599
600 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
602
603 fn clear_all_browsing_data(&self) -> Result<()>;
605}
606
607pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
609 type Runtime: Runtime<T>;
611
612 type WindowBuilder: WindowBuilder;
614
615 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
617
618 fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
620
621 fn scale_factor(&self) -> Result<f64>;
625
626 fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
628
629 fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
631
632 fn inner_size(&self) -> Result<PhysicalSize<u32>>;
636
637 fn outer_size(&self) -> Result<PhysicalSize<u32>>;
641
642 fn is_fullscreen(&self) -> Result<bool>;
644
645 fn is_minimized(&self) -> Result<bool>;
647
648 fn is_maximized(&self) -> Result<bool>;
650
651 fn is_focused(&self) -> Result<bool>;
653
654 fn is_decorated(&self) -> Result<bool>;
656
657 fn is_resizable(&self) -> Result<bool>;
659
660 fn is_maximizable(&self) -> Result<bool>;
666
667 fn is_minimizable(&self) -> Result<bool>;
673
674 fn is_closable(&self) -> Result<bool>;
680
681 fn is_visible(&self) -> Result<bool>;
683
684 fn is_enabled(&self) -> Result<bool>;
686
687 fn is_always_on_top(&self) -> Result<bool>;
693
694 fn title(&self) -> Result<String>;
696
697 fn current_monitor(&self) -> Result<Option<Monitor>>;
701
702 fn primary_monitor(&self) -> Result<Option<Monitor>>;
706
707 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
709
710 fn available_monitors(&self) -> Result<Vec<Monitor>>;
712
713 #[cfg(any(
715 target_os = "linux",
716 target_os = "dragonfly",
717 target_os = "freebsd",
718 target_os = "netbsd",
719 target_os = "openbsd"
720 ))]
721 fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;
722
723 #[cfg(any(
725 target_os = "linux",
726 target_os = "dragonfly",
727 target_os = "freebsd",
728 target_os = "netbsd",
729 target_os = "openbsd"
730 ))]
731 fn default_vbox(&self) -> Result<gtk::Box>;
732
733 fn window_handle(
735 &self,
736 ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
737
738 fn theme(&self) -> Result<Theme>;
740
741 fn center(&self) -> Result<()>;
745
746 fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
750
751 fn create_window<F: Fn(RawWindow) + Send + 'static>(
753 &mut self,
754 pending: PendingWindow<T, Self::Runtime>,
755 after_window_creation: Option<F>,
756 ) -> Result<DetachedWindow<T, Self::Runtime>>;
757
758 fn create_webview(
760 &mut self,
761 pending: PendingWebview<T, Self::Runtime>,
762 ) -> Result<DetachedWebview<T, Self::Runtime>>;
763
764 fn set_resizable(&self, resizable: bool) -> Result<()>;
766
767 fn set_enabled(&self, enabled: bool) -> Result<()>;
773
774 fn set_maximizable(&self, maximizable: bool) -> Result<()>;
781
782 fn set_minimizable(&self, minimizable: bool) -> Result<()>;
788
789 fn set_closable(&self, closable: bool) -> Result<()>;
797
798 fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
800
801 fn maximize(&self) -> Result<()>;
803
804 fn unmaximize(&self) -> Result<()>;
806
807 fn minimize(&self) -> Result<()>;
809
810 fn unminimize(&self) -> Result<()>;
812
813 fn show(&self) -> Result<()>;
815
816 fn hide(&self) -> Result<()>;
818
819 fn close(&self) -> Result<()>;
821
822 fn destroy(&self) -> Result<()>;
824
825 fn set_decorations(&self, decorations: bool) -> Result<()>;
827
828 fn set_shadow(&self, enable: bool) -> Result<()>;
830
831 fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
833
834 fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
836
837 fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
839
840 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
842
843 fn set_content_protected(&self, protected: bool) -> Result<()>;
845
846 fn set_size(&self, size: Size) -> Result<()>;
848
849 fn set_min_size(&self, size: Option<Size>) -> Result<()>;
851
852 fn set_max_size(&self, size: Option<Size>) -> Result<()>;
854
855 fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
857
858 fn set_position(&self, position: Position) -> Result<()>;
860
861 fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
863
864 #[cfg(target_os = "macos")]
865 fn set_simple_fullscreen(&self, enable: bool) -> Result<()>;
866
867 fn set_focus(&self) -> Result<()>;
869
870 fn set_focusable(&self, focusable: bool) -> Result<()>;
872
873 fn set_icon(&self, icon: Icon) -> Result<()>;
875
876 fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
878
879 fn set_cursor_grab(&self, grab: bool) -> Result<()>;
884
885 fn set_cursor_visible(&self, visible: bool) -> Result<()>;
889
890 fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
892
893 fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
895
896 fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
898
899 fn start_dragging(&self) -> Result<()>;
901
902 fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
904
905 fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
914
915 fn set_badge_label(&self, label: Option<String>) -> Result<()>;
917
918 fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
922
923 fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
930
931 fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
937
938 fn set_traffic_light_position(&self, position: Position) -> Result<()>;
946
947 fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
954}