lib.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. // Copyright 2019-2021 Tauri Programme within The Commons Conservancy
  2. // SPDX-License-Identifier: Apache-2.0
  3. // SPDX-License-Identifier: MIT
  4. //! Tauri is a framework for building tiny, blazing fast binaries for all major desktop platforms.
  5. //! Developers can integrate any front-end framework that compiles to HTML, JS and CSS for building their user interface.
  6. //! The backend of the application is a rust-sourced binary with an API that the front-end can interact with.
  7. #![warn(missing_docs, rust_2018_idioms)]
  8. #![cfg_attr(doc_cfg, feature(doc_cfg))]
  9. /// The Tauri error enum.
  10. pub use error::Error;
  11. pub use tauri_macros::{command, generate_handler};
  12. pub mod api;
  13. pub(crate) mod app;
  14. /// Async runtime.
  15. pub mod async_runtime;
  16. pub mod command;
  17. /// The Tauri API endpoints.
  18. mod endpoints;
  19. mod error;
  20. mod event;
  21. mod hooks;
  22. mod manager;
  23. pub mod plugin;
  24. /// Tauri window.
  25. pub mod window;
  26. use tauri_runtime as runtime;
  27. /// The Tauri-specific settings for your runtime e.g. notification permission status.
  28. pub mod settings;
  29. mod state;
  30. #[cfg(feature = "updater")]
  31. pub mod updater;
  32. #[cfg(feature = "wry")]
  33. pub use tauri_runtime_wry::Wry;
  34. /// `Result<T, ::tauri::Error>`
  35. pub type Result<T> = std::result::Result<T, Error>;
  36. /// A task to run on the main thread.
  37. pub type SyncTask = Box<dyn FnOnce() + Send>;
  38. use crate::{
  39. event::{Event, EventHandler},
  40. runtime::window::PendingWindow,
  41. };
  42. use serde::Serialize;
  43. use std::{borrow::Borrow, collections::HashMap, sync::Arc};
  44. // Export types likely to be used by the application.
  45. #[cfg(any(feature = "menu", feature = "system-tray"))]
  46. #[cfg_attr(doc_cfg, doc(cfg(any(feature = "menu", feature = "system-tray"))))]
  47. pub use runtime::menu::CustomMenuItem;
  48. pub use {
  49. self::api::assets::Assets,
  50. self::api::{
  51. config::{Config, WindowUrl},
  52. PackageInfo,
  53. },
  54. self::app::{App, AppHandle, Builder, GlobalWindowEvent},
  55. self::hooks::{
  56. Invoke, InvokeError, InvokeHandler, InvokeMessage, InvokeResolver, InvokeResponse, OnPageLoad,
  57. PageLoadPayload, SetupHook,
  58. },
  59. self::runtime::{
  60. tag::{Tag, TagRef},
  61. webview::{WebviewAttributes, WindowBuilder},
  62. window::{
  63. dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Pixel, Position, Size},
  64. WindowEvent,
  65. },
  66. Icon, MenuId, Params, RunIteration,
  67. },
  68. self::state::{State, StateManager},
  69. self::window::{Monitor, Window},
  70. };
  71. #[cfg(feature = "system-tray")]
  72. #[cfg_attr(doc_cfg, doc(cfg(feature = "system-tray")))]
  73. pub use {self::app::SystemTrayEvent, self::runtime::menu::SystemTrayMenuItem};
  74. #[cfg(feature = "menu")]
  75. #[cfg_attr(doc_cfg, doc(cfg(feature = "menu")))]
  76. pub use {
  77. self::app::WindowMenuEvent,
  78. self::runtime::menu::{Menu, MenuItem},
  79. self::window::MenuEvent,
  80. };
  81. /// Reads the config file at compile time and generates a [`Context`] based on its content.
  82. ///
  83. /// The default config file path is a `tauri.conf.json` file inside the Cargo manifest directory of
  84. /// the crate being built.
  85. ///
  86. /// # Custom Config Path
  87. ///
  88. /// You may pass a string literal to this macro to specify a custom path for the Tauri config file.
  89. /// If the path is relative, it will be search for relative to the Cargo manifest of the compiling
  90. /// crate.
  91. ///
  92. /// # Note
  93. ///
  94. /// This macro should not be called if you are using [`tauri-build`] to generate the context from
  95. /// inside your build script as it will just cause excess computations that will be discarded. Use
  96. /// either the [`tauri-build] method or this macro - not both.
  97. ///
  98. /// [`tauri-build`]: https://docs.rs/tauri-build
  99. pub use tauri_macros::generate_context;
  100. /// Include a [`Context`] that was generated by [`tauri-build`] inside your build script.
  101. ///
  102. /// You should either use [`tauri-build`] and this macro to include the compile time generated code,
  103. /// or [`generate_context!`]. Do not use both at the same time, as they generate the same code and
  104. /// will cause excess computations that will be discarded.
  105. ///
  106. /// [`tauri-build`]: https://docs.rs/tauri-build
  107. #[macro_export]
  108. macro_rules! tauri_build_context {
  109. () => {
  110. include!(concat!(env!("OUT_DIR"), "/tauri-build-context.rs"))
  111. };
  112. }
  113. /// User supplied data required inside of a Tauri application.
  114. ///
  115. /// # Stability
  116. /// This is the output of the `tauri::generate_context!` macro, and is not considered part of the stable API.
  117. /// Unless you know what you are doing and are prepared for this type to have breaking changes, do not create it yourself.
  118. pub struct Context<A: Assets> {
  119. pub(crate) config: Config,
  120. pub(crate) assets: Arc<A>,
  121. pub(crate) default_window_icon: Option<Vec<u8>>,
  122. pub(crate) system_tray_icon: Option<Icon>,
  123. pub(crate) package_info: crate::api::PackageInfo,
  124. }
  125. impl<A: Assets> Context<A> {
  126. /// The config the application was prepared with.
  127. #[inline(always)]
  128. pub fn config(&self) -> &Config {
  129. &self.config
  130. }
  131. /// A mutable reference to the config the application was prepared with.
  132. #[inline(always)]
  133. pub fn config_mut(&mut self) -> &mut Config {
  134. &mut self.config
  135. }
  136. /// The assets to be served directly by Tauri.
  137. #[inline(always)]
  138. pub fn assets(&self) -> Arc<A> {
  139. self.assets.clone()
  140. }
  141. /// A mutable reference to the assets to be served directly by Tauri.
  142. #[inline(always)]
  143. pub fn assets_mut(&mut self) -> &mut Arc<A> {
  144. &mut self.assets
  145. }
  146. /// The default window icon Tauri should use when creating windows.
  147. #[inline(always)]
  148. pub fn default_window_icon(&self) -> Option<&[u8]> {
  149. self.default_window_icon.as_deref()
  150. }
  151. /// A mutable reference to the default window icon Tauri should use when creating windows.
  152. #[inline(always)]
  153. pub fn default_window_icon_mut(&mut self) -> &mut Option<Vec<u8>> {
  154. &mut self.default_window_icon
  155. }
  156. /// The icon to use on the system tray UI.
  157. #[inline(always)]
  158. pub fn system_tray_icon(&self) -> Option<&Icon> {
  159. self.system_tray_icon.as_ref()
  160. }
  161. /// A mutable reference to the icon to use on the system tray UI.
  162. #[inline(always)]
  163. pub fn system_tray_icon_mut(&mut self) -> &mut Option<Icon> {
  164. &mut self.system_tray_icon
  165. }
  166. /// Package information.
  167. #[inline(always)]
  168. pub fn package_info(&self) -> &crate::api::PackageInfo {
  169. &self.package_info
  170. }
  171. /// A mutable reference to the package information.
  172. #[inline(always)]
  173. pub fn package_info_mut(&mut self) -> &mut crate::api::PackageInfo {
  174. &mut self.package_info
  175. }
  176. /// Create a new [`Context`] from the minimal required items.
  177. #[inline(always)]
  178. pub fn new(
  179. config: Config,
  180. assets: Arc<A>,
  181. default_window_icon: Option<Vec<u8>>,
  182. system_tray_icon: Option<Icon>,
  183. package_info: crate::api::PackageInfo,
  184. ) -> Self {
  185. Self {
  186. config,
  187. assets,
  188. default_window_icon,
  189. system_tray_icon,
  190. package_info,
  191. }
  192. }
  193. }
  194. // TODO: expand these docs
  195. /// Manages a running application.
  196. pub trait Manager<P: Params>: sealed::ManagerBase<P> {
  197. /// The [`Config`] the manager was created with.
  198. fn config(&self) -> Arc<Config> {
  199. self.manager().config()
  200. }
  201. /// Emits a event to all windows.
  202. fn emit_all<E: ?Sized, S>(&self, event: &E, payload: S) -> Result<()>
  203. where
  204. P::Event: Borrow<E>,
  205. E: TagRef<P::Event>,
  206. S: Serialize + Clone,
  207. {
  208. self.manager().emit_filter(event, payload, |_| true)
  209. }
  210. /// Emits an event to a window with the specified label.
  211. fn emit_to<E: ?Sized, L: ?Sized, S: Serialize + Clone>(
  212. &self,
  213. label: &L,
  214. event: &E,
  215. payload: S,
  216. ) -> Result<()>
  217. where
  218. P::Label: Borrow<L>,
  219. P::Event: Borrow<E>,
  220. L: TagRef<P::Label>,
  221. E: TagRef<P::Event>,
  222. {
  223. self
  224. .manager()
  225. .emit_filter(event, payload, |w| label == w.label())
  226. }
  227. /// Listen to a global event.
  228. fn listen_global<E: Into<P::Event>, F>(&self, event: E, handler: F) -> EventHandler
  229. where
  230. F: Fn(Event) + Send + 'static,
  231. {
  232. self.manager().listen(event.into(), None, handler)
  233. }
  234. /// Listen to a global event only once.
  235. fn once_global<E: Into<P::Event>, F>(&self, event: E, handler: F) -> EventHandler
  236. where
  237. F: Fn(Event) + Send + 'static,
  238. {
  239. self.manager().once(event.into(), None, handler)
  240. }
  241. /// Trigger a global event.
  242. fn trigger_global<E: ?Sized>(&self, event: &E, data: Option<String>)
  243. where
  244. P::Event: Borrow<E>,
  245. E: TagRef<P::Event>,
  246. {
  247. self.manager().trigger(event, None, data)
  248. }
  249. /// Remove an event listener.
  250. fn unlisten(&self, handler_id: EventHandler) {
  251. self.manager().unlisten(handler_id)
  252. }
  253. /// Fetch a single window from the manager.
  254. fn get_window<L: ?Sized>(&self, label: &L) -> Option<Window<P>>
  255. where
  256. P::Label: Borrow<L>,
  257. L: TagRef<P::Label>,
  258. {
  259. self.manager().get_window(label)
  260. }
  261. /// Fetch all managed windows.
  262. fn windows(&self) -> HashMap<P::Label, Window<P>> {
  263. self.manager().windows()
  264. }
  265. /// Add `state` to the state managed by the application.
  266. /// See [`crate::Builder#manage`] for instructions.
  267. fn manage<T>(&self, state: T)
  268. where
  269. T: Send + Sync + 'static,
  270. {
  271. self.manager().state().set(state);
  272. }
  273. /// Gets the managed state for the type `T`.
  274. fn state<T>(&self) -> State<'_, T>
  275. where
  276. T: Send + Sync + 'static,
  277. {
  278. self.manager().inner.state.get()
  279. }
  280. }
  281. /// Prevent implementation details from leaking out of the [`Manager`] trait.
  282. pub(crate) mod sealed {
  283. use crate::manager::WindowManager;
  284. use tauri_runtime::{Params, Runtime, RuntimeHandle};
  285. /// A running [`Runtime`] or a dispatcher to it.
  286. pub enum RuntimeOrDispatch<'r, P: Params> {
  287. /// Reference to the running [`Runtime`].
  288. Runtime(&'r P::Runtime),
  289. /// Handle to the running [`Runtime`].
  290. RuntimeHandle(<P::Runtime as Runtime>::Handle),
  291. /// A dispatcher to the running [`Runtime`].
  292. Dispatch(<P::Runtime as Runtime>::Dispatcher),
  293. }
  294. /// Managed handle to the application runtime.
  295. pub trait ManagerBase<P: Params> {
  296. /// The manager behind the [`Managed`] item.
  297. fn manager(&self) -> &WindowManager<P>;
  298. fn runtime(&self) -> RuntimeOrDispatch<'_, P>;
  299. /// Creates a new [`Window`] on the [`Runtime`] and attaches it to the [`Manager`].
  300. fn create_new_window(
  301. &self,
  302. pending: crate::PendingWindow<P>,
  303. ) -> crate::Result<crate::Window<P>> {
  304. use crate::runtime::Dispatch;
  305. let labels = self.manager().labels().into_iter().collect::<Vec<_>>();
  306. let pending = self.manager().prepare_window(pending, &labels)?;
  307. match self.runtime() {
  308. RuntimeOrDispatch::Runtime(runtime) => runtime.create_window(pending).map_err(Into::into),
  309. RuntimeOrDispatch::RuntimeHandle(handle) => {
  310. handle.create_window(pending).map_err(Into::into)
  311. }
  312. RuntimeOrDispatch::Dispatch(mut dispatcher) => {
  313. dispatcher.create_window(pending).map_err(Into::into)
  314. }
  315. }
  316. .map(|window| self.manager().attach_window(window))
  317. }
  318. }
  319. }
  320. #[cfg(test)]
  321. mod test {
  322. use proptest::prelude::*;
  323. proptest! {
  324. #![proptest_config(ProptestConfig::with_cases(10000))]
  325. #[test]
  326. // check to see if spawn executes a function.
  327. fn check_spawn_task(task in "[a-z]+") {
  328. // create dummy task function
  329. let dummy_task = async move {
  330. format!("{}-run-dummy-task", task);
  331. };
  332. // call spawn
  333. crate::async_runtime::spawn(dummy_task);
  334. }
  335. }
  336. }