mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-03 10:11:15 +02:00
refactor(tauri): expose all items meant to be public (#1454)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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>>>,
|
||||
}
|
||||
|
||||
|
||||
@@ -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()?;
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
/// }
|
||||
///
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user