refactor(tauri): expose all items meant to be public (#1454)

This commit is contained in:
chip
2021-04-11 16:44:01 -07:00
committed by GitHub
parent 863dd87ad7
commit 7fab1c039b
21 changed files with 683 additions and 636 deletions

View File

@@ -8,7 +8,7 @@ use quote::quote;
use std::path::PathBuf;
use tauri_api::config::Config;
/// Necessary data needed by [`codegen_context`] to generate code for a Tauri application context.
/// Necessary data needed by [`context_codegen`] to generate code for a Tauri application context.
pub struct ContextData {
pub dev: bool,
pub config: Config,
@@ -16,7 +16,7 @@ pub struct ContextData {
pub context_path: TokenStream,
}
/// Build an `AsTauriContext` implementation for including in application code.
/// Build a `tauri::Context` for including in application code.
pub fn context_codegen(data: ContextData) -> Result<TokenStream, EmbeddedAssetsError> {
let ContextData {
dev,

View File

@@ -26,18 +26,7 @@ pub fn generate_handler(item: TokenStream) -> TokenStream {
gen.into()
}
/// Reads a Tauri config file and generates an [`AsTauriContext`] based on the content.
///
/// The default config file path is a `tauri.conf.json` file inside the Cargo manifest directory of
/// the crate being built.
///
/// # Custom Config Path
///
/// You may pass a string literal to this macro to specify a custom path for the Tauri config file.
/// If the path is relative, it will be search for relative to the Cargo manifest of the compiling
/// crate.
///
/// todo: link the [`AsTauriContext`] docs
/// Reads a Tauri config file and generates a `::tauri::Context` based on the content.
#[proc_macro]
pub fn generate_context(items: TokenStream) -> TokenStream {
// this macro is exported from the context module

View File

@@ -5,7 +5,7 @@
use crate::{
api::{config::Config, PackageInfo},
hooks::InvokeMessage,
runtime::Params,
Params,
};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;

View File

@@ -2,10 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use crate::{
endpoints::InvokeResponse,
runtime::{sealed::ManagerPrivate, window::Window, Manager, Params},
};
use crate::{endpoints::InvokeResponse, sealed::ManagerPrivate, Manager, Params, Window};
use serde::Deserialize;
/// The API descriptor.

View File

@@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
use super::InvokeResponse;
use crate::runtime::{window::Window, Dispatch, Params};
use crate::{runtime::Dispatch, Params, Window};
use once_cell::sync::Lazy;
use serde::Deserialize;
use std::sync::{Arc, Mutex};

View File

@@ -3,7 +3,7 @@
// SPDX-License-Identifier: MIT
use super::InvokeResponse;
use crate::{runtime::window::Window, Params};
use crate::{Params, Window};
use serde::Deserialize;
/// The API descriptor.

View File

@@ -8,7 +8,7 @@ use crate::{
rpc::format_callback,
},
endpoints::InvokeResponse,
runtime::{window::Window, Params},
Params, Window,
};
use once_cell::sync::Lazy;
use serde::Deserialize;

View File

@@ -3,15 +3,12 @@
// SPDX-License-Identifier: MIT
use crate::{
endpoints::InvokeResponse,
runtime::{
webview::{Icon, WindowConfig},
window::{PendingWindow, Window},
Manager, Params,
},
api::config::WindowConfig, endpoints::InvokeResponse, runtime::window::PendingWindow, Manager,
Params, Window,
};
use serde::Deserialize;
use crate::Icon;
use std::path::PathBuf;
#[derive(Deserialize)]
@@ -35,7 +32,7 @@ impl Into<Icon> for IconDto {
#[serde(tag = "cmd", rename_all = "camelCase")]
pub enum Cmd {
CreateWebview {
options: crate::api::config::WindowConfig,
options: WindowConfig,
},
SetResizable {
resizable: bool,
@@ -123,7 +120,7 @@ impl Cmd {
});
let url = options.url.clone();
let pending = PendingWindow::new(WindowConfig(options), label.clone(), url);
let pending = PendingWindow::with_config(options, label.clone(), url);
window.create_window(pending)?.emit_others_internal(
"tauri://window-created".to_string(),
Some(WindowCreatedEvent {

View File

@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
/// The plugin error type.
/// Runtime errors that can happen inside a Tauri application.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Failed to create webview.

View File

@@ -4,7 +4,8 @@
use crate::{
api::rpc::{format_callback, format_callback_result},
runtime::{app::App, window::Window, Params},
runtime::app::App,
Params, Window,
};
use serde::{Deserialize, Serialize};
use std::future::Future;

View File

@@ -14,7 +14,7 @@
pub use error::Error;
pub use tauri_api as api;
pub(crate) use tauri_api::private::async_runtime;
pub use tauri_macros::*;
pub use tauri_macros::{command, generate_handler};
/// The Tauri-specific settings for your runtime e.g. notification permission status.
pub mod settings;
@@ -24,28 +24,63 @@ mod endpoints;
mod error;
mod event;
mod hooks;
/// The plugin manager module contains helpers to manage runtime plugins.
pub mod plugin;
/// The internal runtime between an [`App`] and the webview.
pub mod runtime;
#[cfg(feature = "updater")]
mod updater;
/// Tauri result type.
/// `Result<T, ::tauri::Error>`
pub type Result<T> = std::result::Result<T, Error>;
/// A task to run on the main thread.
pub type SyncTask = Box<dyn FnOnce() + Send>;
/// types likely to be used by applications
use crate::api::assets::Assets;
use crate::api::config::Config;
use crate::event::{Event, EventHandler};
use crate::runtime::tag::Tag;
use crate::runtime::window::PendingWindow;
use crate::runtime::{Dispatch, Runtime};
use serde::Serialize;
use std::collections::HashMap;
use std::path::PathBuf;
// Export types likely to be used by the application.
pub use {
api::config::WindowUrl,
hooks::InvokeMessage,
runtime::app::Builder,
runtime::app::{App, Builder},
runtime::webview::Attributes,
runtime::window::Window,
runtime::{Context, Manager, Params},
runtime::window::export::Window,
};
/// Easy helper function to use the Tauri Context you made during build time.
/// Reads the config file at compile time and generates a [`Context`] based on its content.
///
/// The default config file path is a `tauri.conf.json` file inside the Cargo manifest directory of
/// the crate being built.
///
/// # Custom Config Path
///
/// You may pass a string literal to this macro to specify a custom path for the Tauri config file.
/// If the path is relative, it will be search for relative to the Cargo manifest of the compiling
/// crate.
///
/// # Note
///
/// This macro should not be called if you are using [`tauri-build`] to generate the context from
/// inside your build script as it will just cause excess computations that will be discarded. Use
/// either the [`tauri-build] method or this macro - not both.
///
/// [`tauri-build`]: https://docs.rs/tauri-build
pub use tauri_macros::generate_context;
/// Include a [`Context`] that was generated by [`tauri-build`] inside your build script.
///
/// You should either use [`tauri-build`] and this macro to include the compile time generated code,
/// or [`generate_context!`]. Do not use both at the same time, as they generate the same code and
/// will cause excess computations that will be discarded.
///
/// [`tauri-build`]: https://docs.rs/tauri-build
#[macro_export]
macro_rules! tauri_build_context {
() => {
@@ -53,6 +88,244 @@ macro_rules! tauri_build_context {
};
}
/// A icon definition.
pub enum Icon {
/// Icon from file path.
File(PathBuf),
/// Icon from raw bytes.
Raw(Vec<u8>),
}
/// User supplied data required inside of a Tauri application.
pub struct Context<A: Assets> {
/// The config the application was prepared with.
pub config: Config,
/// The assets to be served directly by Tauri.
pub assets: A,
/// The default window icon Tauri should use when creating windows.
pub default_window_icon: Option<Vec<u8>>,
/// Package information.
pub package_info: tauri_api::PackageInfo,
}
/// Types associated with the running Tauri application.
pub trait Params: sealed::ParamsPrivate<Self> {
/// The event type used to create and listen to events.
type Event: Tag;
/// The type used to determine the name of windows.
type Label: Tag;
/// Assets that Tauri should serve from itself.
type Assets: Assets;
/// The underlying webview runtime used by the Tauri application.
type Runtime: Runtime;
}
/// Manages a running application.
pub trait Manager<M: Params>: sealed::ManagerPrivate<M> {
/// The [`Config`] the manager was created with.
fn config(&self) -> &Config {
self.manager().config()
}
/// Emits a event to all windows.
fn emit_all<S: Serialize + Clone>(&self, event: M::Event, payload: Option<S>) -> Result<()> {
self.manager().emit_filter(event, payload, |_| true)
}
/// Emits an event to a window with the specified label.
fn emit_to<S: Serialize + Clone>(
&self,
label: &M::Label,
event: M::Event,
payload: Option<S>,
) -> Result<()> {
self
.manager()
.emit_filter(event, payload, |w| w.label() == label)
}
/// Creates a new [`Window`] on the [`Runtime`] and attaches it to the [`Manager`].
fn create_window(&mut self, pending: PendingWindow<M>) -> Result<Window<M>> {
use sealed::RuntimeOrDispatch::*;
let labels = self.manager().labels().into_iter().collect::<Vec<_>>();
let pending = self.manager().prepare_window(pending, &labels)?;
match self.runtime() {
Runtime(runtime) => runtime.create_window(pending),
Dispatch(mut dispatcher) => dispatcher.create_window(pending),
}
.map(|window| self.manager().attach_window(window))
}
/// Listen to a global event.
fn listen_global<F>(&self, event: M::Event, handler: F) -> EventHandler
where
F: Fn(Event) + Send + 'static,
{
self.manager().listen(event, None, handler)
}
/// Listen to a global event only once.
fn once_global<F>(&self, event: M::Event, handler: F)
where
F: Fn(Event) + Send + 'static,
{
self.manager().once(event, None, handler)
}
/// Trigger a global event.
fn trigger_global(&self, event: M::Event, data: Option<String>) {
self.manager().trigger(event, None, data)
}
/// Remove an event listener.
fn unlisten(&self, handler_id: EventHandler) {
self.manager().unlisten(handler_id)
}
/// Fetch a single window from the manager.
fn get_window(&self, label: &M::Label) -> Option<Window<M>> {
self.manager().get_window(label)
}
/// Fetch all managed windows.
fn windows(&self) -> HashMap<M::Label, Window<M>> {
self.manager().windows()
}
}
/// Prevent implementation details from leaking out of the [`Manager`] and [`Params`] traits.
pub(crate) mod sealed {
use super::Params;
use crate::runtime::Runtime;
use crate::{
api::{config::Config, PackageInfo},
event::{Event, EventHandler},
hooks::{InvokeMessage, PageLoadPayload},
runtime::window::{DetachedWindow, PendingWindow},
Window,
};
use serde::Serialize;
use std::collections::{HashMap, HashSet};
use uuid::Uuid;
/// private manager api
pub trait ParamsPrivate<M: Params>: Clone + Send + Sized + 'static {
/// Pass messages not handled by modules or plugins to the running application
fn run_invoke_handler(&self, message: InvokeMessage<M>);
/// Ran once for every window when the page is loaded.
fn run_on_page_load(&self, window: Window<M>, payload: PageLoadPayload);
/// Pass a message to be handled by a plugin that expects the command.
fn extend_api(&self, command: String, message: InvokeMessage<M>);
/// Initialize all the plugins attached to the [`Manager`].
fn initialize_plugins(&self) -> crate::Result<()>;
/// Prepare a [`PendingWindow`] to be created by the [`Runtime`].
///
/// The passed labels should represent either all the windows in the manager. If the application
/// has not yet been started, the passed labels should represent all windows that will be
/// created before starting.
fn prepare_window(
&self,
pending: PendingWindow<M>,
labels: &[M::Label],
) -> crate::Result<PendingWindow<M>>;
/// Attach a detached window to the manager.
fn attach_window(&self, window: DetachedWindow<M>) -> Window<M>;
/// Emit an event to javascript windows that pass the predicate.
fn emit_filter_internal<S: Serialize + Clone, F: Fn(&Window<Self>) -> bool>(
&self,
event: String,
payload: Option<S>,
filter: F,
) -> crate::Result<()>;
/// Emit an event to javascript windows that pass the predicate.
fn emit_filter<S: Serialize + Clone, F: Fn(&Window<M>) -> bool>(
&self,
event: M::Event,
payload: Option<S>,
predicate: F,
) -> crate::Result<()>;
/// All current window labels existing.
fn labels(&self) -> HashSet<M::Label>;
/// The configuration the [`Manager`] was built with.
fn config(&self) -> &Config;
/// App package information.
fn package_info(&self) -> &PackageInfo;
/// Remove the specified event handler.
fn unlisten(&self, handler_id: EventHandler);
/// Trigger an event.
fn trigger(&self, event: M::Event, window: Option<M::Label>, data: Option<String>);
/// Set up a listener to an event.
fn listen<F: Fn(Event) + Send + 'static>(
&self,
event: M::Event,
window: Option<M::Label>,
handler: F,
) -> EventHandler;
/// Set up a listener to and event that is automatically removed after called once.
fn once<F: Fn(Event) + Send + 'static>(
&self,
event: M::Event,
window: Option<M::Label>,
handler: F,
);
fn event_listeners_object_name(&self) -> String;
fn event_queue_object_name(&self) -> String;
fn event_emit_function_name(&self) -> String;
/// Generate a random salt and store it in the manager
fn generate_salt(&self) -> Uuid;
/// Verify that the passed salt is a valid salt in the manager.
fn verify_salt(&self, salt: String) -> bool;
/// Get a single managed window.
fn get_window(&self, label: &M::Label) -> Option<Window<M>>;
/// Get all managed windows.
fn windows(&self) -> HashMap<M::Label, Window<M>>;
}
/// Represents either a running [`Runtime`] or a dispatcher to it.
pub enum RuntimeOrDispatch<'m, M: Params> {
/// Mutable reference to the running [`Runtime`].
Runtime(&'m mut M::Runtime),
/// A dispatcher to the running [`Runtime`].
Dispatch(<M::Runtime as Runtime>::Dispatcher),
}
/// Represents a managed handle to the application runner.
pub trait ManagerPrivate<M: Params> {
/// The manager behind the [`Managed`] item.
fn manager(&self) -> &M;
/// The runtime or runtime dispatcher of the [`Managed`] item.
fn runtime(&mut self) -> RuntimeOrDispatch<'_, M>;
}
}
#[cfg(test)]
mod test {
use proptest::prelude::*;

View File

@@ -2,10 +2,12 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! Extend Tauri functionality.
use crate::{
api::config::PluginConfig,
hooks::{InvokeMessage, PageLoadPayload},
runtime::{window::Window, Params},
Params, Window,
};
use serde_json::Value as JsonValue;
use std::collections::HashMap;
@@ -44,7 +46,7 @@ pub trait Plugin<M: Params>: Send {
}
/// Plugin collection type.
pub struct PluginStore<M: Params> {
pub(crate) struct PluginStore<M: Params> {
store: HashMap<&'static str, Box<dyn Plugin<M>>>,
}

View File

@@ -7,18 +7,19 @@ use crate::{
hooks::{InvokeHandler, InvokeMessage, OnPageLoad, PageLoadPayload, SetupHook},
plugin::{Plugin, PluginStore},
runtime::{
flavor::wry::Wry,
manager::WindowManager,
sealed::{ManagerPrivate, ParamsPrivate},
tag::Tag,
updater,
webview::{Attributes, WindowConfig},
window::{PendingWindow, Window},
Context, Dispatch, Manager, Params, Runtime, RuntimeOrDispatch,
flavors::wry::Wry, manager::WindowManager, tag::Tag, webview::Attributes,
window::PendingWindow, Dispatch, Runtime,
},
sealed::{ManagerPrivate, ParamsPrivate, RuntimeOrDispatch},
Context, Manager, Params, Window,
};
#[cfg(feature = "updater")]
use crate::updater;
/// A handle to the currently running application.
///
/// This type implements [`Manager`] which allows for manipulation of global application items.
pub struct App<P: Params> {
runtime: P::Runtime,
manager: P,
@@ -94,7 +95,7 @@ impl<M: Params> App<M> {
}
}
/// The App builder.
/// Builds a Tauri application.
pub struct Builder<E, L, A, R>
where
E: Tag,
@@ -202,7 +203,7 @@ where
self
.pending_windows
.push(PendingWindow::new(WindowConfig(config), label, url));
.push(PendingWindow::with_config(config, label, url));
}
manager.initialize_plugins()?;

View File

@@ -2,15 +2,19 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! The [`wry`] webview runtime.
//! The [`wry`] Tauri [`Runtime`].
use crate::runtime::{
webview::{
Attributes, AttributesPrivate, CustomProtocol, FileDropEvent, FileDropHandler, Icon,
RpcRequest, WebviewRpcHandler, WindowConfig,
use crate::{
api::config::WindowConfig,
runtime::{
webview::{
Attributes, AttributesBase, CustomProtocol, FileDropEvent, FileDropHandler, RpcRequest,
WebviewRpcHandler,
},
window::{DetachedWindow, PendingWindow},
Dispatch, Params, Runtime,
},
window::{DetachedWindow, PendingWindow},
Dispatch, Params, Runtime,
Icon,
};
use std::{convert::TryFrom, path::PathBuf};
@@ -19,7 +23,7 @@ use std::fs::create_dir_all;
#[cfg(target_os = "windows")]
use tauri_api::path::{resolve_path, BaseDirectory};
/// Wraps a Tauri icon into a format [`wry`] expects the icon to be in.
/// Wrapper around a [`wry::Icon`] that can be created from an [`Icon`].
pub struct WryIcon(wry::Icon);
impl TryFrom<Icon> for WryIcon {
@@ -37,42 +41,43 @@ impl TryFrom<Icon> for WryIcon {
}
}
impl AttributesPrivate for wry::Attributes {
fn url(mut self, url: String) -> Self {
self.url.replace(url);
self
}
}
impl AttributesBase for wry::Attributes {}
impl Attributes for wry::Attributes {
type Icon = WryIcon;
impl From<WindowConfig> for wry::Attributes {
fn from(window_config: WindowConfig) -> Self {
fn new() -> Self {
Default::default()
}
fn with_config(config: WindowConfig) -> Self {
let mut webview = wry::Attributes::default()
.title(window_config.0.title.to_string())
.width(window_config.0.width)
.height(window_config.0.height)
.visible(window_config.0.visible)
.resizable(window_config.0.resizable)
.decorations(window_config.0.decorations)
.maximized(window_config.0.maximized)
.fullscreen(window_config.0.fullscreen)
.transparent(window_config.0.transparent)
.always_on_top(window_config.0.always_on_top);
if let Some(min_width) = window_config.0.min_width {
.title(config.title.to_string())
.width(config.width)
.height(config.height)
.visible(config.visible)
.resizable(config.resizable)
.decorations(config.decorations)
.maximized(config.maximized)
.fullscreen(config.fullscreen)
.transparent(config.transparent)
.always_on_top(config.always_on_top);
if let Some(min_width) = config.min_width {
webview = webview.min_width(min_width);
}
if let Some(min_height) = window_config.0.min_height {
if let Some(min_height) = config.min_height {
webview = webview.min_height(min_height);
}
if let Some(max_width) = window_config.0.max_width {
if let Some(max_width) = config.max_width {
webview = webview.max_width(max_width);
}
if let Some(max_height) = window_config.0.max_height {
if let Some(max_height) = config.max_height {
webview = webview.max_height(max_height);
}
if let Some(x) = window_config.0.x {
if let Some(x) = config.x {
webview = webview.x(x);
}
if let Some(y) = window_config.0.y {
if let Some(y) = config.y {
webview = webview.y(y);
}
@@ -101,15 +106,6 @@ impl From<WindowConfig> for wry::Attributes {
webview
}
}
/// The webview builder.
impl Attributes for wry::Attributes {
type Icon = WryIcon;
fn new() -> Self {
Default::default()
}
fn initialization_script(mut self, init: &str) -> Self {
self.initialization_scripts.push(init.to_string());
@@ -210,6 +206,11 @@ impl Attributes for wry::Attributes {
self
}
fn url(mut self, url: String) -> Self {
self.url.replace(url);
self
}
fn build(self) -> Self {
self
}
@@ -234,7 +235,7 @@ impl From<wry::FileDropEvent> for FileDropEvent {
}
}
/// A dispatcher for a [`wry`] runtime.
/// The Tauri [`Dispatch`] for [`Wry`].
#[derive(Clone)]
pub struct WryDispatcher {
window: wry::WindowProxy,
@@ -440,7 +441,7 @@ impl Dispatch for WryDispatcher {
}
}
/// A wrapper around the wry Application interface.
/// A Tauri [`Runtime`] wrapper around [`wry::Application`].
pub struct Wry {
inner: wry::Application,
}

View File

@@ -12,15 +12,13 @@ use crate::{
hooks::{InvokeHandler, InvokeMessage, InvokePayload, OnPageLoad, PageLoadPayload},
plugin::PluginStore,
runtime::{
sealed::ParamsPrivate,
tag::{tags_to_javascript_array, Tag, ToJavascript},
webview::{
Attributes, AttributesPrivate, CustomProtocol, FileDropEvent, FileDropHandler,
WebviewRpcHandler,
},
window::{DetachedWindow, PendingWindow, Window},
Context, Dispatch, Icon, Params, Runtime,
webview::{Attributes, CustomProtocol, FileDropEvent, FileDropHandler, WebviewRpcHandler},
window::{DetachedWindow, PendingWindow},
Dispatch, Icon, Runtime,
},
sealed::ParamsPrivate,
Context, Params, Window,
};
use serde::Serialize;
use serde_json::Value as JsonValue;
@@ -344,7 +342,7 @@ where
#[cfg(test)]
mod test {
use super::WindowManager;
use crate::{generate_context, plugin::PluginStore, runtime::flavor::wry::Wry};
use crate::{generate_context, plugin::PluginStore, runtime::flavors::wry::Wry};
#[test]
fn check_get_url() {
@@ -361,7 +359,7 @@ mod test {
#[cfg(dev)]
{
use crate::runtime::sealed::ParamsPrivate;
use crate::sealed::ParamsPrivate;
assert_eq!(manager.get_url(), manager.config().build.dev_path);
}
}

View File

@@ -2,43 +2,23 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! Internal runtime between Tauri and the underlying webview runtime.
use crate::{
api::{assets::Assets, config::Config},
event::{Event, EventHandler},
runtime::{
webview::{Attributes, AttributesPrivate, Icon, WindowConfig},
window::{DetachedWindow, PendingWindow, Window},
webview::AttributesBase,
window::{DetachedWindow, PendingWindow},
},
Attributes, Icon, Params,
};
use serde::Serialize;
use std::convert::TryFrom;
pub(crate) mod app;
pub mod flavor;
pub mod flavors;
pub(crate) mod manager;
pub(crate) mod tag;
#[cfg(feature = "updater")]
pub(crate) mod updater;
pub(crate) mod webview;
pub(crate) mod window;
pub use self::tag::Tag;
use std::collections::HashMap;
/// Important configurable items required by Tauri.
pub struct Context<A: Assets> {
/// The config the application was prepared with.
pub config: Config,
/// The assets to be served directly by Tauri.
pub assets: A,
/// The default window icon Tauri should use when creating windows.
pub default_window_icon: Option<Vec<u8>>,
/// Package information.
pub package_info: tauri_api::PackageInfo,
}
pub mod tag;
pub mod webview;
pub mod window;
/// The webview runtime interface.
pub trait Runtime: Sized + 'static {
@@ -48,11 +28,11 @@ pub trait Runtime: Sized + 'static {
/// Creates a new webview runtime.
fn new() -> crate::Result<Self>;
/// Creates a new webview window.
fn create_window<M: Params<Runtime = Self>>(
/// Create a new webview window.
fn create_window<P: Params<Runtime = Self>>(
&mut self,
pending: PendingWindow<M>,
) -> crate::Result<DetachedWindow<M>>;
pending: PendingWindow<P>,
) -> crate::Result<DetachedWindow<P>>;
/// Run the webview runtime.
fn run(self);
@@ -67,17 +47,13 @@ pub trait Dispatch: Clone + Send + Sized + 'static {
type Icon: TryFrom<Icon, Error = crate::Error>;
/// The webview builder type.
type Attributes: Attributes<Icon = Self::Icon>
+ AttributesPrivate
+ From<WindowConfig>
+ Clone
+ Send;
type Attributes: Attributes<Icon = Self::Icon> + AttributesBase + Clone + Send;
/// Creates a new webview window.
fn create_window<M: Params<Runtime = Self::Runtime>>(
/// Create a new webview window.
fn create_window<P: Params<Runtime = Self::Runtime>>(
&mut self,
pending: PendingWindow<M>,
) -> crate::Result<DetachedWindow<M>>;
pending: PendingWindow<P>,
) -> crate::Result<DetachedWindow<P>>;
/// Updates the window resizable flag.
fn set_resizable(&self, resizable: bool) -> crate::Result<()>;
@@ -145,221 +121,3 @@ pub trait Dispatch: Clone + Send + Sized + 'static {
/// Executes javascript on the window this [`Dispatch`] represents.
fn eval_script<S: Into<String>>(&self, script: S) -> crate::Result<()>;
}
/// Prevent implementation details from leaking out of the [`Manager`] and [`Managed`] traits.
pub(crate) mod sealed {
use super::Params;
use crate::{
api::{config::Config, PackageInfo},
event::{Event, EventHandler},
hooks::{InvokeMessage, PageLoadPayload},
runtime::{
window::{DetachedWindow, PendingWindow, Window},
RuntimeOrDispatch,
},
};
use serde::Serialize;
use std::collections::{HashMap, HashSet};
use uuid::Uuid;
/// private manager api
pub trait ParamsPrivate<M: Params>: Clone + Send + Sized + 'static {
/// Pass messages not handled by modules or plugins to the running application
fn run_invoke_handler(&self, message: InvokeMessage<M>);
/// Ran once for every window when the page is loaded.
fn run_on_page_load(&self, window: Window<M>, payload: PageLoadPayload);
/// Pass a message to be handled by a plugin that expects the command.
fn extend_api(&self, command: String, message: InvokeMessage<M>);
/// Initialize all the plugins attached to the [`Manager`].
fn initialize_plugins(&self) -> crate::Result<()>;
/// Prepare a [`PendingWindow`] to be created by the [`Runtime`].
///
/// The passed labels should represent either all the windows in the manager. If the application
/// has not yet been started, the passed labels should represent all windows that will be
/// created before starting.
fn prepare_window(
&self,
pending: PendingWindow<M>,
labels: &[M::Label],
) -> crate::Result<PendingWindow<M>>;
/// Attach a detached window to the manager.
fn attach_window(&self, window: DetachedWindow<M>) -> Window<M>;
/// Emit an event to javascript windows that pass the predicate.
fn emit_filter_internal<S: Serialize + Clone, F: Fn(&Window<Self>) -> bool>(
&self,
event: String,
payload: Option<S>,
filter: F,
) -> crate::Result<()>;
/// Emit an event to javascript windows that pass the predicate.
fn emit_filter<S: Serialize + Clone, F: Fn(&Window<M>) -> bool>(
&self,
event: M::Event,
payload: Option<S>,
predicate: F,
) -> crate::Result<()>;
/// All current window labels existing.
fn labels(&self) -> HashSet<M::Label>;
/// The configuration the [`Manager`] was built with.
fn config(&self) -> &Config;
/// App package information.
fn package_info(&self) -> &PackageInfo;
/// Remove the specified event handler.
fn unlisten(&self, handler_id: EventHandler);
/// Trigger an event.
fn trigger(&self, event: M::Event, window: Option<M::Label>, data: Option<String>);
/// Set up a listener to an event.
fn listen<F: Fn(Event) + Send + 'static>(
&self,
event: M::Event,
window: Option<M::Label>,
handler: F,
) -> EventHandler;
/// Set up a listener to and event that is automatically removed after called once.
fn once<F: Fn(Event) + Send + 'static>(
&self,
event: M::Event,
window: Option<M::Label>,
handler: F,
);
fn event_listeners_object_name(&self) -> String;
fn event_queue_object_name(&self) -> String;
fn event_emit_function_name(&self) -> String;
/// Generate a random salt and store it in the manager
fn generate_salt(&self) -> Uuid;
/// Verify that the passed salt is a valid salt in the manager.
fn verify_salt(&self, salt: String) -> bool;
/// Get a single managed window.
fn get_window(&self, label: &M::Label) -> Option<Window<M>>;
/// Get all managed windows.
fn windows(&self) -> HashMap<M::Label, Window<M>>;
}
/// Represents a managed handle to the application runner.
pub trait ManagerPrivate<M: Params> {
/// The manager behind the [`Managed`] item.
fn manager(&self) -> &M;
/// The runtime or runtime dispatcher of the [`Managed`] item.
fn runtime(&mut self) -> RuntimeOrDispatch<'_, M>;
}
}
/// Represents either a [`Runtime`] or its dispatcher.
pub enum RuntimeOrDispatch<'m, M: Params> {
/// Mutable reference to the [`Runtime`].
Runtime(&'m mut M::Runtime),
/// Copy of the [`Runtime`]'s dispatcher.
Dispatch(<M::Runtime as Runtime>::Dispatcher),
}
/// Represents a managed handle to the application runner
pub trait Manager<M: Params>: sealed::ManagerPrivate<M> {
/// The [`Config`] the manager was created with.
fn config(&self) -> &Config {
self.manager().config()
}
/// Emits a event to all windows.
fn emit_all<S: Serialize + Clone>(
&self,
event: M::Event,
payload: Option<S>,
) -> crate::Result<()> {
self.manager().emit_filter(event, payload, |_| true)
}
/// Emits an event to a window with the specified label.
fn emit_to<S: Serialize + Clone>(
&self,
label: &M::Label,
event: M::Event,
payload: Option<S>,
) -> crate::Result<()> {
self
.manager()
.emit_filter(event, payload, |w| w.label() == label)
}
/// Creates a new [`Window`] on the [`Runtime`] and attaches it to the [`Manager`].
fn create_window(&mut self, pending: PendingWindow<M>) -> crate::Result<Window<M>> {
let labels = self.manager().labels().into_iter().collect::<Vec<_>>();
let pending = self.manager().prepare_window(pending, &labels)?;
match self.runtime() {
RuntimeOrDispatch::Runtime(runtime) => runtime.create_window(pending),
RuntimeOrDispatch::Dispatch(mut dispatcher) => dispatcher.create_window(pending),
}
.map(|window| self.manager().attach_window(window))
}
/// Listen to a global event.
fn listen_global<F>(&self, event: M::Event, handler: F) -> EventHandler
where
F: Fn(Event) + Send + 'static,
{
self.manager().listen(event, None, handler)
}
/// Listen to a global event only once.
fn once_global<F>(&self, event: M::Event, handler: F)
where
F: Fn(Event) + Send + 'static,
{
self.manager().once(event, None, handler)
}
/// Trigger a global event.
fn trigger_global(&self, event: M::Event, data: Option<String>) {
self.manager().trigger(event, None, data)
}
/// Remove an event listener.
fn unlisten(&self, handler_id: EventHandler) {
self.manager().unlisten(handler_id)
}
/// Fetch a single window from the manager.
fn get_window(&self, label: &M::Label) -> Option<Window<M>> {
self.manager().get_window(label)
}
/// Fetch all managed windows.
fn windows(&self) -> HashMap<M::Label, Window<M>> {
self.manager().windows()
}
}
/// Types that the manager needs to have passed in by the application.
pub trait Params: sealed::ParamsPrivate<Self> {
/// The event type used to create and listen to events.
type Event: Tag;
/// The type used to determine the name of windows.
type Label: Tag;
/// Assets that Tauri should serve from itself.
type Assets: Assets;
/// The underlying webview runtime used by the Tauri application.
type Runtime: Runtime;
}

View File

@@ -26,7 +26,7 @@ use std::{
/// # Handling Errors
///
/// Because we leave it up to the type to implement [`FromStr`], if an error is returned during
/// parsing then Tauri will [`panic!`](std::panic) with the string it failed to parse.
/// parsing then Tauri will [`std::panic!`] with the string it failed to parse.
///
/// To avoid Tauri panicking during the application runtime, have your type be able to handle
/// unknown events and never return an error in [`FromStr`]. Then it will be up to your own code
@@ -71,7 +71,7 @@ use std::{
/// let event: Event = "tauri://file-drop".parse().unwrap();
///
/// // show that this event type can be represented as a Tag, a requirement for using it in Tauri.
/// fn is_file_drop(tag: impl tauri::runtime::Tag) {
/// fn is_file_drop(tag: impl tauri::runtime::tag::Tag) {
/// assert_eq!("tauri://file-drop", tag.to_string());
/// }
///

View File

@@ -2,33 +2,32 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
use crate::runtime::window::DetachedWindow;
//! Items specific to the [`Runtime`](crate::runtime::Runtime)'s webview.
use crate::runtime::Icon;
use crate::{api::config::WindowConfig, runtime::window::DetachedWindow};
use serde_json::Value as JsonValue;
use std::{convert::TryFrom, path::PathBuf};
/// A icon definition.
pub enum Icon {
/// Icon from file path.
File(PathBuf),
/// Icon from raw bytes.
Raw(Vec<u8>),
}
/// Do **NOT** implement this trait except for use in a custom [`Runtime`](crate::runtime::Runtime).
///
/// This trait is separate from [`Attributes`] to prevent "accidental" implementation.
pub trait AttributesBase: Sized {}
pub struct WindowConfig(pub crate::api::config::WindowConfig);
pub trait AttributesPrivate: Sized {
/// Sets the webview url.
fn url(self, url: String) -> Self;
}
/// The webview builder.
pub trait Attributes: Sized {
/// A builder for all attributes related to a single webview.
///
/// This trait is only meant to be implemented by a custom [`Runtime`](crate::runtime::Runtime)
/// and not by applications.
pub trait Attributes: AttributesBase {
/// Expected icon format.
type Icon: TryFrom<Icon, Error = crate::Error>;
/// Initializes a new webview builder.
fn new() -> Self;
/// Initializes a new webview builder from a [`WindowConfig`]
fn with_config(config: WindowConfig) -> Self;
/// Sets the init script.
fn initialization_script(self, init: &str) -> Self;
@@ -90,12 +89,13 @@ pub trait Attributes: Sized {
/// User data path for the webview. Actually only supported on Windows.
fn user_data_path(self, user_data_path: Option<PathBuf>) -> Self;
/// Sets the webview url.
fn url(self, url: String) -> Self;
/// The full attributes.
fn build(self) -> Self;
}
// TODO: should probably expand the following documentation
/// Rpc request.
pub struct RpcRequest {
/// RPC command.
@@ -104,9 +104,6 @@ pub struct RpcRequest {
pub params: Option<JsonValue>,
}
/// Rpc handler.
pub type WebviewRpcHandler<M> = Box<dyn Fn(DetachedWindow<M>, RpcRequest) + Send>;
/// Uses a custom handler to resolve file requests
pub struct CustomProtocol {
/// Name of the protocol
@@ -126,6 +123,9 @@ pub enum FileDropEvent {
Cancelled,
}
/// Rpc handler.
pub(crate) type WebviewRpcHandler<M> = Box<dyn Fn(DetachedWindow<M>, RpcRequest) + Send>;
/// File drop handler callback
/// Return `true` in the callback to block the OS' default behavior of handling a file drop.
pub type FileDropHandler<M> = Box<dyn Fn(FileDropEvent, DetachedWindow<M>) -> bool + Send>;
pub(crate) type FileDropHandler<M> = Box<dyn Fn(FileDropEvent, DetachedWindow<M>) -> bool + Send>;

View File

@@ -2,16 +2,20 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
//! A layer between raw [`Runtime`] webview windows and Tauri.
use crate::api::config::WindowConfig;
use crate::{
api::config::WindowUrl,
event::{Event, EventHandler},
hooks::{InvokeMessage, InvokePayload, PageLoadPayload},
runtime::{
sealed::ManagerPrivate,
tag::ToJavascript,
webview::{CustomProtocol, FileDropHandler, Icon, WebviewRpcHandler},
Dispatch, Manager, Params, Runtime, RuntimeOrDispatch,
webview::{CustomProtocol, FileDropHandler, WebviewRpcHandler},
Dispatch, Runtime,
},
sealed::{ManagerPrivate, RuntimeOrDispatch},
Attributes, Icon, Manager, Params,
};
use serde::Serialize;
use serde_json::Value as JsonValue;
@@ -42,13 +46,28 @@ pub struct PendingWindow<M: Params> {
}
impl<M: Params> PendingWindow<M> {
/// Create a new [`PendingWindow`] with a label and starting url.
pub fn new(
attributes: impl Into<<<M::Runtime as Runtime>::Dispatcher as Dispatch>::Attributes>,
attributes: <<M::Runtime as Runtime>::Dispatcher as Dispatch>::Attributes,
label: M::Label,
url: WindowUrl,
) -> Self {
Self {
attributes: attributes.into(),
attributes,
label,
url,
rpc_handler: None,
custom_protocol: None,
file_drop_handler: None,
}
}
/// Create a new [`PendingWindow`] from a [`WindowConfig`] with a label and starting url.
pub fn with_config(window_config: WindowConfig, label: M::Label, url: WindowUrl) -> Self {
Self {
attributes: <<<M::Runtime as Runtime>::Dispatcher as Dispatch>::Attributes>::with_config(
window_config,
),
label,
url,
rpc_handler: None,
@@ -60,7 +79,10 @@ impl<M: Params> PendingWindow<M> {
/// A webview window that is not yet managed by Tauri.
pub struct DetachedWindow<M: Params> {
/// Name of the window
pub label: M::Label,
/// The [`Dispatch`](crate::runtime::Dispatch) associated with the window.
pub dispatcher: <M::Runtime as Runtime>::Dispatcher,
}
@@ -88,285 +110,293 @@ impl<M: Params> PartialEq for DetachedWindow<M> {
}
}
/// A webview window managed by Tarui.
///
/// TODO: expand these docs since this is a pretty important type
pub struct Window<M: Params> {
/// The webview window created by the runtime.
window: DetachedWindow<M>,
/// We want to export the runtime related window at the crate root, but not look like a re-export.
pub(crate) mod export {
use super::*;
/// The manager to associate this webview window with.
manager: M,
}
/// A webview window managed by Tauri.
///
/// This type also implements [`Manager`] which allows you to manage other windows attached to
/// the same application.
///
/// TODO: expand these docs since this is a pretty important type
pub struct Window<M: Params> {
/// The webview window created by the runtime.
window: DetachedWindow<M>,
impl<M: Params> Clone for Window<M> {
fn clone(&self) -> Self {
Self {
window: self.window.clone(),
manager: self.manager.clone(),
}
}
}
impl<M: Params> Hash for Window<M> {
/// Only use the [`Window`]'s label to represent its hash.
fn hash<H: Hasher>(&self, state: &mut H) {
self.window.label.hash(state)
}
}
impl<M: Params> Eq for Window<M> {}
impl<M: Params> PartialEq for Window<M> {
/// Only use the [`Window`]'s label to compare equality.
fn eq(&self, other: &Self) -> bool {
self.window.label.eq(&other.window.label)
}
}
impl<M: Params> Manager<M> for Window<M> {}
impl<M: Params> ManagerPrivate<M> for Window<M> {
fn manager(&self) -> &M {
&self.manager
/// The manager to associate this webview window with.
manager: M,
}
fn runtime(&mut self) -> RuntimeOrDispatch<'_, M> {
RuntimeOrDispatch::Dispatch(self.dispatcher())
}
}
impl<M: Params> Window<M> {
/// Create a new window that is attached to the manager.
pub(crate) fn new(manager: M, window: DetachedWindow<M>) -> Self {
Self { manager, window }
}
/// The current window's dispatcher.
pub(crate) fn dispatcher(&self) -> <M::Runtime as Runtime>::Dispatcher {
self.window.dispatcher.clone()
}
/// How to handle this window receiving an [`InvokeMessage`].
pub(crate) fn on_message(self, command: String, payload: InvokePayload) -> crate::Result<()> {
let manager = self.manager.clone();
if &command == "__initialized" {
let payload: PageLoadPayload = serde_json::from_value(payload.inner)?;
manager.run_on_page_load(self, payload);
} else {
let message = InvokeMessage::new(self, command.to_string(), payload);
if let Some(module) = &message.payload.tauri_module {
let module = module.to_string();
crate::endpoints::handle(module, message, manager.config(), manager.package_info());
} else if command.starts_with("plugin:") {
manager.extend_api(command, message);
} else {
manager.run_invoke_handler(message);
impl<M: Params> Clone for Window<M> {
fn clone(&self) -> Self {
Self {
window: self.window.clone(),
manager: self.manager.clone(),
}
}
Ok(())
}
/// The label of this window.
pub fn label(&self) -> &M::Label {
&self.window.label
impl<M: Params> Hash for Window<M> {
/// Only use the [`Window`]'s label to represent its hash.
fn hash<H: Hasher>(&self, state: &mut H) {
self.window.label.hash(state)
}
}
pub(crate) fn emit_internal<E: ToJavascript, S: Serialize>(
&self,
event: E,
payload: Option<S>,
) -> crate::Result<()> {
let js_payload = match payload {
Some(payload_value) => serde_json::to_value(payload_value)?,
None => JsonValue::Null,
};
self.eval(&format!(
"window['{}']({{event: {}, payload: {}}}, '{}')",
self.manager.event_emit_function_name(),
event.to_javascript()?,
js_payload,
self.manager.generate_salt(),
))?;
Ok(())
impl<M: Params> Eq for Window<M> {}
impl<M: Params> PartialEq for Window<M> {
/// Only use the [`Window`]'s label to compare equality.
fn eq(&self, other: &Self) -> bool {
self.window.label.eq(&other.window.label)
}
}
/// Emits an event to the current window.
pub fn emit<S: Serialize>(&self, event: &M::Event, payload: Option<S>) -> crate::Result<()> {
self.emit_internal(event.clone(), payload)
impl<M: Params> Manager<M> for Window<M> {}
impl<M: Params> ManagerPrivate<M> for Window<M> {
fn manager(&self) -> &M {
&self.manager
}
fn runtime(&mut self) -> RuntimeOrDispatch<'_, M> {
RuntimeOrDispatch::Dispatch(self.dispatcher())
}
}
pub(crate) fn emit_others_internal<S: Serialize + Clone>(
&self,
event: String,
payload: Option<S>,
) -> crate::Result<()> {
self
.manager
.emit_filter_internal(event, payload, |w| w != self)
}
impl<M: Params> Window<M> {
/// Create a new window that is attached to the manager.
pub(crate) fn new(manager: M, window: DetachedWindow<M>) -> Self {
Self { manager, window }
}
/// Emits an event on all windows except this one.
pub fn emit_others<S: Serialize + Clone>(
&self,
event: M::Event,
payload: Option<S>,
) -> crate::Result<()> {
self.manager.emit_filter(event, payload, |w| w != self)
}
/// The current window's dispatcher.
pub(crate) fn dispatcher(&self) -> <M::Runtime as Runtime>::Dispatcher {
self.window.dispatcher.clone()
}
/// Listen to an event on this window.
pub fn listen<F>(&self, event: M::Event, handler: F) -> EventHandler
where
F: Fn(Event) + Send + 'static,
{
let label = self.window.label.clone();
self.manager.listen(event, Some(label), handler)
}
/// How to handle this window receiving an [`InvokeMessage`].
pub(crate) fn on_message(self, command: String, payload: InvokePayload) -> crate::Result<()> {
let manager = self.manager.clone();
if &command == "__initialized" {
let payload: PageLoadPayload = serde_json::from_value(payload.inner)?;
manager.run_on_page_load(self, payload);
} else {
let message = InvokeMessage::new(self, command.to_string(), payload);
if let Some(module) = &message.payload.tauri_module {
let module = module.to_string();
crate::endpoints::handle(module, message, manager.config(), manager.package_info());
} else if command.starts_with("plugin:") {
manager.extend_api(command, message);
} else {
manager.run_invoke_handler(message);
}
}
/// Listen to a an event on this window a single time.
pub fn once<F>(&self, event: M::Event, handler: F)
where
F: Fn(Event) + Send + 'static,
{
let label = self.window.label.clone();
self.manager.once(event, Some(label), handler)
}
Ok(())
}
/// Triggers an event on this window.
pub(crate) fn trigger(&self, event: M::Event, data: Option<String>) {
let label = self.window.label.clone();
self.manager.trigger(event, Some(label), data)
}
/// The label of this window.
pub fn label(&self) -> &M::Label {
&self.window.label
}
/// Evaluates JavaScript on this window.
pub fn eval(&self, js: &str) -> crate::Result<()> {
self.window.dispatcher.eval_script(js)
}
pub(crate) fn emit_internal<E: ToJavascript, S: Serialize>(
&self,
event: E,
payload: Option<S>,
) -> crate::Result<()> {
let js_payload = match payload {
Some(payload_value) => serde_json::to_value(payload_value)?,
None => JsonValue::Null,
};
/// Determines if this window should be resizable.
pub fn set_resizable(&self, resizable: bool) -> crate::Result<()> {
self.window.dispatcher.set_resizable(resizable)
}
self.eval(&format!(
"window['{}']({{event: {}, payload: {}}}, '{}')",
self.manager.event_emit_function_name(),
event.to_javascript()?,
js_payload,
self.manager.generate_salt(),
))?;
/// Set this window's title.
pub fn set_title(&self, title: &str) -> crate::Result<()> {
self.window.dispatcher.set_title(title.to_string())
}
Ok(())
}
/// Maximizes this window.
pub fn maximize(&self) -> crate::Result<()> {
self.window.dispatcher.maximize()
}
/// Emits an event to the current window.
pub fn emit<S: Serialize>(&self, event: &M::Event, payload: Option<S>) -> crate::Result<()> {
self.emit_internal(event.clone(), payload)
}
/// Un-maximizes this window.
pub fn unmaximize(&self) -> crate::Result<()> {
self.window.dispatcher.unmaximize()
}
pub(crate) fn emit_others_internal<S: Serialize + Clone>(
&self,
event: String,
payload: Option<S>,
) -> crate::Result<()> {
self
.manager
.emit_filter_internal(event, payload, |w| w != self)
}
/// Minimizes this window.
pub fn minimize(&self) -> crate::Result<()> {
self.window.dispatcher.minimize()
}
/// Emits an event on all windows except this one.
pub fn emit_others<S: Serialize + Clone>(
&self,
event: M::Event,
payload: Option<S>,
) -> crate::Result<()> {
self.manager.emit_filter(event, payload, |w| w != self)
}
/// Un-minimizes this window.
pub fn unminimize(&self) -> crate::Result<()> {
self.window.dispatcher.unminimize()
}
/// Listen to an event on this window.
pub fn listen<F>(&self, event: M::Event, handler: F) -> EventHandler
where
F: Fn(Event) + Send + 'static,
{
let label = self.window.label.clone();
self.manager.listen(event, Some(label), handler)
}
/// Show this window.
pub fn show(&self) -> crate::Result<()> {
self.window.dispatcher.show()
}
/// Listen to a an event on this window a single time.
pub fn once<F>(&self, event: M::Event, handler: F)
where
F: Fn(Event) + Send + 'static,
{
let label = self.window.label.clone();
self.manager.once(event, Some(label), handler)
}
/// Hide this window.
pub fn hide(&self) -> crate::Result<()> {
self.window.dispatcher.hide()
}
/// Triggers an event on this window.
pub(crate) fn trigger(&self, event: M::Event, data: Option<String>) {
let label = self.window.label.clone();
self.manager.trigger(event, Some(label), data)
}
/// Closes this window.
pub fn close(&self) -> crate::Result<()> {
self.window.dispatcher.close()
}
/// Evaluates JavaScript on this window.
pub fn eval(&self, js: &str) -> crate::Result<()> {
self.window.dispatcher.eval_script(js)
}
/// Determines if this window should be [decorated].
///
/// [decorated]: https://en.wikipedia.org/wiki/Window_(computing)#Window_decoration
pub fn set_decorations(&self, decorations: bool) -> crate::Result<()> {
self.window.dispatcher.set_decorations(decorations)
}
/// Determines if this window should be resizable.
pub fn set_resizable(&self, resizable: bool) -> crate::Result<()> {
self.window.dispatcher.set_resizable(resizable)
}
/// Determines if this window should always be on top of other windows.
pub fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()> {
self.window.dispatcher.set_always_on_top(always_on_top)
}
/// Set this window's title.
pub fn set_title(&self, title: &str) -> crate::Result<()> {
self.window.dispatcher.set_title(title.to_string())
}
/// Sets this window's width.
pub fn set_width(&self, width: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_width(width.into())
}
/// Maximizes this window.
pub fn maximize(&self) -> crate::Result<()> {
self.window.dispatcher.maximize()
}
/// Sets this window's height.
pub fn set_height(&self, height: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_height(height.into())
}
/// Un-maximizes this window.
pub fn unmaximize(&self) -> crate::Result<()> {
self.window.dispatcher.unmaximize()
}
/// Resizes this window.
pub fn resize(&self, width: impl Into<f64>, height: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.resize(width.into(), height.into())
}
/// Minimizes this window.
pub fn minimize(&self) -> crate::Result<()> {
self.window.dispatcher.minimize()
}
/// Sets this window's minimum size.
pub fn set_min_size(
&self,
min_width: impl Into<f64>,
min_height: impl Into<f64>,
) -> crate::Result<()> {
self
.window
.dispatcher
.set_min_size(min_width.into(), min_height.into())
}
/// Un-minimizes this window.
pub fn unminimize(&self) -> crate::Result<()> {
self.window.dispatcher.unminimize()
}
/// Sets this window's maximum size.
pub fn set_max_size(
&self,
max_width: impl Into<f64>,
max_height: impl Into<f64>,
) -> crate::Result<()> {
self
.window
.dispatcher
.set_max_size(max_width.into(), max_height.into())
}
/// Show this window.
pub fn show(&self) -> crate::Result<()> {
self.window.dispatcher.show()
}
/// Sets this window's x position.
pub fn set_x(&self, x: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_x(x.into())
}
/// Hide this window.
pub fn hide(&self) -> crate::Result<()> {
self.window.dispatcher.hide()
}
/// Sets this window's y position.
pub fn set_y(&self, y: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_y(y.into())
}
/// Closes this window.
pub fn close(&self) -> crate::Result<()> {
self.window.dispatcher.close()
}
/// Sets this window's position.
pub fn set_position(&self, x: impl Into<f64>, y: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_position(x.into(), y.into())
}
/// Determines if this window should be [decorated].
///
/// [decorated]: https://en.wikipedia.org/wiki/Window_(computing)#Window_decoration
pub fn set_decorations(&self, decorations: bool) -> crate::Result<()> {
self.window.dispatcher.set_decorations(decorations)
}
/// Determines if this window should be fullscreen.
pub fn set_fullscreen(&self, fullscreen: bool) -> crate::Result<()> {
self.window.dispatcher.set_fullscreen(fullscreen)
}
/// Determines if this window should always be on top of other windows.
pub fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()> {
self.window.dispatcher.set_always_on_top(always_on_top)
}
/// Sets this window' icon.
pub fn set_icon(&self, icon: Icon) -> crate::Result<()> {
self.window.dispatcher.set_icon(icon.try_into()?)
}
/// Sets this window's width.
pub fn set_width(&self, width: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_width(width.into())
}
pub(crate) fn verify_salt(&self, salt: String) -> bool {
self.manager.verify_salt(salt)
/// Sets this window's height.
pub fn set_height(&self, height: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_height(height.into())
}
/// Resizes this window.
pub fn resize(&self, width: impl Into<f64>, height: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.resize(width.into(), height.into())
}
/// Sets this window's minimum size.
pub fn set_min_size(
&self,
min_width: impl Into<f64>,
min_height: impl Into<f64>,
) -> crate::Result<()> {
self
.window
.dispatcher
.set_min_size(min_width.into(), min_height.into())
}
/// Sets this window's maximum size.
pub fn set_max_size(
&self,
max_width: impl Into<f64>,
max_height: impl Into<f64>,
) -> crate::Result<()> {
self
.window
.dispatcher
.set_max_size(max_width.into(), max_height.into())
}
/// Sets this window's x position.
pub fn set_x(&self, x: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_x(x.into())
}
/// Sets this window's y position.
pub fn set_y(&self, y: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_y(y.into())
}
/// Sets this window's position.
pub fn set_position(&self, x: impl Into<f64>, y: impl Into<f64>) -> crate::Result<()> {
self.window.dispatcher.set_position(x.into(), y.into())
}
/// Determines if this window should be fullscreen.
pub fn set_fullscreen(&self, fullscreen: bool) -> crate::Result<()> {
self.window.dispatcher.set_fullscreen(fullscreen)
}
/// Sets this window' icon.
pub fn set_icon(&self, icon: Icon) -> crate::Result<()> {
self.window.dispatcher.set_icon(icon.try_into()?)
}
pub(crate) fn verify_salt(&self, salt: String) -> bool {
self.manager.verify_salt(salt)
}
}
}

View File

@@ -8,14 +8,14 @@ use crate::{
config::UpdaterConfig,
dialog::{ask, AskResponse},
},
runtime::{window::Window, Params},
Params, Window,
};
// Check for new updates
pub const EVENT_CHECK_UPDATE: &str = "tauri://update";
// New update available
pub const EVENT_UPDATE_AVAILABLE: &str = "tauri://update-available";
// Used to intialize an update *should run check-update first (once you received the update available event)*
// Used to initialize an update *should run check-update first (once you received the update available event)*
pub const EVENT_INSTALL_UPDATE: &str = "tauri://update-install";
// Send updater status or error even if dialog is enabled, you should
// always listen for this event. It'll send you the install progress