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, Serialize};
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 monitor;
26pub mod webview;
27pub mod window;
28
29use dpi::{PhysicalPosition, PhysicalSize, Position, Size};
30use monitor::Monitor;
31use window::{
32 CursorIcon, DetachedWindow, PendingWindow, RawWindow, WebviewEvent, WindowEvent,
33 WindowSizeConstraints,
34};
35use window::{WindowBuilder, WindowId};
36
37use http::{
38 header::{InvalidHeaderName, InvalidHeaderValue},
39 method::InvalidMethod,
40 status::InvalidStatusCode,
41};
42
43pub use dpi;
45
46pub use cookie::Cookie;
48
49pub type WindowEventId = u32;
50pub type WebviewEventId = u32;
51
52#[derive(Clone, Copy, Debug, Serialize)]
54pub struct Rect {
55 pub position: dpi::Position,
57 pub size: dpi::Size,
59}
60
61impl Default for Rect {
62 fn default() -> Self {
63 Self {
64 position: Position::Logical((0, 0).into()),
65 size: Size::Logical((0, 0).into()),
66 }
67 }
68}
69
70#[derive(Debug, Clone, Copy, Deserialize)]
72#[serde(rename_all = "camelCase")]
73pub enum ProgressBarStatus {
74 None,
76 Normal,
78 Indeterminate,
80 Paused,
82 Error,
84}
85
86#[derive(Debug, Deserialize)]
88#[serde(rename_all = "camelCase")]
89pub struct ProgressBarState {
90 pub status: Option<ProgressBarStatus>,
92 pub progress: Option<u64>,
94 pub desktop_filename: Option<String>,
96}
97
98#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
100#[serde(tag = "type")]
101pub enum UserAttentionType {
102 Critical,
106 Informational,
110}
111
112#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
113#[serde(tag = "type")]
114pub enum DeviceEventFilter {
115 Always,
117 Unfocused,
119 Never,
121}
122
123impl Default for DeviceEventFilter {
124 fn default() -> Self {
125 Self::Unfocused
126 }
127}
128
129#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
131pub enum ResizeDirection {
132 East,
133 North,
134 NorthEast,
135 NorthWest,
136 South,
137 SouthEast,
138 SouthWest,
139 West,
140}
141
142#[derive(Debug, thiserror::Error)]
143#[non_exhaustive]
144pub enum Error {
145 #[error("failed to create webview: {0}")]
147 CreateWebview(Box<dyn std::error::Error + Send + Sync>),
148 #[error("failed to create window")]
150 CreateWindow,
151 #[error("Window labels must only include alphanumeric characters, `-`, `/`, `:` and `_`.")]
153 InvalidWindowLabel,
154 #[error("failed to send message to the webview")]
156 FailedToSendMessage,
157 #[error("failed to receive message from webview")]
159 FailedToReceiveMessage,
160 #[error("JSON error: {0}")]
162 Json(#[from] serde_json::Error),
163 #[error("invalid icon: {0}")]
165 InvalidIcon(Box<dyn std::error::Error + Send + Sync>),
166 #[error("failed to get monitor")]
168 FailedToGetMonitor,
169 #[error("failed to get cursor position")]
171 FailedToGetCursorPosition,
172 #[error("Invalid header name: {0}")]
173 InvalidHeaderName(#[from] InvalidHeaderName),
174 #[error("Invalid header value: {0}")]
175 InvalidHeaderValue(#[from] InvalidHeaderValue),
176 #[error("Invalid status code: {0}")]
177 InvalidStatusCode(#[from] InvalidStatusCode),
178 #[error("Invalid method: {0}")]
179 InvalidMethod(#[from] InvalidMethod),
180 #[error("Infallible error, something went really wrong: {0}")]
181 Infallible(#[from] std::convert::Infallible),
182 #[error("the event loop has been closed")]
183 EventLoopClosed,
184 #[error("Invalid proxy url")]
185 InvalidProxyUrl,
186 #[error("window not found")]
187 WindowNotFound,
188 #[cfg(any(target_os = "macos", target_os = "ios"))]
189 #[error("failed to remove data store")]
190 FailedToRemoveDataStore,
191}
192
193pub type Result<T> = std::result::Result<T, Error>;
195
196#[derive(Debug, Clone)]
198pub struct Icon<'a> {
199 pub rgba: Cow<'a, [u8]>,
201 pub width: u32,
203 pub height: u32,
205}
206
207pub trait UserEvent: Debug + Clone + Send + 'static {}
209
210impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
211
212#[derive(Debug)]
214#[non_exhaustive]
215pub enum RunEvent<T: UserEvent> {
216 Exit,
218 ExitRequested {
220 code: Option<i32>,
222 tx: Sender<ExitRequestedEventAction>,
223 },
224 WindowEvent {
226 label: String,
228 event: WindowEvent,
230 },
231 WebviewEvent {
233 label: String,
235 event: WebviewEvent,
237 },
238 Ready,
240 Resumed,
242 MainEventsCleared,
246 #[cfg(any(target_os = "macos", target_os = "ios"))]
248 Opened { urls: Vec<url::Url> },
249 #[cfg(target_os = "macos")]
251 Reopen {
252 has_visible_windows: bool,
254 },
255 UserEvent(T),
257}
258
259#[derive(Debug)]
261pub enum ExitRequestedEventAction {
262 Prevent,
264}
265
266#[cfg(target_os = "macos")]
268#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
269#[non_exhaustive]
270pub enum ActivationPolicy {
271 Regular,
273 Accessory,
275 Prohibited,
277}
278
279pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
281 type Runtime: Runtime<T, Handle = Self>;
282
283 fn create_proxy(&self) -> <Self::Runtime as Runtime<T>>::EventLoopProxy;
285
286 #[cfg(target_os = "macos")]
288 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
289 fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;
290
291 #[cfg(target_os = "macos")]
294 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
295 fn set_dock_visibility(&self, visible: bool) -> Result<()>;
296
297 fn request_exit(&self, code: i32) -> Result<()>;
299
300 fn create_window<F: Fn(RawWindow) + Send + 'static>(
302 &self,
303 pending: PendingWindow<T, Self::Runtime>,
304 after_window_creation: Option<F>,
305 ) -> Result<DetachedWindow<T, Self::Runtime>>;
306
307 fn create_webview(
309 &self,
310 window_id: WindowId,
311 pending: PendingWebview<T, Self::Runtime>,
312 ) -> Result<DetachedWebview<T, Self::Runtime>>;
313
314 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
316
317 fn display_handle(&self) -> std::result::Result<DisplayHandle, raw_window_handle::HandleError>;
318
319 fn primary_monitor(&self) -> Option<Monitor>;
320 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
321 fn available_monitors(&self) -> Vec<Monitor>;
322
323 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
324
325 fn set_theme(&self, theme: Option<Theme>);
326
327 #[cfg(target_os = "macos")]
329 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
330 fn show(&self) -> Result<()>;
331
332 #[cfg(target_os = "macos")]
334 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
335 fn hide(&self) -> Result<()>;
336
337 #[cfg(target_os = "android")]
339 fn find_class<'a>(
340 &self,
341 env: &mut jni::JNIEnv<'a>,
342 activity: &jni::objects::JObject<'_>,
343 name: impl Into<String>,
344 ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
345
346 #[cfg(target_os = "android")]
350 fn run_on_android_context<F>(&self, f: F)
351 where
352 F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
353
354 #[cfg(any(target_os = "macos", target_os = "ios"))]
355 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
356 fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
357 &self,
358 cb: F,
359 ) -> Result<()>;
360
361 #[cfg(any(target_os = "macos", target_os = "ios"))]
362 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
363 fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
364 &self,
365 uuid: [u8; 16],
366 cb: F,
367 ) -> Result<()>;
368}
369
370pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
371 fn send_event(&self, event: T) -> Result<()>;
372}
373
374#[derive(Default)]
375pub struct RuntimeInitArgs {
376 #[cfg(any(
377 target_os = "linux",
378 target_os = "dragonfly",
379 target_os = "freebsd",
380 target_os = "netbsd",
381 target_os = "openbsd"
382 ))]
383 pub app_id: Option<String>,
384 #[cfg(windows)]
385 pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
386}
387
388pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
390 type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
392 type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
394 type Handle: RuntimeHandle<T, Runtime = Self>;
396 type EventLoopProxy: EventLoopProxy<T>;
398
399 fn new(args: RuntimeInitArgs) -> Result<Self>;
401
402 #[cfg(any(windows, target_os = "linux"))]
404 #[cfg_attr(docsrs, doc(cfg(any(windows, target_os = "linux"))))]
405 fn new_any_thread(args: RuntimeInitArgs) -> Result<Self>;
406
407 fn create_proxy(&self) -> Self::EventLoopProxy;
409
410 fn handle(&self) -> Self::Handle;
412
413 fn create_window<F: Fn(RawWindow) + Send + 'static>(
415 &self,
416 pending: PendingWindow<T, Self>,
417 after_window_creation: Option<F>,
418 ) -> Result<DetachedWindow<T, Self>>;
419
420 fn create_webview(
422 &self,
423 window_id: WindowId,
424 pending: PendingWebview<T, Self>,
425 ) -> Result<DetachedWebview<T, Self>>;
426
427 fn primary_monitor(&self) -> Option<Monitor>;
428 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
429 fn available_monitors(&self) -> Vec<Monitor>;
430
431 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
432
433 fn set_theme(&self, theme: Option<Theme>);
434
435 #[cfg(target_os = "macos")]
437 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
438 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
439
440 #[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}