Skip to main content

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