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 fn request_exit(&self, code: i32) -> Result<()>;
293
294 fn create_window<F: Fn(RawWindow) + Send + 'static>(
296 &self,
297 pending: PendingWindow<T, Self::Runtime>,
298 before_window_creation: Option<F>,
299 ) -> Result<DetachedWindow<T, Self::Runtime>>;
300
301 fn create_webview(
303 &self,
304 window_id: WindowId,
305 pending: PendingWebview<T, Self::Runtime>,
306 ) -> Result<DetachedWebview<T, Self::Runtime>>;
307
308 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
310
311 fn display_handle(&self) -> std::result::Result<DisplayHandle, raw_window_handle::HandleError>;
312
313 fn primary_monitor(&self) -> Option<Monitor>;
314 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
315 fn available_monitors(&self) -> Vec<Monitor>;
316
317 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
318
319 fn set_theme(&self, theme: Option<Theme>);
320
321 #[cfg(target_os = "macos")]
323 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
324 fn show(&self) -> Result<()>;
325
326 #[cfg(target_os = "macos")]
328 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
329 fn hide(&self) -> Result<()>;
330
331 #[cfg(target_os = "android")]
333 fn find_class<'a>(
334 &self,
335 env: &mut jni::JNIEnv<'a>,
336 activity: &jni::objects::JObject<'_>,
337 name: impl Into<String>,
338 ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
339
340 #[cfg(target_os = "android")]
344 fn run_on_android_context<F>(&self, f: F)
345 where
346 F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
347
348 #[cfg(any(target_os = "macos", target_os = "ios"))]
349 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
350 fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
351 &self,
352 cb: F,
353 ) -> Result<()>;
354
355 #[cfg(any(target_os = "macos", target_os = "ios"))]
356 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
357 fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
358 &self,
359 uuid: [u8; 16],
360 cb: F,
361 ) -> Result<()>;
362}
363
364pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
365 fn send_event(&self, event: T) -> Result<()>;
366}
367
368#[derive(Default)]
369pub struct RuntimeInitArgs {
370 #[cfg(any(
371 target_os = "linux",
372 target_os = "dragonfly",
373 target_os = "freebsd",
374 target_os = "netbsd",
375 target_os = "openbsd"
376 ))]
377 pub app_id: Option<String>,
378 #[cfg(windows)]
379 pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
380}
381
382pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
384 type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
386 type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
388 type Handle: RuntimeHandle<T, Runtime = Self>;
390 type EventLoopProxy: EventLoopProxy<T>;
392
393 fn new(args: RuntimeInitArgs) -> Result<Self>;
395
396 #[cfg(any(windows, target_os = "linux"))]
398 #[cfg_attr(docsrs, doc(cfg(any(windows, target_os = "linux"))))]
399 fn new_any_thread(args: RuntimeInitArgs) -> Result<Self>;
400
401 fn create_proxy(&self) -> Self::EventLoopProxy;
403
404 fn handle(&self) -> Self::Handle;
406
407 fn create_window<F: Fn(RawWindow) + Send + 'static>(
409 &self,
410 pending: PendingWindow<T, Self>,
411 after_window_creation: Option<F>,
412 ) -> Result<DetachedWindow<T, Self>>;
413
414 fn create_webview(
416 &self,
417 window_id: WindowId,
418 pending: PendingWebview<T, Self>,
419 ) -> Result<DetachedWebview<T, Self>>;
420
421 fn primary_monitor(&self) -> Option<Monitor>;
422 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
423 fn available_monitors(&self) -> Vec<Monitor>;
424
425 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
426
427 fn set_theme(&self, theme: Option<Theme>);
428
429 #[cfg(target_os = "macos")]
431 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
432 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
433
434 #[cfg(target_os = "macos")]
436 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
437 fn show(&self);
438
439 #[cfg(target_os = "macos")]
441 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
442 fn hide(&self);
443
444 fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
456
457 #[cfg(desktop)]
459 fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
460
461 fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32;
463
464 fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
466}
467
468pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
470 type Runtime: Runtime<T>;
472
473 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
475
476 fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
478
479 fn with_webview<F: FnOnce(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()>;
481
482 #[cfg(any(debug_assertions, feature = "devtools"))]
484 fn open_devtools(&self);
485
486 #[cfg(any(debug_assertions, feature = "devtools"))]
488 fn close_devtools(&self);
489
490 #[cfg(any(debug_assertions, feature = "devtools"))]
492 fn is_devtools_open(&self) -> Result<bool>;
493
494 fn url(&self) -> Result<String>;
498
499 fn bounds(&self) -> Result<Rect>;
501
502 fn position(&self) -> Result<PhysicalPosition<i32>>;
504
505 fn size(&self) -> Result<PhysicalSize<u32>>;
507
508 fn navigate(&self, url: Url) -> Result<()>;
512
513 fn reload(&self) -> Result<()>;
515
516 fn print(&self) -> Result<()>;
518
519 fn close(&self) -> Result<()>;
521
522 fn set_bounds(&self, bounds: Rect) -> Result<()>;
524
525 fn set_size(&self, size: Size) -> Result<()>;
527
528 fn set_position(&self, position: Position) -> Result<()>;
530
531 fn set_focus(&self) -> Result<()>;
533
534 fn hide(&self) -> Result<()>;
536
537 fn show(&self) -> Result<()>;
539
540 fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
542
543 fn reparent(&self, window_id: WindowId) -> Result<()>;
545
546 fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
553
554 fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
561
562 fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
564
565 fn set_zoom(&self, scale_factor: f64) -> Result<()>;
567
568 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
570
571 fn clear_all_browsing_data(&self) -> Result<()>;
573}
574
575pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
577 type Runtime: Runtime<T>;
579
580 type WindowBuilder: WindowBuilder;
582
583 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
585
586 fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
588
589 fn scale_factor(&self) -> Result<f64>;
593
594 fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
596
597 fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
599
600 fn inner_size(&self) -> Result<PhysicalSize<u32>>;
604
605 fn outer_size(&self) -> Result<PhysicalSize<u32>>;
609
610 fn is_fullscreen(&self) -> Result<bool>;
612
613 fn is_minimized(&self) -> Result<bool>;
615
616 fn is_maximized(&self) -> Result<bool>;
618
619 fn is_focused(&self) -> Result<bool>;
621
622 fn is_decorated(&self) -> Result<bool>;
624
625 fn is_resizable(&self) -> Result<bool>;
627
628 fn is_maximizable(&self) -> Result<bool>;
634
635 fn is_minimizable(&self) -> Result<bool>;
641
642 fn is_closable(&self) -> Result<bool>;
648
649 fn is_visible(&self) -> Result<bool>;
651
652 fn is_enabled(&self) -> Result<bool>;
654
655 fn is_always_on_top(&self) -> Result<bool>;
661
662 fn title(&self) -> Result<String>;
664
665 fn current_monitor(&self) -> Result<Option<Monitor>>;
669
670 fn primary_monitor(&self) -> Result<Option<Monitor>>;
674
675 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
677
678 fn available_monitors(&self) -> Result<Vec<Monitor>>;
680
681 #[cfg(any(
683 target_os = "linux",
684 target_os = "dragonfly",
685 target_os = "freebsd",
686 target_os = "netbsd",
687 target_os = "openbsd"
688 ))]
689 fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;
690
691 #[cfg(any(
693 target_os = "linux",
694 target_os = "dragonfly",
695 target_os = "freebsd",
696 target_os = "netbsd",
697 target_os = "openbsd"
698 ))]
699 fn default_vbox(&self) -> Result<gtk::Box>;
700
701 fn window_handle(
703 &self,
704 ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
705
706 fn theme(&self) -> Result<Theme>;
708
709 fn center(&self) -> Result<()>;
713
714 fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
718
719 fn create_window<F: Fn(RawWindow) + Send + 'static>(
721 &mut self,
722 pending: PendingWindow<T, Self::Runtime>,
723 after_window_creation: Option<F>,
724 ) -> Result<DetachedWindow<T, Self::Runtime>>;
725
726 fn create_webview(
728 &mut self,
729 pending: PendingWebview<T, Self::Runtime>,
730 ) -> Result<DetachedWebview<T, Self::Runtime>>;
731
732 fn set_resizable(&self, resizable: bool) -> Result<()>;
734
735 fn set_enabled(&self, enabled: bool) -> Result<()>;
741
742 fn set_maximizable(&self, maximizable: bool) -> Result<()>;
749
750 fn set_minimizable(&self, minimizable: bool) -> Result<()>;
756
757 fn set_closable(&self, closable: bool) -> Result<()>;
765
766 fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
768
769 fn maximize(&self) -> Result<()>;
771
772 fn unmaximize(&self) -> Result<()>;
774
775 fn minimize(&self) -> Result<()>;
777
778 fn unminimize(&self) -> Result<()>;
780
781 fn show(&self) -> Result<()>;
783
784 fn hide(&self) -> Result<()>;
786
787 fn close(&self) -> Result<()>;
789
790 fn destroy(&self) -> Result<()>;
792
793 fn set_decorations(&self, decorations: bool) -> Result<()>;
795
796 fn set_shadow(&self, enable: bool) -> Result<()>;
798
799 fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
801
802 fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
804
805 fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
807
808 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
810
811 fn set_content_protected(&self, protected: bool) -> Result<()>;
813
814 fn set_size(&self, size: Size) -> Result<()>;
816
817 fn set_min_size(&self, size: Option<Size>) -> Result<()>;
819
820 fn set_max_size(&self, size: Option<Size>) -> Result<()>;
822
823 fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
825
826 fn set_position(&self, position: Position) -> Result<()>;
828
829 fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
831
832 fn set_focus(&self) -> Result<()>;
834
835 fn set_icon(&self, icon: Icon) -> Result<()>;
837
838 fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
840
841 fn set_cursor_grab(&self, grab: bool) -> Result<()>;
846
847 fn set_cursor_visible(&self, visible: bool) -> Result<()>;
851
852 fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
854
855 fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
857
858 fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
860
861 fn start_dragging(&self) -> Result<()>;
863
864 fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
866
867 fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
876
877 fn set_badge_label(&self, label: Option<String>) -> Result<()>;
879
880 fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
884
885 fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
892
893 fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
899
900 fn set_traffic_light_position(&self, position: Position) -> Result<()>;
908
909 fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
916}