tauri_runtime/lib.rs
1// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
2// SPDX-License-Identifier: Apache-2.0
3// SPDX-License-Identifier: MIT
4
5//! Internal runtime between Tauri and the underlying webview runtime.
6//!
7//! None of the exposed API of this crate is stable, and it may break semver
8//! compatibility in the future. The major version only signifies the intended Tauri version.
9
10#![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::Theme;
20use tauri_utils::config::Color;
21use url::Url;
22use webview::{DetachedWebview, PendingWebview};
23
24/// UI scaling utilities.
25pub mod dpi;
26pub mod dynamic;
27#[cfg(any(
28 target_os = "linux",
29 target_os = "dragonfly",
30 target_os = "freebsd",
31 target_os = "netbsd",
32 target_os = "openbsd"
33))]
34pub mod gtk;
35/// Types useful for interacting with a user's monitors.
36pub mod monitor;
37pub mod webview;
38mod webview_permissions;
39pub mod window;
40
41use dpi::{PhysicalPosition, PhysicalSize, Position, Rect, Size};
42use monitor::Monitor;
43use window::{
44 CursorIcon, DetachedWindow, PendingWindow, RawWindow, WebviewEvent, WindowEvent,
45 WindowSizeConstraints,
46};
47use window::{WindowBuilder, WindowId};
48
49use http::{
50 header::{InvalidHeaderName, InvalidHeaderValue},
51 method::InvalidMethod,
52 status::InvalidStatusCode,
53};
54
55/// Cookie extraction
56pub use cookie::Cookie;
57
58pub type WindowEventId = u32;
59pub type WebviewEventId = u32;
60
61/// Progress bar status.
62#[derive(Debug, Clone, Copy, Deserialize)]
63#[serde(rename_all = "camelCase")]
64pub enum ProgressBarStatus {
65 /// Hide progress bar.
66 None,
67 /// Normal state.
68 Normal,
69 /// Indeterminate state. **Treated as Normal on Linux and macOS**
70 Indeterminate,
71 /// Paused state. **Treated as Normal on Linux**
72 Paused,
73 /// Error state. **Treated as Normal on Linux**
74 Error,
75}
76
77/// Progress Bar State
78#[derive(Debug, Deserialize)]
79#[serde(rename_all = "camelCase")]
80pub struct ProgressBarState {
81 /// The progress bar status.
82 pub status: Option<ProgressBarStatus>,
83 /// The progress bar progress. This can be a value ranging from `0` to `100`
84 pub progress: Option<u64>,
85 /// The `.desktop` filename with the Unity desktop window manager, for example `myapp.desktop` **Linux Only**
86 pub desktop_filename: Option<String>,
87}
88
89/// Type of user attention requested on a window.
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
91#[serde(tag = "type")]
92pub enum UserAttentionType {
93 /// ## Platform-specific
94 /// - **macOS:** Bounces the dock icon until the application is in focus.
95 /// - **Windows:** Flashes both the window and the taskbar button until the application is in focus.
96 Critical,
97 /// ## Platform-specific
98 /// - **macOS:** Bounces the dock icon once.
99 /// - **Windows:** Flashes the taskbar button until the application is in focus.
100 Informational,
101}
102
103#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
104#[serde(tag = "type")]
105pub enum DeviceEventFilter {
106 /// Always filter out device events.
107 Always,
108 /// Filter out device events while the window is not focused.
109 #[default]
110 Unfocused,
111 /// Report all device events regardless of window focus.
112 Never,
113}
114
115/// Defines the orientation that a window resize will be performed.
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
117pub enum ResizeDirection {
118 East,
119 North,
120 NorthEast,
121 NorthWest,
122 South,
123 SouthEast,
124 SouthWest,
125 West,
126}
127
128#[derive(Debug, thiserror::Error)]
129#[non_exhaustive]
130pub enum Error {
131 /// Failed to create webview.
132 #[error("failed to create webview: {0}")]
133 CreateWebview(Box<dyn std::error::Error + Send + Sync>),
134 /// Failed to create window.
135 #[error("failed to create window: {0}")]
136 CreateWindow(Box<dyn std::error::Error + Send + Sync>),
137 /// The given window label is invalid.
138 #[error("Window labels must only include alphanumeric characters, `-`, `/`, `:` and `_`.")]
139 InvalidWindowLabel,
140 /// Failed to send message to webview.
141 #[error("failed to send message to the webview")]
142 FailedToSendMessage,
143 /// Failed to receive message from webview.
144 #[error("failed to receive message from webview")]
145 FailedToReceiveMessage,
146 /// Failed to serialize/deserialize.
147 #[error("JSON error: {0}")]
148 Json(#[from] serde_json::Error),
149 /// Failed to load window icon.
150 #[error("invalid icon: {0}")]
151 InvalidIcon(Box<dyn std::error::Error + Send + Sync>),
152 /// Failed to get monitor on window operation.
153 #[error("failed to get monitor")]
154 FailedToGetMonitor,
155 /// Failed to get cursor position.
156 #[error("failed to get cursor position")]
157 FailedToGetCursorPosition,
158 #[error("Invalid header name: {0}")]
159 InvalidHeaderName(#[from] InvalidHeaderName),
160 #[error("Invalid header value: {0}")]
161 InvalidHeaderValue(#[from] InvalidHeaderValue),
162 #[error("Invalid status code: {0}")]
163 InvalidStatusCode(#[from] InvalidStatusCode),
164 #[error("Invalid method: {0}")]
165 InvalidMethod(#[from] InvalidMethod),
166 #[error("Infallible error, something went really wrong: {0}")]
167 Infallible(#[from] std::convert::Infallible),
168 #[error("the event loop has been closed")]
169 EventLoopClosed,
170 #[error("Invalid proxy url")]
171 InvalidProxyUrl,
172 #[error("window not found")]
173 WindowNotFound,
174 #[cfg(any(target_os = "macos", target_os = "ios"))]
175 #[error("failed to remove data store")]
176 FailedToRemoveDataStore,
177 #[error("Could not find the webview runtime, make sure it is installed")]
178 WebviewRuntimeNotInstalled,
179 /// The type-erased runtime was initialized without selecting a concrete runtime.
180 #[error(
181 "no runtime was configured; select one with e.g. `tauri::Builder::default().runtime(tauri_runtime_wry::Wry::default())`"
182 )]
183 RuntimeNotConfigured,
184 /// A runtime-specific value was given to a different runtime than the one it belongs to.
185 #[error("runtime type mismatch: {0}")]
186 RuntimeTypeMismatch(String),
187 /// Failed to determine the webview version.
188 #[error("failed to get the webview version: {0}")]
189 WebviewVersion(Box<dyn std::error::Error + Send + Sync>),
190}
191
192/// Result type.
193pub type Result<T> = std::result::Result<T, Error>;
194
195/// Window icon.
196#[derive(Debug, Clone)]
197pub struct Icon<'a> {
198 /// RGBA bytes of the icon.
199 pub rgba: Cow<'a, [u8]>,
200 /// Icon width.
201 pub width: u32,
202 /// Icon height.
203 pub height: u32,
204}
205
206impl<'a> Icon<'a> {
207 pub fn into_owned(self) -> Icon<'static> {
208 Icon {
209 rgba: std::borrow::Cow::Owned(self.rgba.into_owned()),
210 width: self.width,
211 height: self.height,
212 }
213 }
214}
215
216/// A type that can be used as an user event.
217pub trait UserEvent: Debug + Clone + Send + 'static {}
218
219impl<T: Debug + Clone + Send + 'static> UserEvent for T {}
220
221/// Event triggered on the event loop run.
222#[derive(Debug)]
223#[non_exhaustive]
224pub enum RunEvent<T: UserEvent> {
225 /// Event loop is exiting.
226 Exit,
227 /// Event loop is about to exit
228 ExitRequested {
229 /// The exit code.
230 code: Option<i32>,
231 tx: Sender<ExitRequestedEventAction>,
232 },
233 /// An event associated with a window.
234 WindowEvent {
235 /// The window label.
236 label: String,
237 /// The detailed event.
238 event: WindowEvent,
239 },
240 /// An event associated with a webview.
241 WebviewEvent {
242 /// The webview label.
243 label: String,
244 /// The detailed event.
245 event: WebviewEvent,
246 },
247 /// Application ready.
248 Ready,
249 /// Sent if the event loop is being resumed.
250 Resumed,
251 /// Emitted when all of the event loop's input events have been processed and redraw processing is about to begin.
252 ///
253 /// This event is useful as a place to put your code that should be run after all state-changing events have been handled and you want to do stuff (updating state, performing calculations, etc) that happens as the "main body" of your event loop.
254 MainEventsCleared,
255 /// Emitted when the user wants to open the specified resource with the app.
256 Opened { urls: Vec<url::Url> },
257 /// Emitted when the NSApplicationDelegate's applicationShouldHandleReopen gets called
258 #[cfg(target_os = "macos")]
259 Reopen {
260 /// Indicates whether the NSApplication object found any visible windows in your application.
261 has_visible_windows: bool,
262 },
263 /// A custom event defined by the user.
264 UserEvent(T),
265 /// Emitted when a scene is requested by the system.
266 ///
267 /// This event is emitted when a scene is requested by the system.
268 /// Scenes created by [`Window::new`] are not emitted with this event.
269 /// It is also not emitted for the main scene.
270 #[cfg(target_os = "ios")]
271 SceneRequested {
272 /// Scene that was requested by the system.
273 scene: objc2::rc::Retained<objc2_ui_kit::UIScene>,
274 /// Options that were used to request the scene.
275 ///
276 /// This lets you determine why the scene was requested.
277 options: objc2::rc::Retained<objc2_ui_kit::UISceneConnectionOptions>,
278 },
279}
280
281/// Action to take when the event loop is about to exit
282#[derive(Debug)]
283pub enum ExitRequestedEventAction {
284 /// Prevent the event loop from exiting
285 Prevent,
286}
287
288/// Application's activation policy. Corresponds to NSApplicationActivationPolicy.
289#[cfg(target_os = "macos")]
290#[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
291#[non_exhaustive]
292pub enum ActivationPolicy {
293 /// Corresponds to NSApplicationActivationPolicyRegular.
294 Regular,
295 /// Corresponds to NSApplicationActivationPolicyAccessory.
296 Accessory,
297 /// Corresponds to NSApplicationActivationPolicyProhibited.
298 Prohibited,
299}
300
301/// A [`Send`] handle to the runtime.
302pub trait RuntimeHandle<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
303 type Runtime: Runtime<T, Handle = Self>;
304
305 /// Creates an `EventLoopProxy` that can be used to dispatch user events to the main event loop.
306 fn create_proxy(&self) -> <Self::Runtime as Runtime<T>>::EventLoopProxy;
307
308 /// Sets the activation policy for the application.
309 #[cfg(target_os = "macos")]
310 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
311 fn set_activation_policy(&self, activation_policy: ActivationPolicy) -> Result<()>;
312
313 /// Sets the dock visibility for the application.
314 #[cfg(target_os = "macos")]
315 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
316 fn set_dock_visibility(&self, visible: bool) -> Result<()>;
317
318 /// Requests an exit of the event loop.
319 fn request_exit(&self, code: i32) -> Result<()>;
320
321 /// Create a new window.
322 fn create_window<F: Fn(RawWindow) + Send + 'static>(
323 &self,
324 pending: PendingWindow<T, Self::Runtime>,
325 after_window_creation: Option<F>,
326 ) -> Result<DetachedWindow<T, Self::Runtime>>;
327
328 /// Create a new webview.
329 fn create_webview(
330 &self,
331 window_id: WindowId,
332 pending: PendingWebview<T, Self::Runtime>,
333 ) -> Result<DetachedWebview<T, Self::Runtime>>;
334
335 /// Run a task on the main thread.
336 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
337
338 /// Get a handle to the display controller of the windowing system.
339 fn display_handle(
340 &self,
341 ) -> std::result::Result<DisplayHandle<'_>, raw_window_handle::HandleError>;
342
343 /// Returns the primary monitor of the system.
344 ///
345 /// Returns None if it can't identify any monitor as a primary one.
346 fn primary_monitor(&self) -> Result<Option<Monitor>>;
347
348 /// Returns the monitor that contains the given point.
349 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
350
351 /// Returns the list of all the monitors available on the system.
352 fn available_monitors(&self) -> Result<Vec<Monitor>>;
353
354 /// Get the cursor position relative to the top-left hand corner of the desktop.
355 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
356
357 /// Sets the app theme.
358 fn set_theme(&self, theme: Option<Theme>);
359
360 /// Shows the application, but does not automatically focus it.
361 #[cfg(target_os = "macos")]
362 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
363 fn show(&self) -> Result<()>;
364
365 /// Hides the application.
366 #[cfg(target_os = "macos")]
367 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
368 fn hide(&self) -> Result<()>;
369
370 /// Change the device event filter mode.
371 ///
372 /// See [Runtime::set_device_event_filter] for details.
373 ///
374 /// ## Platform-specific
375 ///
376 /// See [Runtime::set_device_event_filter] for details.
377 fn set_device_event_filter(&self, filter: DeviceEventFilter);
378
379 /// Returns the URL a custom scheme is served from,
380 /// e.g. `tauri://localhost` or `http://tauri.localhost`.
381 ///
382 /// The format is entirely up to the runtime. Tauri never assumes a particular scheme or host
383 /// layout: every custom protocol URL it builds or compares against goes through this function,
384 /// and the asset path of an incoming custom protocol request is always taken from its URI path.
385 ///
386 /// `scheme` is usually a registered protocol name such as `tauri`, `ipc` or `asset`, but it can
387 /// also be the literal placeholder `{protocol}`, which Tauri uses to build the URL template
388 /// injected into the webview (the frontend expands it in `convertFileSrc`). Implementations must
389 /// therefore interpolate `scheme` verbatim, without validating, escaping or normalizing it.
390 ///
391 /// `https` reflects [`crate::webview::WebviewAttributes::use_https_scheme`]; runtimes that do not
392 /// serve custom protocols over `http(s)` can ignore it.
393 fn custom_scheme_url(&self, scheme: &str, https: bool) -> String;
394
395 /// Returns the version of the underlying webview engine.
396 fn webview_version(&self) -> Result<String>;
397
398 /// Finds an Android class in the project scope.
399 #[cfg(target_os = "android")]
400 fn find_class<'a>(
401 &self,
402 env: &mut jni::JNIEnv<'a>,
403 activity: &jni::objects::JObject<'_>,
404 name: impl Into<String>,
405 ) -> std::result::Result<jni::objects::JClass<'a>, jni::errors::Error>;
406
407 /// Dispatch a closure to run on the Android context.
408 ///
409 /// The closure takes the JNI env, the Android activity instance and the possibly null webview.
410 #[cfg(target_os = "android")]
411 fn run_on_android_context<F>(&self, f: F)
412 where
413 F: FnOnce(&mut jni::JNIEnv, &jni::objects::JObject, &jni::objects::JObject) + Send + 'static;
414
415 #[cfg(any(target_os = "macos", target_os = "ios"))]
416 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
417 fn fetch_data_store_identifiers<F: FnOnce(Vec<[u8; 16]>) + Send + 'static>(
418 &self,
419 cb: F,
420 ) -> Result<()>;
421
422 #[cfg(any(target_os = "macos", target_os = "ios"))]
423 #[cfg_attr(docsrs, doc(cfg(any(target_os = "macos", target_os = "ios"))))]
424 fn remove_data_store<F: FnOnce(Result<()>) + Send + 'static>(
425 &self,
426 uuid: [u8; 16],
427 cb: F,
428 ) -> Result<()>;
429}
430
431pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
432 fn send_event(&self, event: T) -> Result<()>;
433}
434
435#[derive(Default)]
436pub struct RuntimeInitArgs<A> {
437 #[cfg(any(
438 target_os = "linux",
439 target_os = "dragonfly",
440 target_os = "freebsd",
441 target_os = "netbsd",
442 target_os = "openbsd"
443 ))]
444 pub app_id: Option<String>,
445 #[cfg(windows)]
446 pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
447 pub identifier: String,
448 pub custom_schemes: Vec<String>,
449 pub runtime_init_attrs: A,
450}
451
452impl<A> RuntimeInitArgs<A> {
453 /// Replaces the runtime-specific attributes, returning the new arguments and the previous attributes.
454 ///
455 /// Used by the type-erased [`dynamic::DynRuntime`] to move the attributes of the selected runtime
456 /// in and out of the arguments, since the erased layer only carries `RuntimeInitArgs<()>`.
457 pub(crate) fn with_attrs<B>(self, runtime_init_attrs: B) -> (RuntimeInitArgs<B>, A) {
458 let RuntimeInitArgs {
459 #[cfg(any(
460 target_os = "linux",
461 target_os = "dragonfly",
462 target_os = "freebsd",
463 target_os = "netbsd",
464 target_os = "openbsd"
465 ))]
466 app_id,
467 #[cfg(windows)]
468 msg_hook,
469 identifier,
470 custom_schemes,
471 runtime_init_attrs: previous,
472 } = self;
473 (
474 RuntimeInitArgs {
475 #[cfg(any(
476 target_os = "linux",
477 target_os = "dragonfly",
478 target_os = "freebsd",
479 target_os = "netbsd",
480 target_os = "openbsd"
481 ))]
482 app_id,
483 #[cfg(windows)]
484 msg_hook,
485 identifier,
486 custom_schemes,
487 runtime_init_attrs,
488 },
489 previous,
490 )
491 }
492}
493
494/// Runtime-specific initialization attributes.
495///
496/// Every [`Runtime`] defines its own attributes type. That type is also what *selects* the runtime
497/// when the application uses the type-erased [`dynamic::DynRuntime`]: passing the attributes
498/// (e.g. `tauri_runtime_wry::Wry::default()` or `tauri_runtime_cef::Cef::default()`) to
499/// `tauri::Builder::runtime` picks the runtime they belong to.
500///
501/// For that to work, runtime crates also implement `From<Self>` for [`dynamic::DynRuntimeInitAttrs`]
502/// (wrapping the attributes with [`dynamic::DynRuntimeInitAttrs::new`]).
503pub trait RuntimeInitAttrs<T: UserEvent>: Default + Send + Sync + 'static {
504 /// The runtime initialized with these attributes.
505 type Runtime: Runtime<T, RuntimeInitAttrs = Self>;
506
507 /// Applies attributes derived from the application configuration.
508 fn apply_config(&mut self, _config: &tauri_utils::config::Config) -> Result<()> {
509 Ok(())
510 }
511}
512
513/// The webview runtime interface.
514pub trait Runtime<T: UserEvent>: Debug + Sized + 'static {
515 /// The window message dispatcher.
516 type WindowDispatcher: WindowDispatch<T, Runtime = Self>;
517 /// The webview message dispatcher.
518 type WebviewDispatcher: WebviewDispatch<T, Runtime = Self>;
519 /// The runtime handle type.
520 type Handle: RuntimeHandle<T, Runtime = Self>;
521 /// The proxy type.
522 type EventLoopProxy: EventLoopProxy<T>;
523 /// The runtime-specific webview attributes, set on the webview builders through the runtime's extension traits.
524 ///
525 /// The default value is used when the application sets none.
526 type RuntimeWebviewAttributes: Default + Send + Sync + 'static;
527 /// The platform webview handle exposed through [`WebviewDispatch::with_webview`].
528 ///
529 /// This is the runtime-specific type the user interacts with to reach the
530 /// underlying platform webview APIs.
531 type Webview: 'static;
532 /// Runtime-specific initialization attributes. Also used to select this runtime, see [`RuntimeInitAttrs`].
533 type RuntimeInitAttrs: RuntimeInitAttrs<T, Runtime = Self>;
534 /// Data about the window that requested the new window for [`PendingWebview::new_window_handler`].
535 type WindowOpener: Send + Sync + Debug + 'static;
536
537 /// Creates a new webview runtime. Must be used on the main thread.
538 fn new(args: RuntimeInitArgs<Self::RuntimeInitAttrs>) -> Result<Self>;
539
540 /// Creates a new webview runtime on any thread.
541 #[cfg(any(
542 windows,
543 target_os = "linux",
544 target_os = "dragonfly",
545 target_os = "freebsd",
546 target_os = "netbsd",
547 target_os = "openbsd"
548 ))]
549 #[cfg_attr(
550 docsrs,
551 doc(cfg(any(
552 windows,
553 target_os = "linux",
554 target_os = "dragonfly",
555 target_os = "freebsd",
556 target_os = "netbsd",
557 target_os = "openbsd"
558 )))
559 )]
560 fn new_any_thread(args: RuntimeInitArgs<Self::RuntimeInitAttrs>) -> Result<Self>;
561
562 /// Creates an `EventLoopProxy` that can be used to dispatch user events to the main event loop.
563 fn create_proxy(&self) -> Self::EventLoopProxy;
564
565 /// Gets a runtime handle.
566 fn handle(&self) -> Self::Handle;
567
568 /// Create a new window.
569 fn create_window<F: Fn(RawWindow) + Send + 'static>(
570 &self,
571 pending: PendingWindow<T, Self>,
572 after_window_creation: Option<F>,
573 ) -> Result<DetachedWindow<T, Self>>;
574
575 /// Create a new webview.
576 fn create_webview(
577 &self,
578 window_id: WindowId,
579 pending: PendingWebview<T, Self>,
580 ) -> Result<DetachedWebview<T, Self>>;
581
582 /// Returns the primary monitor of the system.
583 ///
584 /// Returns None if it can't identify any monitor as a primary one.
585 fn primary_monitor(&self) -> Option<Monitor>;
586
587 /// Returns the monitor that contains the given point.
588 fn monitor_from_point(&self, x: f64, y: f64) -> Option<Monitor>;
589
590 /// Returns the list of all the monitors available on the system.
591 fn available_monitors(&self) -> Vec<Monitor>;
592
593 /// Get the cursor position relative to the top-left hand corner of the desktop.
594 fn cursor_position(&self) -> Result<PhysicalPosition<f64>>;
595
596 /// Sets the app theme.
597 fn set_theme(&self, theme: Option<Theme>);
598
599 /// Sets the activation policy for the application.
600 #[cfg(target_os = "macos")]
601 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
602 fn set_activation_policy(&mut self, activation_policy: ActivationPolicy);
603
604 /// Sets whether the application activates when launched while another application is already active.
605 ///
606 /// This API must be called before the event loop starts.
607 ///
608 /// If `false`, the app activates only if no other app is currently active.
609 /// If `true`, the app activates regardless.
610 #[cfg(target_os = "macos")]
611 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
612 fn set_activate_ignoring_other_apps(&mut self, ignore: bool);
613
614 /// Sets the dock visibility for the application.
615 #[cfg(target_os = "macos")]
616 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
617 fn set_dock_visibility(&mut self, visible: bool);
618
619 /// Shows the application, but does not automatically focus it.
620 #[cfg(target_os = "macos")]
621 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
622 fn show(&self);
623
624 /// Hides the application.
625 #[cfg(target_os = "macos")]
626 #[cfg_attr(docsrs, doc(cfg(target_os = "macos")))]
627 fn hide(&self);
628
629 /// Change the device event filter mode.
630 ///
631 /// Since the DeviceEvent capture can lead to high CPU usage for unfocused windows, [`tao`]
632 /// will ignore them by default for unfocused windows on Windows. This method allows changing
633 /// the filter to explicitly capture them again.
634 ///
635 /// ## Platform-specific
636 ///
637 /// - ** Linux / macOS / iOS / Android**: Unsupported.
638 ///
639 /// [`tao`]: https://crates.io/crates/tao
640 fn set_device_event_filter(&mut self, filter: DeviceEventFilter);
641
642 /// Runs an iteration of the runtime event loop and returns control flow to the caller.
643 #[cfg(desktop)]
644 fn run_iteration<F: FnMut(RunEvent<T>) + 'static>(&mut self, callback: F);
645
646 /// Equivalent to [`Runtime::run`] but returns the exit code instead of exiting the process.
647 fn run_return<F: FnMut(RunEvent<T>) + 'static>(self, callback: F) -> i32;
648
649 /// Run the webview runtime.
650 fn run<F: FnMut(RunEvent<T>) + 'static>(self, callback: F);
651}
652
653/// Webview dispatcher. A thread-safe handle to the webview APIs.
654pub trait WebviewDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
655 /// The runtime this [`WebviewDispatch`] runs under.
656 type Runtime: Runtime<T>;
657
658 /// Run a task on the main thread.
659 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
660
661 /// Registers a webview event handler.
662 fn on_webview_event<F: Fn(&WebviewEvent) + Send + 'static>(&self, f: F) -> WebviewEventId;
663
664 /// Runs a closure with the platform webview object as argument.
665 fn with_webview<F: FnOnce(<Self::Runtime as Runtime<T>>::Webview) + Send + 'static>(
666 &self,
667 f: F,
668 ) -> Result<()>;
669
670 /// Runs a closure with the iOS handles of the webview (the `WKWebView`, its user content controller and view controller).
671 ///
672 /// The closure is executed on the main thread.
673 #[cfg(target_os = "ios")]
674 fn with_ios_webview<F: FnOnce(webview::IosWebviewHandle) + Send + 'static>(
675 &self,
676 f: F,
677 ) -> Result<()>;
678
679 /// Open the web inspector which is usually called devtools.
680 ///
681 /// Runtimes compiled without devtools support (release builds without their `devtools` feature) do nothing.
682 fn open_devtools(&self);
683
684 /// Close the web inspector which is usually called devtools.
685 ///
686 /// Runtimes compiled without devtools support (release builds without their `devtools` feature) do nothing.
687 fn close_devtools(&self);
688
689 /// Gets the devtools window's current open state.
690 ///
691 /// Runtimes compiled without devtools support (release builds without their `devtools` feature) return `false`.
692 fn is_devtools_open(&self) -> Result<bool>;
693
694 // GETTERS
695
696 /// Returns the webview's current URL.
697 fn url(&self) -> Result<String>;
698
699 /// Returns the webview's bounds.
700 fn bounds(&self) -> Result<Rect>;
701
702 /// Returns the position of the top-left hand corner of the webviews's client area relative to the top-left hand corner of the window.
703 fn position(&self) -> Result<PhysicalPosition<i32>>;
704
705 /// Returns the physical size of the webviews's client area.
706 fn size(&self) -> Result<PhysicalSize<u32>>;
707
708 // SETTER
709
710 /// Navigate to the given URL.
711 fn navigate(&self, url: Url) -> Result<()>;
712
713 /// Reloads the current page.
714 fn reload(&self) -> Result<()>;
715
716 fn go_back(&self) -> Result<()>;
717
718 fn can_go_back(&self) -> Result<bool>;
719
720 fn go_forward(&self) -> Result<()>;
721
722 fn can_go_forward(&self) -> Result<bool>;
723
724 /// Opens the dialog to prints the contents of the webview.
725 fn print(&self) -> Result<()>;
726
727 /// Closes the webview.
728 fn close(&self) -> Result<()>;
729
730 /// Sets the webview's bounds.
731 fn set_bounds(&self, bounds: Rect) -> Result<()>;
732
733 /// Resizes the webview.
734 fn set_size(&self, size: Size) -> Result<()>;
735
736 /// Updates the webview position.
737 fn set_position(&self, position: Position) -> Result<()>;
738
739 /// Bring the window to front and focus the webview.
740 fn set_focus(&self) -> Result<()>;
741
742 /// Hide the webview
743 fn hide(&self) -> Result<()>;
744
745 /// Show the webview
746 fn show(&self) -> Result<()>;
747
748 /// Executes javascript on the window this [`WindowDispatch`] represents.
749 fn eval_script<S: Into<String>>(&self, script: S) -> Result<()>;
750
751 /// Evaluate JavaScript with callback function on the webview this [`WebviewDispatch`] represents.
752 /// The evaluation result will be serialized into a JSON string and passed to the callback function.
753 ///
754 /// Exception is ignored because of the limitation on Windows. You can catch it yourself and return as string as a workaround.
755 fn eval_script_with_callback<S: Into<String>>(
756 &self,
757 script: S,
758 callback: impl Fn(String) + Send + 'static,
759 ) -> Result<()>;
760
761 /// Moves the webview to the given window.
762 fn reparent(&self, window_id: WindowId) -> Result<()>;
763
764 /// Get cookies for a particular url.
765 ///
766 /// # Stability
767 ///
768 /// See [WebviewDispatch::cookies].
769 fn cookies_for_url(&self, url: Url) -> Result<Vec<Cookie<'static>>>;
770
771 /// Return all cookies in the cookie store.
772 ///
773 /// # Stability
774 ///
775 /// The return value of this function leverages [`cookie::Cookie`] which re-exports the cookie crate.
776 /// This dependency might receive updates in minor Tauri releases.
777 fn cookies(&self) -> Result<Vec<Cookie<'static>>>;
778
779 /// Set a cookie for the webview.
780 ///
781 /// # Stability
782 ///
783 /// See [WebviewDispatch::cookies].
784 fn set_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
785
786 /// Delete a cookie for the webview.
787 ///
788 /// # Stability
789 ///
790 /// See [WebviewDispatch::cookies].
791 fn delete_cookie(&self, cookie: cookie::Cookie<'_>) -> Result<()>;
792
793 /// Sets whether the webview should automatically grow and shrink its size and position when the parent window resizes.
794 fn set_auto_resize(&self, auto_resize: bool) -> Result<()>;
795
796 /// Set the webview zoom level
797 fn set_zoom(&self, scale_factor: f64) -> Result<()>;
798
799 /// Set the webview background.
800 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
801
802 /// Clear all browsing data for this webview.
803 fn clear_all_browsing_data(&self) -> Result<()>;
804}
805
806/// Window dispatcher. A thread-safe handle to the window APIs.
807pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 'static {
808 /// The runtime this [`WindowDispatch`] runs under.
809 type Runtime: Runtime<T>;
810
811 /// The window builder type.
812 type WindowBuilder: WindowBuilder;
813
814 /// Run a task on the main thread.
815 fn run_on_main_thread<F: FnOnce() + Send + 'static>(&self, f: F) -> Result<()>;
816
817 /// Registers a window event handler.
818 fn on_window_event<F: Fn(&WindowEvent) + Send + 'static>(&self, f: F) -> WindowEventId;
819
820 // GETTERS
821
822 /// Returns the scale factor that can be used to map logical pixels to physical pixels, and vice versa.
823 fn scale_factor(&self) -> Result<f64>;
824
825 /// Returns the position of the top-left hand corner of the window's client area relative to the top-left hand corner of the desktop.
826 fn inner_position(&self) -> Result<PhysicalPosition<i32>>;
827
828 /// Returns the position of the top-left hand corner of the window relative to the top-left hand corner of the desktop.
829 fn outer_position(&self) -> Result<PhysicalPosition<i32>>;
830
831 /// Returns the physical size of the window's client area.
832 ///
833 /// The client area is the content of the window, excluding the title bar and borders.
834 fn inner_size(&self) -> Result<PhysicalSize<u32>>;
835
836 /// Returns the physical size of the entire window.
837 ///
838 /// These dimensions include the title bar and borders. If you don't want that (and you usually don't), use inner_size instead.
839 fn outer_size(&self) -> Result<PhysicalSize<u32>>;
840
841 /// Gets the window's current fullscreen state.
842 fn is_fullscreen(&self) -> Result<bool>;
843
844 /// Gets the window's current minimized state.
845 fn is_minimized(&self) -> Result<bool>;
846
847 /// Gets the window's current maximized state.
848 fn is_maximized(&self) -> Result<bool>;
849
850 /// Gets the window's current focus state.
851 fn is_focused(&self) -> Result<bool>;
852
853 /// Gets the window's current decoration state.
854 fn is_decorated(&self) -> Result<bool>;
855
856 /// Gets the window's current resizable state.
857 fn is_resizable(&self) -> Result<bool>;
858
859 /// Gets the window's native maximize button state.
860 ///
861 /// ## Platform-specific
862 ///
863 /// - **Linux / iOS / Android:** Unsupported.
864 fn is_maximizable(&self) -> Result<bool>;
865
866 /// Gets the window's native minimize button state.
867 ///
868 /// ## Platform-specific
869 ///
870 /// - **Linux / iOS / Android:** Unsupported.
871 fn is_minimizable(&self) -> Result<bool>;
872
873 /// Gets the window's native close button state.
874 ///
875 /// ## Platform-specific
876 ///
877 /// - **iOS / Android:** Unsupported.
878 fn is_closable(&self) -> Result<bool>;
879
880 /// Gets the window's current visibility state.
881 fn is_visible(&self) -> Result<bool>;
882
883 /// Whether the window is enabled or disable.
884 fn is_enabled(&self) -> Result<bool>;
885
886 /// Gets the window alwaysOnTop flag state.
887 ///
888 /// ## Platform-specific
889 ///
890 /// - **iOS / Android:** Unsupported.
891 fn is_always_on_top(&self) -> Result<bool>;
892
893 /// Gets the window's current title.
894 fn title(&self) -> Result<String>;
895
896 /// Returns the monitor on which the window currently resides.
897 ///
898 /// Returns None if current monitor can't be detected.
899 fn current_monitor(&self) -> Result<Option<Monitor>>;
900
901 /// Returns the primary monitor of the system.
902 ///
903 /// Returns None if it can't identify any monitor as a primary one.
904 fn primary_monitor(&self) -> Result<Option<Monitor>>;
905
906 /// Returns the monitor that contains the given point.
907 fn monitor_from_point(&self, x: f64, y: f64) -> Result<Option<Monitor>>;
908
909 /// Returns the list of all the monitors available on the system.
910 fn available_monitors(&self) -> Result<Vec<Monitor>>;
911
912 /// Returns the GTK application window pointer (`GtkApplicationWindow*`) that is used by this window.
913 ///
914 /// # Ownership
915 ///
916 /// The pointer is *transfer full*: implementations must hand out a strong reference
917 /// (`g_object_ref`, i.e. glib's `to_glib_full`) and the caller is responsible for releasing it
918 /// (`g_object_unref`, i.e. glib's `from_glib_full`). It is never null on success.
919 ///
920 /// The GTK major version of the object is the one the runtime was built against, so callers must
921 /// wrap it with matching bindings - the `tauri` crate selects them through its `gtk3`/`gtk4`
922 /// features, which the runtime crate enables. Runtimes must report that version with
923 /// [`gtk::declare_version`] so a mismatch can be detected instead of reinterpreting the object.
924 ///
925 /// The object may only be used on the main thread.
926 #[cfg(any(
927 target_os = "linux",
928 target_os = "dragonfly",
929 target_os = "freebsd",
930 target_os = "netbsd",
931 target_os = "openbsd"
932 ))]
933 fn gtk_window(&self) -> Result<*mut std::ffi::c_void>;
934
935 /// Returns the vertical GTK box pointer (`GtkBox*`) that is added by default as the sole child of this window.
936 ///
937 /// # Ownership
938 ///
939 /// Same contract as [`WindowDispatch::gtk_window`]: *transfer full*, never null on success, main
940 /// thread only.
941 #[cfg(any(
942 target_os = "linux",
943 target_os = "dragonfly",
944 target_os = "freebsd",
945 target_os = "netbsd",
946 target_os = "openbsd"
947 ))]
948 fn default_vbox(&self) -> Result<*mut std::ffi::c_void>;
949
950 /// Returns the name of the Android activity associated with this window.
951 #[cfg(target_os = "android")]
952 fn activity_name(&self) -> Result<String>;
953
954 /// Returns the identifier of the UIScene tied to this UIWindow.
955 #[cfg(target_os = "ios")]
956 fn scene_identifier(&self) -> Result<String>;
957
958 /// Raw window handle.
959 fn window_handle(
960 &self,
961 ) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError>;
962
963 /// Returns the current window theme.
964 fn theme(&self) -> Result<Theme>;
965
966 // SETTERS
967
968 /// Centers the window.
969 fn center(&self) -> Result<()>;
970
971 /// Requests user attention to the window.
972 ///
973 /// Providing `None` will unset the request for user attention.
974 fn request_user_attention(&self, request_type: Option<UserAttentionType>) -> Result<()>;
975
976 /// Create a new window.
977 fn create_window<F: Fn(RawWindow) + Send + 'static>(
978 &mut self,
979 pending: PendingWindow<T, Self::Runtime>,
980 after_window_creation: Option<F>,
981 ) -> Result<DetachedWindow<T, Self::Runtime>>;
982
983 /// Create a new webview.
984 fn create_webview(
985 &mut self,
986 pending: PendingWebview<T, Self::Runtime>,
987 ) -> Result<DetachedWebview<T, Self::Runtime>>;
988
989 /// Updates the window resizable flag.
990 fn set_resizable(&self, resizable: bool) -> Result<()>;
991
992 /// Enable or disable the window.
993 ///
994 /// ## Platform-specific
995 ///
996 /// - **Android / iOS**: Unsupported.
997 fn set_enabled(&self, enabled: bool) -> Result<()>;
998
999 /// Updates the window's native maximize button state.
1000 ///
1001 /// ## Platform-specific
1002 ///
1003 /// - **macOS:** Disables the "zoom" button in the window titlebar, which is also used to enter fullscreen mode.
1004 /// - **Linux / iOS / Android:** Unsupported.
1005 fn set_maximizable(&self, maximizable: bool) -> Result<()>;
1006
1007 /// Updates the window's native minimize button state.
1008 ///
1009 /// ## Platform-specific
1010 ///
1011 /// - **Linux / iOS / Android:** Unsupported.
1012 fn set_minimizable(&self, minimizable: bool) -> Result<()>;
1013
1014 /// Updates the window's native close button state.
1015 ///
1016 /// ## Platform-specific
1017 ///
1018 /// - **Linux:** "GTK+ will do its best to convince the window manager not to show a close button.
1019 /// Depending on the system, this function may not have any effect when called on a window that is already visible"
1020 /// - **iOS / Android:** Unsupported.
1021 fn set_closable(&self, closable: bool) -> Result<()>;
1022
1023 /// Updates the window title.
1024 fn set_title<S: Into<String>>(&self, title: S) -> Result<()>;
1025
1026 /// Maximizes the window.
1027 fn maximize(&self) -> Result<()>;
1028
1029 /// Unmaximizes the window.
1030 fn unmaximize(&self) -> Result<()>;
1031
1032 /// Minimizes the window.
1033 fn minimize(&self) -> Result<()>;
1034
1035 /// Unminimizes the window.
1036 fn unminimize(&self) -> Result<()>;
1037
1038 /// Shows the window.
1039 fn show(&self) -> Result<()>;
1040
1041 /// Hides the window.
1042 fn hide(&self) -> Result<()>;
1043
1044 /// Closes the window.
1045 fn close(&self) -> Result<()>;
1046
1047 /// Destroys the window.
1048 fn destroy(&self) -> Result<()>;
1049
1050 /// Updates the decorations flag.
1051 fn set_decorations(&self, decorations: bool) -> Result<()>;
1052
1053 /// Updates the shadow flag.
1054 fn set_shadow(&self, enable: bool) -> Result<()>;
1055
1056 /// Updates the window alwaysOnBottom flag.
1057 fn set_always_on_bottom(&self, always_on_bottom: bool) -> Result<()>;
1058
1059 /// Updates the window alwaysOnTop flag.
1060 fn set_always_on_top(&self, always_on_top: bool) -> Result<()>;
1061
1062 /// Updates the window visibleOnAllWorkspaces flag.
1063 fn set_visible_on_all_workspaces(&self, visible_on_all_workspaces: bool) -> Result<()>;
1064
1065 /// Set the window background.
1066 fn set_background_color(&self, color: Option<Color>) -> Result<()>;
1067
1068 /// Prevents the window contents from being captured by other apps.
1069 fn set_content_protected(&self, protected: bool) -> Result<()>;
1070
1071 /// Resizes the window.
1072 fn set_size(&self, size: Size) -> Result<()>;
1073
1074 /// Updates the window min inner size.
1075 fn set_min_size(&self, size: Option<Size>) -> Result<()>;
1076
1077 /// Updates the window max inner size.
1078 fn set_max_size(&self, size: Option<Size>) -> Result<()>;
1079
1080 /// Sets this window's minimum inner width.
1081 fn set_size_constraints(&self, constraints: WindowSizeConstraints) -> Result<()>;
1082
1083 /// Updates the window position.
1084 fn set_position(&self, position: Position) -> Result<()>;
1085
1086 /// Updates the window fullscreen state.
1087 fn set_fullscreen(&self, fullscreen: bool) -> Result<()>;
1088
1089 /// Sets the window as fullscreen on the monitor that contains the given physical position.
1090 ///
1091 /// Does nothing if no monitor contains the position.
1092 fn set_fullscreen_on_monitor(&self, position: PhysicalPosition<f64>) -> Result<()>;
1093
1094 #[cfg(target_os = "macos")]
1095 fn set_simple_fullscreen(&self, enable: bool) -> Result<()>;
1096
1097 /// Bring the window to front and focus.
1098 fn set_focus(&self) -> Result<()>;
1099
1100 /// Sets whether the window can be focused.
1101 fn set_focusable(&self, focusable: bool) -> Result<()>;
1102
1103 /// Updates the window icon.
1104 fn set_icon(&self, icon: Icon) -> Result<()>;
1105
1106 /// Whether to hide the window icon from the taskbar or not.
1107 fn set_skip_taskbar(&self, skip: bool) -> Result<()>;
1108
1109 /// Grabs the cursor, preventing it from leaving the window.
1110 ///
1111 /// There's no guarantee that the cursor will be hidden. You should
1112 /// hide it by yourself if you want so.
1113 fn set_cursor_grab(&self, grab: bool) -> Result<()>;
1114
1115 /// Modifies the cursor's visibility.
1116 ///
1117 /// If `false`, this will hide the cursor. If `true`, this will show the cursor.
1118 fn set_cursor_visible(&self, visible: bool) -> Result<()>;
1119
1120 // Modifies the cursor icon of the window.
1121 fn set_cursor_icon(&self, icon: CursorIcon) -> Result<()>;
1122
1123 /// Changes the position of the cursor in window coordinates.
1124 fn set_cursor_position<Pos: Into<Position>>(&self, position: Pos) -> Result<()>;
1125
1126 /// Ignores the window cursor events.
1127 fn set_ignore_cursor_events(&self, ignore: bool) -> Result<()>;
1128
1129 /// Starts dragging the window.
1130 fn start_dragging(&self) -> Result<()>;
1131
1132 /// Starts resize-dragging the window.
1133 fn start_resize_dragging(&self, direction: ResizeDirection) -> Result<()>;
1134
1135 /// Sets the badge count on the taskbar
1136 /// The badge count appears as a whole for the application
1137 /// Using `0` or using `None` will remove the badge
1138 ///
1139 /// ## Platform-specific
1140 /// - **Windows:** Unsupported, use [`WindowDispatch::set_overlay_icon`] instead.
1141 /// - **Android:** Unsupported.
1142 /// - **iOS:** iOS expects i32, if the value is larger than i32::MAX, it will be clamped to i32::MAX.
1143 fn set_badge_count(&self, count: Option<i64>, desktop_filename: Option<String>) -> Result<()>;
1144
1145 /// Sets the badge count on the taskbar **macOS only**. Using `None` will remove the badge
1146 fn set_badge_label(&self, label: Option<String>) -> Result<()>;
1147
1148 /// Sets the overlay icon on the taskbar **Windows only**. Using `None` will remove the icon
1149 ///
1150 /// The overlay icon can be unique for each window.
1151 fn set_overlay_icon(&self, icon: Option<Icon>) -> Result<()>;
1152
1153 /// Sets the taskbar progress state.
1154 ///
1155 /// ## Platform-specific
1156 ///
1157 /// - **Linux / macOS**: Progress bar is app-wide and not specific to this window. Only supported desktop environments with `libunity` (e.g. GNOME).
1158 /// - **iOS / Android:** Unsupported.
1159 fn set_progress_bar(&self, progress_state: ProgressBarState) -> Result<()>;
1160
1161 /// Sets the title bar style. Available on macOS only.
1162 ///
1163 /// ## Platform-specific
1164 ///
1165 /// - **Linux / Windows / iOS / Android:** Unsupported.
1166 fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>;
1167
1168 /// Change the position of the window controls. Available on macOS only.
1169 ///
1170 /// Requires titleBarStyle: Overlay and decorations: true.
1171 ///
1172 /// ## Platform-specific
1173 ///
1174 /// - **Linux / Windows / iOS / Android:** Unsupported.
1175 fn set_traffic_light_position(&self, position: Position) -> Result<()>;
1176
1177 /// Sets the theme for this window.
1178 ///
1179 /// ## Platform-specific
1180 ///
1181 /// - **Linux / macOS**: Theme is app-wide and not specific to this window.
1182 /// - **iOS / Android:** Unsupported.
1183 fn set_theme(&self, theme: Option<Theme>) -> Result<()>;
1184}