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