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 type WindowEventId = u32;
47pub type WebviewEventId = u32;
48
49#[derive(Clone, Copy, Debug, Serialize)]
51pub struct Rect {
52 pub position: dpi::Position,
54 pub size: dpi::Size,
56}
57
58impl Default for Rect {
59 fn default() -> Self {
60 Self {
61 position: Position::Logical((0, 0).into()),
62 size: Size::Logical((0, 0).into()),
63 }
64 }
65}
66
67#[derive(Debug, Clone, Copy, Deserialize)]
69#[serde(rename_all = "camelCase")]
70pub enum ProgressBarStatus {
71 None,
73 Normal,
75 Indeterminate,
77 Paused,
79 Error,
81}
82
83#[derive(Debug, Deserialize)]
85#[serde(rename_all = "camelCase")]
86pub struct ProgressBarState {
87 pub status: Option<ProgressBarStatus>,
89 pub progress: Option<u64>,
91 pub desktop_filename: Option<String>,
93}
94
95#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
97#[serde(tag = "type")]
98pub enum UserAttentionType {
99 Critical,
103 Informational,
107}
108
109#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
110#[serde(tag = "type")]
111pub enum DeviceEventFilter {
112 Always,
114 Unfocused,
116 Never,
118}
119
120impl Default for DeviceEventFilter {
121 fn default() -> Self {
122 Self::Unfocused
123 }
124}
125
126#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
128pub enum ResizeDirection {
129 East,
130 North,
131 NorthEast,
132 NorthWest,
133 South,
134 SouthEast,
135 SouthWest,
136 West,
137}
138
139#[derive(Debug, thiserror::Error)]
140#[non_exhaustive]
141pub enum Error {
142 #[error("failed to create webview: {0}")]
144 CreateWebview(Box<dyn std::error::Error + Send + Sync>),
145 #[error("failed to create window")]
147 CreateWindow,
148 #[error("Window labels must only include alphanumeric characters, `-`, `/`, `:` and `_`.")]
150 InvalidWindowLabel,
151 #[error("failed to send message to the webview")]
153 FailedToSendMessage,
154 #[error("failed to receive message from webview")]
156 FailedToReceiveMessage,
157 #[error("JSON error: {0}")]
159 Json(#[from] serde_json::Error),
160 #[error("invalid icon: {0}")]
162 InvalidIcon(Box<dyn std::error::Error + Send + Sync>),
163 #[error("failed to get monitor")]
165 FailedToGetMonitor,
166 #[error("failed to get cursor position")]
168 FailedToGetCursorPosition,
169 #[error("Invalid header name: {0}")]
170 InvalidHeaderName(#[from] InvalidHeaderName),
171 #[error("Invalid header value: {0}")]
172 InvalidHeaderValue(#[from] InvalidHeaderValue),
173 #[error("Invalid status code: {0}")]
174 InvalidStatusCode(#[from] InvalidStatusCode),
175 #[error("Invalid method: {0}")]
176 InvalidMethod(#[from] InvalidMethod),
177 #[error("Infallible error, something went really wrong: {0}")]
178 Infallible(#[from] std::convert::Infallible),
179 #[error("the event loop has been closed")]
180 EventLoopClosed,
181 #[error("Invalid proxy url")]
182 InvalidProxyUrl,
183 #[error("window not found")]
184 WindowNotFound,
185}
186
187pub type Result<T> = std::result::Result<T, Error>;
189
190#[derive(Debug, Clone)]
192pub struct Icon<'a> {
193 pub rgba: Cow<'a, [u8]>,
195 pub width: u32,
197 pub height: u32,
199}
200
201pub trait UserEvent: Debug + Clone + Send + 'static {}
203
204impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
205
206#[derive(Debug)]
208#[non_exhaustive]
209pub enum RunEvent<T: UserEvent> {
210 Exit,
212 ExitRequested {
214 code: Option<i32>,
216 tx: Sender<ExitRequestedEventAction>,
217 },
218 WindowEvent {
220 label: String,
222 event: WindowEvent,
224 },
225 WebviewEvent {
227 label: String,
229 event: WebviewEvent,
231 },
232 Ready,
234 Resumed,
236 MainEventsCleared,
240 #[cfg(any(target_os = "macos", target_os = "ios"))]
242 Opened { urls: Vec<url::Url> },
243 #[cfg(target_os = "macos")]
245 Reopen {
246 has_visible_windows: bool,
248 },
249 UserEvent(T),
251}
252
253#[derive(Debug)]
255pub enum ExitRequestedEventAction {
256 Prevent,
258}
259
260#[cfg(target_os = "macos")]
262#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
263#[non_exhaustive]
264pub enum ActivationPolicy {
265 Regular,
267 Accessory,
269 Prohibited,
271}
272
273pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
275 type Runtime: Runtime<T, Handle = Self>;
276
277 fn create_proxy(&self) -> <Self::Runtime as Runtime<T>>::EventLoopProxy;
279
280 #[cfg(target_os = "macos")]
282 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
283 fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;
284
285 fn request_exit(&self, code: i32) -> Result<()>;
287
288 fn create_window<F: Fn(RawWindow) + Send + 'static>(
290 &self,
291 pending: PendingWindow<T, Self::Runtime>,
292 before_window_creation: Option<F>,
293 ) -> Result<DetachedWindow<T, Self::Runtime>>;
294
295 fn create_webview(
297 &self,
298 window_id: WindowId,
299 pending: PendingWebview<T, Self::Runtime>,
300 ) -> Result<DetachedWebview<T, Self::Runtime>>;
301
302 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
304
305 fn display_handle(&self) -> std::result::Result<DisplayHandle, raw_window_handle::HandleError>;
306
307 fn primary_monitor(&self) -> Option<Monitor>;
308 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
309 fn available_monitors(&self) -> Vec<Monitor>;
310
311 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
312
313 fn set_theme(&self, theme: Option<Theme>);
314
315 #[cfg(target_os = "macos")]
317 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
318 fn show(&self) -> Result<()>;
319
320 #[cfg(target_os = "macos")]
322 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
323 fn hide(&self) -> Result<()>;
324
325 #[cfg(target_os = "android")]
327 fn find_class<'a>(
328 &self,
329 env: &mut jni::JNIEnv<'a>,
330 activity: &jni::objects::JObject<'_>,
331 name: impl Into<String>,
332 ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
333
334 #[cfg(target_os = "android")]
338 fn run_on_android_context<F>(&self, f: F)
339 where
340 F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
341}
342
343pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
344 fn send_event(&self, event: T) -> Result<()>;
345}
346
347#[derive(Default)]
348pub struct RuntimeInitArgs {
349 #[cfg(any(
350 target_os = "linux",
351 target_os = "dragonfly",
352 target_os = "freebsd",
353 target_os = "netbsd",
354 target_os = "openbsd"
355 ))]
356 pub app_id: Option<String>,
357 #[cfg(windows)]
358 pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
359}
360
361pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
363 type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
365 type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
367 type Handle: RuntimeHandle<T, Runtime = Self>;
369 type EventLoopProxy: EventLoopProxy<T>;
371
372 fn new(args: RuntimeInitArgs) -> Result<Self>;
374
375 #[cfg(any(windows, target_os = "linux"))]
377 #[cfg_attr(docsrs, doc(cfg(any(windows, target_os = "linux"))))]
378 fn new_any_thread(args: RuntimeInitArgs) -> Result<Self>;
379
380 fn create_proxy(&self) -> Self::EventLoopProxy;
382
383 fn handle(&self) -> Self::Handle;
385
386 fn create_window<F: Fn(RawWindow) + Send + 'static>(
388 &self,
389 pending: PendingWindow<T, Self>,
390 after_window_creation: Option<F>,
391 ) -> Result<DetachedWindow<T, Self>>;
392
393 fn create_webview(
395 &self,
396 window_id: WindowId,
397 pending: PendingWebview<T, Self>,
398 ) -> Result<DetachedWebview<T, Self>>;
399
400 fn primary_monitor(&self) -> Option<Monitor>;
401 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
402 fn available_monitors(&self) -> Vec<Monitor>;
403
404 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
405
406 fn set_theme(&self, theme: Option<Theme>);
407
408 #[cfg(target_os = "macos")]
410 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
411 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
412
413 #[cfg(target_os = "macos")]
415 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
416 fn show(&self);
417
418 #[cfg(target_os = "macos")]
420 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
421 fn hide(&self);
422
423 fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
435
436 #[cfg(desktop)]
438 fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
439
440 fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
442}
443
444pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
446 type Runtime: Runtime<T>;
448
449 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
451
452 fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
454
455 fn with_webview<F: FnOnce(Box<dyn std::any::Any>) + Send + 'static>(&self, f: F) -> Result<()>;
457
458 #[cfg(any(debug_assertions, feature = "devtools"))]
460 fn open_devtools(&self);
461
462 #[cfg(any(debug_assertions, feature = "devtools"))]
464 fn close_devtools(&self);
465
466 #[cfg(any(debug_assertions, feature = "devtools"))]
468 fn is_devtools_open(&self) -> Result<bool>;
469
470 fn url(&self) -> Result<String>;
474
475 fn bounds(&self) -> Result<Rect>;
477
478 fn position(&self) -> Result<PhysicalPosition<i32>>;
480
481 fn size(&self) -> Result<PhysicalSize<u32>>;
483
484 fn navigate(&self, url: Url) -> Result<()>;
488
489 fn print(&self) -> Result<()>;
491
492 fn close(&self) -> Result<()>;
494
495 fn set_bounds(&self, bounds: Rect) -> Result<()>;
497
498 fn set_size(&self, size: Size) -> Result<()>;
500
501 fn set_position(&self, position: Position) -> Result<()>;
503
504 fn set_focus(&self) -> Result<()>;
506
507 fn hide(&self) -> Result<()>;
509
510 fn show(&self) -> Result<()>;
512
513 fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
515
516 fn reparent(&self, window_id: WindowId) -> Result<()>;
518
519 fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
521
522 fn set_zoom(&self, scale_factor: f64) -> Result<()>;
524
525 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
527
528 fn clear_all_browsing_data(&self) -> Result<()>;
530}
531
532pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
534 type Runtime: Runtime<T>;
536
537 type WindowBuilder: WindowBuilder;
539
540 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
542
543 fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
545
546 fn scale_factor(&self) -> Result<f64>;
550
551 fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
553
554 fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
556
557 fn inner_size(&self) -> Result<PhysicalSize<u32>>;
561
562 fn outer_size(&self) -> Result<PhysicalSize<u32>>;
566
567 fn is_fullscreen(&self) -> Result<bool>;
569
570 fn is_minimized(&self) -> Result<bool>;
572
573 fn is_maximized(&self) -> Result<bool>;
575
576 fn is_focused(&self) -> Result<bool>;
578
579 fn is_decorated(&self) -> Result<bool>;
581
582 fn is_resizable(&self) -> Result<bool>;
584
585 fn is_maximizable(&self) -> Result<bool>;
591
592 fn is_minimizable(&self) -> Result<bool>;
598
599 fn is_closable(&self) -> Result<bool>;
605
606 fn is_visible(&self) -> Result<bool>;
608
609 fn is_enabled(&self) -> Result<bool>;
611
612 fn title(&self) -> Result<String>;
614
615 fn current_monitor(&self) -> Result<Option<Monitor>>;
619
620 fn primary_monitor(&self) -> Result<Option<Monitor>>;
624
625 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
627
628 fn available_monitors(&self) -> Result<Vec<Monitor>>;
630
631 #[cfg(any(
633 target_os = "linux",
634 target_os = "dragonfly",
635 target_os = "freebsd",
636 target_os = "netbsd",
637 target_os = "openbsd"
638 ))]
639 fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;
640
641 #[cfg(any(
643 target_os = "linux",
644 target_os = "dragonfly",
645 target_os = "freebsd",
646 target_os = "netbsd",
647 target_os = "openbsd"
648 ))]
649 fn default_vbox(&self) -> Result<gtk::Box>;
650
651 fn window_handle(
653 &self,
654 ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
655
656 fn theme(&self) -> Result<Theme>;
658
659 fn center(&self) -> Result<()>;
663
664 fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
668
669 fn create_window<F: Fn(RawWindow) + Send + 'static>(
671 &mut self,
672 pending: PendingWindow<T, Self::Runtime>,
673 after_window_creation: Option<F>,
674 ) -> Result<DetachedWindow<T, Self::Runtime>>;
675
676 fn create_webview(
678 &mut self,
679 pending: PendingWebview<T, Self::Runtime>,
680 ) -> Result<DetachedWebview<T, Self::Runtime>>;
681
682 fn set_resizable(&self, resizable: bool) -> Result<()>;
684
685 fn set_enabled(&self, enabled: bool) -> Result<()>;
691
692 fn set_maximizable(&self, maximizable: bool) -> Result<()>;
699
700 fn set_minimizable(&self, minimizable: bool) -> Result<()>;
706
707 fn set_closable(&self, closable: bool) -> Result<()>;
715
716 fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
718
719 fn maximize(&self) -> Result<()>;
721
722 fn unmaximize(&self) -> Result<()>;
724
725 fn minimize(&self) -> Result<()>;
727
728 fn unminimize(&self) -> Result<()>;
730
731 fn show(&self) -> Result<()>;
733
734 fn hide(&self) -> Result<()>;
736
737 fn close(&self) -> Result<()>;
739
740 fn destroy(&self) -> Result<()>;
742
743 fn set_decorations(&self, decorations: bool) -> Result<()>;
745
746 fn set_shadow(&self, enable: bool) -> Result<()>;
748
749 fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
751
752 fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
754
755 fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
757
758 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
760
761 fn set_content_protected(&self, protected: bool) -> Result<()>;
763
764 fn set_size(&self, size: Size) -> Result<()>;
766
767 fn set_min_size(&self, size: Option<Size>) -> Result<()>;
769
770 fn set_max_size(&self, size: Option<Size>) -> Result<()>;
772
773 fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
775
776 fn set_position(&self, position: Position) -> Result<()>;
778
779 fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
781
782 fn set_focus(&self) -> Result<()>;
784
785 fn set_icon(&self, icon: Icon) -> Result<()>;
787
788 fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
790
791 fn set_cursor_grab(&self, grab: bool) -> Result<()>;
796
797 fn set_cursor_visible(&self, visible: bool) -> Result<()>;
801
802 fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
804
805 fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
807
808 fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
810
811 fn start_dragging(&self) -> Result<()>;
813
814 fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
816
817 fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
826
827 fn set_badge_label(&self, label: Option<String>) -> Result<()>;
829
830 fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
834
835 fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
842
843 fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
849
850 fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
857}