mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-05 10:13:00 +02:00
refactor(core): update wry (#1242)
This commit is contained in:
committed by
GitHub
parent
ddcb70c8fe
commit
25e47e8f9b
@@ -32,7 +32,7 @@ thiserror = "1.0.23"
|
||||
once_cell = "1.5.2"
|
||||
tauri-api = { version = "0.7.5", path = "../tauri-api" }
|
||||
tauri-macros = { version = "0.1", path = "../tauri-macros" }
|
||||
wry = { git = "https://github.com/tauri-apps/wry", rev = "b36b3e2d07edddf2ef49dcc901ae2c5888873ad2" }
|
||||
wry = { git = "https://github.com/tauri-apps/wry", rev = "af07c28503e41a0a164cb7256fa0ec938d5daee4" }
|
||||
rand = "0.8"
|
||||
|
||||
[target."cfg(target_os = \"windows\")".dependencies]
|
||||
|
||||
2
tauri/examples/api/src-tauri/Cargo.lock
generated
2
tauri/examples/api/src-tauri/Cargo.lock
generated
@@ -3601,7 +3601,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.4.1"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=b36b3e2d07edddf2ef49dcc901ae2c5888873ad2#b36b3e2d07edddf2ef49dcc901ae2c5888873ad2"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=af07c28503e41a0a164cb7256fa0ec938d5daee4#af07c28503e41a0a164cb7256fa0ec938d5daee4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cocoa",
|
||||
|
||||
@@ -18,7 +18,7 @@ struct Context;
|
||||
fn main() {
|
||||
tauri::AppBuilder::<tauri::flavors::Wry, Context>::new()
|
||||
.setup(|webview_manager| async move {
|
||||
let dispatcher = webview_manager.current_webview().unwrap();
|
||||
let dispatcher = webview_manager.current_webview().await.unwrap();
|
||||
let dispatcher_ = dispatcher.clone();
|
||||
dispatcher.listen("js-event", move |msg| {
|
||||
println!("got js-event with message '{:?}'", msg);
|
||||
@@ -35,21 +35,16 @@ fn main() {
|
||||
use cmd::Cmd::*;
|
||||
match serde_json::from_str(&arg) {
|
||||
Err(e) => Err(e.into()),
|
||||
Ok(command) => {
|
||||
match command {
|
||||
LogOperation { event, payload } => {
|
||||
println!("{} {:?}", event, payload);
|
||||
Ok(serde_json::Value::Null)
|
||||
}
|
||||
PerformRequest {
|
||||
endpoint,
|
||||
body,
|
||||
} => {
|
||||
println!("{} {:?}", endpoint, body);
|
||||
Ok(serde_json::Value::String("message response".to_string()))
|
||||
}
|
||||
Ok(command) => match command {
|
||||
LogOperation { event, payload } => {
|
||||
println!("{} {:?}", event, payload);
|
||||
Ok(serde_json::Value::Null)
|
||||
}
|
||||
}
|
||||
PerformRequest { endpoint, body } => {
|
||||
println!("{} {:?}", endpoint, body);
|
||||
Ok(serde_json::Value::String("message response".to_string()))
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
.build()
|
||||
|
||||
@@ -3601,7 +3601,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.4.1"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=b36b3e2d07edddf2ef49dcc901ae2c5888873ad2#b36b3e2d07edddf2ef49dcc901ae2c5888873ad2"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=af07c28503e41a0a164cb7256fa0ec938d5daee4#af07c28503e41a0a164cb7256fa0ec938d5daee4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cocoa",
|
||||
|
||||
@@ -19,7 +19,7 @@ struct Context;
|
||||
fn main() {
|
||||
tauri::AppBuilder::<tauri::flavors::Wry, Context>::new()
|
||||
.setup(|webview_manager| async move {
|
||||
let dispatcher = webview_manager.current_webview().unwrap();
|
||||
let dispatcher = webview_manager.current_webview().await.unwrap();
|
||||
let dispatcher_ = dispatcher.clone();
|
||||
dispatcher.listen("js-event", move |msg| {
|
||||
println!("got js-event with message '{:?}'", msg);
|
||||
|
||||
2
tauri/examples/multiwindow/src-tauri/Cargo.lock
generated
2
tauri/examples/multiwindow/src-tauri/Cargo.lock
generated
@@ -3513,7 +3513,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.4.1"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=b36b3e2d07edddf2ef49dcc901ae2c5888873ad2#b36b3e2d07edddf2ef49dcc901ae2c5888873ad2"
|
||||
source = "git+https://github.com/tauri-apps/wry?rev=af07c28503e41a0a164cb7256fa0ec938d5daee4#af07c28503e41a0a164cb7256fa0ec938d5daee4"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cocoa",
|
||||
|
||||
@@ -15,7 +15,7 @@ fn main() {
|
||||
println!("got 'clicked' event on global channel");
|
||||
});
|
||||
}
|
||||
let current_webview = webview_manager.current_webview().unwrap().clone();
|
||||
let current_webview = webview_manager.current_webview().await.unwrap();
|
||||
let label = webview_manager.current_window_label().to_string();
|
||||
current_webview.listen("clicked", move |_| {
|
||||
println!("got 'clicked' event on window '{}'", label)
|
||||
|
||||
@@ -10,7 +10,7 @@ mod webview_manager;
|
||||
|
||||
pub use webview::{
|
||||
wry::WryApplication, ApplicationDispatcherExt, ApplicationExt, Callback, Icon, Message,
|
||||
WebviewBuilderExt, WindowBuilderExt,
|
||||
WebviewBuilderExt,
|
||||
};
|
||||
pub use webview_manager::{WebviewDispatcher, WebviewManager};
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ pub fn emit<D: ApplicationDispatcherExt, S: Serialize>(
|
||||
event.as_ref(),
|
||||
js_payload,
|
||||
salt
|
||||
));
|
||||
))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ use crate::{
|
||||
ApplicationExt, WebviewBuilderExt,
|
||||
};
|
||||
|
||||
use super::{App, ApplicationDispatcherExt, WebviewDispatcher, WebviewManager, WindowBuilderExt};
|
||||
use super::{App, ApplicationDispatcherExt, WebviewDispatcher, WebviewManager};
|
||||
#[cfg(embedded_server)]
|
||||
use crate::api::tcp::{get_available_port, port_is_available};
|
||||
use crate::app::Context;
|
||||
use crate::{app::Context, async_runtime::Mutex};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
@@ -287,11 +287,15 @@ fn build_webview<A: ApplicationExt + 'static>(
|
||||
|
||||
let mut webview_application = A::new()?;
|
||||
|
||||
let mut window_refs = Vec::new();
|
||||
let mut dispatchers = HashMap::new();
|
||||
let dispatchers = Arc::new(Mutex::new(HashMap::new()));
|
||||
let mut window_labels = Vec::new();
|
||||
|
||||
for window_config in &application.context.config.tauri.windows {
|
||||
window_labels.push(window_config.label.to_string());
|
||||
}
|
||||
|
||||
for window_config in application.context.config.tauri.windows.clone() {
|
||||
let mut window = A::WindowBuilder::new()
|
||||
let mut webview = A::WebviewBuilder::new()
|
||||
.title(window_config.title.to_string())
|
||||
.width(window_config.width)
|
||||
.height(window_config.height)
|
||||
@@ -303,34 +307,24 @@ fn build_webview<A: ApplicationExt + 'static>(
|
||||
.transparent(window_config.transparent)
|
||||
.always_on_top(window_config.always_on_top);
|
||||
if let Some(min_width) = window_config.min_width {
|
||||
window = window.min_width(min_width);
|
||||
webview = webview.min_width(min_width);
|
||||
}
|
||||
if let Some(min_height) = window_config.min_height {
|
||||
window = window.min_height(min_height);
|
||||
webview = webview.min_height(min_height);
|
||||
}
|
||||
if let Some(max_width) = window_config.max_width {
|
||||
window = window.max_width(max_width);
|
||||
webview = webview.max_width(max_width);
|
||||
}
|
||||
if let Some(max_height) = window_config.max_height {
|
||||
window = window.max_height(max_height);
|
||||
webview = webview.max_height(max_height);
|
||||
}
|
||||
if let Some(x) = window_config.x {
|
||||
window = window.x(x);
|
||||
webview = webview.x(x);
|
||||
}
|
||||
if let Some(y) = window_config.y {
|
||||
window = window.y(y);
|
||||
webview = webview.y(y);
|
||||
}
|
||||
|
||||
let window = webview_application.create_window(window)?;
|
||||
let dispatcher = webview_application.dispatcher(&window);
|
||||
dispatchers.insert(
|
||||
window_config.label.to_string(),
|
||||
WebviewDispatcher::new(dispatcher, window_config.label.to_string()),
|
||||
);
|
||||
window_refs.push((window_config, window));
|
||||
}
|
||||
|
||||
for (window_config, window) in window_refs {
|
||||
let webview_manager = WebviewManager::new(dispatchers.clone(), window_config.label.to_string());
|
||||
|
||||
let application = application.clone();
|
||||
@@ -371,9 +365,11 @@ fn build_webview<A: ApplicationExt + 'static>(
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
if let Ok(dispatcher) = webview_manager.current_webview() {
|
||||
if let Ok(dispatcher) =
|
||||
crate::async_runtime::block_on(webview_manager.current_webview())
|
||||
{
|
||||
let error: crate::Error = e.into();
|
||||
dispatcher.eval(&format!(
|
||||
let _ = dispatcher.eval(&format!(
|
||||
r#"console.error({})"#,
|
||||
JsonValue::String(error.to_string())
|
||||
));
|
||||
@@ -389,9 +385,7 @@ fn build_webview<A: ApplicationExt + 'static>(
|
||||
WindowUrl::Custom(url) => url.to_string(),
|
||||
};
|
||||
|
||||
webview_application.create_webview(
|
||||
A::WebviewBuilder::new()
|
||||
.url(webview_url)
|
||||
webview = webview.url(webview_url)
|
||||
.initialization_script(&initialization_script)
|
||||
.initialization_script(&format!(
|
||||
r#"
|
||||
@@ -399,12 +393,15 @@ fn build_webview<A: ApplicationExt + 'static>(
|
||||
window.__TAURI__.__currentWindow = {{ label: "{current_window_label}" }}
|
||||
"#,
|
||||
window_labels_array =
|
||||
serde_json::to_string(&dispatchers.keys().collect::<Vec<&String>>()).unwrap(),
|
||||
serde_json::to_string(&window_labels).unwrap(),
|
||||
current_window_label = window_config.label,
|
||||
)),
|
||||
window,
|
||||
vec![tauri_invoke_handler],
|
||||
)?;
|
||||
));
|
||||
|
||||
let dispatcher = webview_application.create_webview(webview, vec![tauri_invoke_handler])?;
|
||||
crate::async_runtime::block_on(dispatchers.lock()).insert(
|
||||
window_config.label.to_string(),
|
||||
WebviewDispatcher::new(dispatcher, window_config.label.to_string()),
|
||||
);
|
||||
|
||||
crate::async_runtime::spawn(async move {
|
||||
crate::plugin::created(A::plugin_store(), &webview_manager).await
|
||||
@@ -437,8 +434,8 @@ async fn execute_promise<
|
||||
Ok(callback_string) => callback_string,
|
||||
Err(e) => format_callback(error_callback, e.to_string()),
|
||||
};
|
||||
if let Ok(dispatcher) = webview_manager.current_webview() {
|
||||
dispatcher.eval(callback_string.as_str());
|
||||
if let Ok(dispatcher) = webview_manager.current_webview().await {
|
||||
let _ = dispatcher.eval(callback_string.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,20 @@ pub enum Message {
|
||||
SetIcon(Icon),
|
||||
}
|
||||
|
||||
/// The window builder.
|
||||
pub trait WindowBuilderExt: Sized {
|
||||
/// Initializes a new window builder.
|
||||
/// The webview builder.
|
||||
pub trait WebviewBuilderExt: Sized {
|
||||
/// The webview object that this builder creates.
|
||||
type Webview;
|
||||
|
||||
/// Initializes a new webview builder.
|
||||
fn new() -> Self;
|
||||
|
||||
/// Sets the webview url.
|
||||
fn url(self, url: String) -> Self;
|
||||
|
||||
/// Sets the init script.
|
||||
fn initialization_script(self, init: &str) -> Self;
|
||||
|
||||
/// The horizontal position of the window's top left corner.
|
||||
fn x(self, x: f64) -> Self;
|
||||
|
||||
@@ -133,21 +142,6 @@ pub trait WindowBuilderExt: Sized {
|
||||
|
||||
/// Whether the window should always be on top of other windows.
|
||||
fn always_on_top(self, always_on_top: bool) -> Self;
|
||||
}
|
||||
|
||||
/// The webview builder.
|
||||
pub trait WebviewBuilderExt: Sized {
|
||||
/// The webview object that this builder creates.
|
||||
type Webview;
|
||||
|
||||
/// Initializes a new webview builder.
|
||||
fn new() -> Self;
|
||||
|
||||
/// Sets the webview url.
|
||||
fn url(self, url: String) -> Self;
|
||||
|
||||
/// Sets the init script.
|
||||
fn initialization_script(self, init: &str) -> Self;
|
||||
|
||||
/// Builds the webview instance.
|
||||
fn finish(self) -> crate::Result<Self::Webview>;
|
||||
@@ -158,13 +152,76 @@ pub struct Callback<D> {
|
||||
/// Function name to bind.
|
||||
pub name: String,
|
||||
/// Function callback handler.
|
||||
pub function: Box<dyn FnMut(&D, i32, Vec<String>) -> i32 + Send>,
|
||||
pub function: Box<dyn FnMut(D, i32, Vec<String>) -> i32 + Send>,
|
||||
}
|
||||
|
||||
/// Webview dispatcher. A thread-safe handle to the webview API.
|
||||
pub trait ApplicationDispatcherExt: Clone + Send + Sync + Sized {
|
||||
/// Sends a message to the window.
|
||||
fn send_message(&self, message: Message);
|
||||
/// Updates the window resizable flag.
|
||||
fn set_resizable(&self, resizable: bool) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window title.
|
||||
fn set_title<S: Into<String>>(&self, title: S) -> crate::Result<()>;
|
||||
|
||||
/// Maximizes the window.
|
||||
fn maximize(&self) -> crate::Result<()>;
|
||||
|
||||
/// Unmaximizes the window.
|
||||
fn unmaximize(&self) -> crate::Result<()>;
|
||||
|
||||
/// Minimizes the window.
|
||||
fn minimize(&self) -> crate::Result<()>;
|
||||
|
||||
/// Unminimizes the window.
|
||||
fn unminimize(&self) -> crate::Result<()>;
|
||||
|
||||
/// Shows the window.
|
||||
fn show(&self) -> crate::Result<()>;
|
||||
|
||||
/// Hides the window.
|
||||
fn hide(&self) -> crate::Result<()>;
|
||||
|
||||
/// Updates the transparency flag.
|
||||
fn set_transparent(&self, resizable: bool) -> crate::Result<()>;
|
||||
|
||||
/// Updates the hasDecorations flag.
|
||||
fn set_decorations(&self, decorations: bool) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window alwaysOnTop flag.
|
||||
fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window width.
|
||||
fn set_width(&self, width: f64) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window height.
|
||||
fn set_height(&self, height: f64) -> crate::Result<()>;
|
||||
|
||||
/// Resizes the window.
|
||||
fn resize(&self, width: f64, height: f64) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window min size.
|
||||
fn set_min_size(&self, min_width: f64, min_height: f64) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window max size.
|
||||
fn set_max_size(&self, max_width: f64, max_height: f64) -> crate::Result<()>;
|
||||
|
||||
/// Updates the X position.
|
||||
fn set_x(&self, x: f64) -> crate::Result<()>;
|
||||
|
||||
/// Updates the Y position.
|
||||
fn set_y(&self, y: f64) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window position.
|
||||
fn set_position(&self, x: f64, y: f64) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window fullscreen state.
|
||||
fn set_fullscreen(&self, fullscreen: bool) -> crate::Result<()>;
|
||||
|
||||
/// Updates the window icon.
|
||||
fn set_icon(&self, icon: Icon) -> crate::Result<()>;
|
||||
|
||||
/// Evals a script on the webview.
|
||||
fn eval_script<S: Into<String>>(&self, script: S) -> crate::Result<()>;
|
||||
}
|
||||
|
||||
/// The application interface.
|
||||
@@ -172,10 +229,6 @@ pub trait ApplicationDispatcherExt: Clone + Send + Sync + Sized {
|
||||
pub trait ApplicationExt: Sized {
|
||||
/// The webview builder.
|
||||
type WebviewBuilder: WebviewBuilderExt;
|
||||
/// The window builder.
|
||||
type WindowBuilder: WindowBuilderExt;
|
||||
/// The window type.
|
||||
type Window;
|
||||
/// The message dispatcher.
|
||||
type Dispatcher: ApplicationDispatcherExt;
|
||||
|
||||
@@ -185,19 +238,12 @@ pub trait ApplicationExt: Sized {
|
||||
/// Creates a new application.
|
||||
fn new() -> crate::Result<Self>;
|
||||
|
||||
/// Gets the message dispatcher for the given window.
|
||||
fn dispatcher(&self, window: &Self::Window) -> Self::Dispatcher;
|
||||
|
||||
/// Creates a new window.
|
||||
fn create_window(&self, window_builder: Self::WindowBuilder) -> crate::Result<Self::Window>;
|
||||
|
||||
/// Creates a new webview.
|
||||
fn create_webview(
|
||||
&mut self,
|
||||
webview_builder: Self::WebviewBuilder,
|
||||
window: Self::Window,
|
||||
callbacks: Vec<Callback<Self::Dispatcher>>,
|
||||
) -> crate::Result<()>;
|
||||
) -> crate::Result<Self::Dispatcher>;
|
||||
|
||||
/// Run the application.
|
||||
fn run(self);
|
||||
|
||||
@@ -1,16 +1,11 @@
|
||||
use super::{
|
||||
ApplicationDispatcherExt, ApplicationExt, Callback, Icon, Message, WebviewBuilderExt,
|
||||
WindowBuilderExt,
|
||||
};
|
||||
|
||||
use wry::{ApplicationDispatcher, ApplicationExt as _, WebviewMessage, WindowExt, WindowMessage};
|
||||
use super::{ApplicationDispatcherExt, ApplicationExt, Callback, Icon, WebviewBuilderExt};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
use crate::plugin::PluginStore;
|
||||
|
||||
use std::{
|
||||
convert::{TryFrom, TryInto},
|
||||
convert::TryInto,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
@@ -29,11 +24,25 @@ impl TryInto<wry::Icon> for Icon {
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowBuilderExt for wry::AppWindowAttributes {
|
||||
/// The webview builder.
|
||||
impl WebviewBuilderExt for wry::WebViewAttributes {
|
||||
/// The webview object that this builder creates.
|
||||
type Webview = Self;
|
||||
|
||||
fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn url(mut self, url: String) -> Self {
|
||||
self.url.replace(url);
|
||||
self
|
||||
}
|
||||
|
||||
fn initialization_script(mut self, init: &str) -> Self {
|
||||
self.initialization_scripts.push(init.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
fn x(mut self, x: f64) -> Self {
|
||||
self.x = Some(x);
|
||||
self
|
||||
@@ -113,26 +122,6 @@ impl WindowBuilderExt for wry::AppWindowAttributes {
|
||||
self.always_on_top = always_on_top;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// The webview builder.
|
||||
impl WebviewBuilderExt for wry::WebViewAttributes {
|
||||
/// The webview object that this builder creates.
|
||||
type Webview = Self;
|
||||
|
||||
fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
|
||||
fn url(mut self, url: String) -> Self {
|
||||
self.url.replace(url);
|
||||
self
|
||||
}
|
||||
|
||||
fn initialization_script(mut self, init: &str) -> Self {
|
||||
self.initialization_script.push(init.to_string());
|
||||
self
|
||||
}
|
||||
|
||||
fn finish(self) -> crate::Result<Self::Webview> {
|
||||
Ok(self)
|
||||
@@ -140,101 +129,215 @@ impl WebviewBuilderExt for wry::WebViewAttributes {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct WryDispatcher {
|
||||
inner: Arc<Mutex<wry::AppDispatcher<()>>>,
|
||||
current_window: wry::WindowId,
|
||||
}
|
||||
|
||||
struct WryMessage(wry::Message<wry::WindowId, ()>);
|
||||
|
||||
impl TryFrom<(wry::WindowId, Message)> for WryMessage {
|
||||
type Error = crate::Error;
|
||||
fn try_from((id, message): (wry::WindowId, Message)) -> crate::Result<Self> {
|
||||
let message = match message {
|
||||
Message::EvalScript(js) => wry::Message::Webview(id, WebviewMessage::EvalScript(js)),
|
||||
Message::SetResizable(resizable) => {
|
||||
wry::Message::Window(id, WindowMessage::SetResizable(resizable))
|
||||
}
|
||||
Message::SetTitle(title) => wry::Message::Window(id, WindowMessage::SetTitle(title)),
|
||||
Message::Maximize => wry::Message::Window(id, WindowMessage::Maximize),
|
||||
Message::Unmaximize => wry::Message::Window(id, WindowMessage::Unmaximize),
|
||||
Message::Minimize => wry::Message::Window(id, WindowMessage::Minimize),
|
||||
Message::Unminimize => wry::Message::Window(id, WindowMessage::Unminimize),
|
||||
Message::Show => wry::Message::Window(id, WindowMessage::Show),
|
||||
Message::Hide => wry::Message::Window(id, WindowMessage::Hide),
|
||||
Message::SetTransparent(transparent) => {
|
||||
wry::Message::Window(id, WindowMessage::SetTransparent(transparent))
|
||||
}
|
||||
Message::SetDecorations(decorations) => {
|
||||
wry::Message::Window(id, WindowMessage::SetDecorations(decorations))
|
||||
}
|
||||
Message::SetAlwaysOnTop(always_on_top) => {
|
||||
wry::Message::Window(id, WindowMessage::SetAlwaysOnTop(always_on_top))
|
||||
}
|
||||
Message::SetWidth(width) => wry::Message::Window(id, WindowMessage::SetWidth(width)),
|
||||
Message::SetHeight(height) => wry::Message::Window(id, WindowMessage::SetHeight(height)),
|
||||
Message::Resize { width, height } => {
|
||||
wry::Message::Window(id, WindowMessage::Resize { width, height })
|
||||
}
|
||||
Message::SetMinSize {
|
||||
min_width,
|
||||
min_height,
|
||||
} => wry::Message::Window(
|
||||
id,
|
||||
WindowMessage::SetMinSize {
|
||||
min_width,
|
||||
min_height,
|
||||
},
|
||||
),
|
||||
Message::SetMaxSize {
|
||||
max_width,
|
||||
max_height,
|
||||
} => wry::Message::Window(
|
||||
id,
|
||||
WindowMessage::SetMaxSize {
|
||||
max_width,
|
||||
max_height,
|
||||
},
|
||||
),
|
||||
Message::SetX(x) => wry::Message::Window(id, WindowMessage::SetX(x)),
|
||||
Message::SetY(y) => wry::Message::Window(id, WindowMessage::SetY(y)),
|
||||
Message::SetPosition { x, y } => {
|
||||
wry::Message::Window(id, WindowMessage::SetPosition { x, y })
|
||||
}
|
||||
Message::SetFullscreen(fullscreen) => {
|
||||
wry::Message::Window(id, WindowMessage::SetFullscreen(fullscreen))
|
||||
}
|
||||
Message::SetIcon(icon) => wry::Message::Window(id, WindowMessage::SetIcon(icon.try_into()?)),
|
||||
};
|
||||
Ok(WryMessage(message))
|
||||
}
|
||||
}
|
||||
pub struct WryDispatcher(Arc<Mutex<wry::WindowDispatcher>>);
|
||||
|
||||
impl ApplicationDispatcherExt for WryDispatcher {
|
||||
fn send_message(&self, message: Message) {
|
||||
let message_res: crate::Result<WryMessage> = (self.current_window, message).try_into();
|
||||
// TODO error propagation
|
||||
if let Ok(message) = message_res {
|
||||
self
|
||||
.inner
|
||||
.lock()
|
||||
.unwrap()
|
||||
.dispatch_message(message.0)
|
||||
.unwrap();
|
||||
}
|
||||
fn set_resizable(&self, resizable: bool) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_resizable(resizable)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_title<S: Into<String>>(&self, title: S) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_title(title)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn maximize(&self) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.maximize()
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn unmaximize(&self) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.unmaximize()
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn minimize(&self) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.minimize()
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn unminimize(&self) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.unminimize()
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn show(&self) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.show()
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn hide(&self) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.hide()
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_transparent(&self, transparent: bool) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_transparent(transparent)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_decorations(&self, decorations: bool) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_decorations(decorations)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_always_on_top(always_on_top)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_width(&self, width: f64) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_width(width)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_height(&self, height: f64) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_height(height)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn resize(&self, width: f64, height: f64) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.resize(width, height)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_min_size(&self, min_width: f64, min_height: f64) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_min_size(min_width, min_height)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_max_size(&self, max_width: f64, max_height: f64) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_max_size(max_width, max_height)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_x(&self, x: f64) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_x(x)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_y(&self, y: f64) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_y(y)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_position(&self, x: f64, y: f64) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_position(x, y)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_fullscreen(&self, fullscreen: bool) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_fullscreen(fullscreen)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn set_icon(&self, icon: Icon) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_icon(icon.try_into()?)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
|
||||
fn eval_script<S: Into<String>>(&self, script: S) -> crate::Result<()> {
|
||||
self
|
||||
.0
|
||||
.lock()
|
||||
.unwrap()
|
||||
.eval_script(script)
|
||||
.map_err(|_| crate::Error::FailedToSendMessage)
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around the wry Application interface.
|
||||
pub struct WryApplication {
|
||||
inner: wry::Application<()>,
|
||||
dispatcher_handle: Arc<Mutex<wry::AppDispatcher<()>>>,
|
||||
inner: wry::Application,
|
||||
}
|
||||
|
||||
impl ApplicationExt for WryApplication {
|
||||
type WebviewBuilder = wry::WebViewAttributes;
|
||||
type WindowBuilder = wry::AppWindowAttributes;
|
||||
type Window = wry::Window;
|
||||
type Dispatcher = WryDispatcher;
|
||||
|
||||
fn plugin_store() -> &'static PluginStore<Self::Dispatcher> {
|
||||
@@ -244,61 +347,30 @@ impl ApplicationExt for WryApplication {
|
||||
|
||||
fn new() -> crate::Result<Self> {
|
||||
let app = wry::Application::new().map_err(|_| crate::Error::CreateWebview)?;
|
||||
let dispatcher = app.dispatcher();
|
||||
|
||||
Ok(Self {
|
||||
inner: app,
|
||||
dispatcher_handle: Arc::new(Mutex::new(dispatcher)),
|
||||
})
|
||||
}
|
||||
|
||||
fn dispatcher(&self, window: &Self::Window) -> Self::Dispatcher {
|
||||
WryDispatcher {
|
||||
inner: self.dispatcher_handle.clone(),
|
||||
current_window: window.id(),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_window(&self, window_builder: Self::WindowBuilder) -> crate::Result<Self::Window> {
|
||||
let window = self
|
||||
.inner
|
||||
.create_window(window_builder)
|
||||
.map_err(|_| crate::Error::CreateWindow)?;
|
||||
Ok(window)
|
||||
Ok(Self { inner: app })
|
||||
}
|
||||
|
||||
fn create_webview(
|
||||
&mut self,
|
||||
webview_builder: Self::WebviewBuilder,
|
||||
window: Self::Window,
|
||||
callbacks: Vec<Callback<Self::Dispatcher>>,
|
||||
) -> crate::Result<()> {
|
||||
) -> crate::Result<Self::Dispatcher> {
|
||||
let mut wry_callbacks = Vec::new();
|
||||
for mut callback in callbacks {
|
||||
let dispatcher_handle = self.dispatcher_handle.clone();
|
||||
let window_id = window.id();
|
||||
|
||||
let callback = wry::Callback {
|
||||
name: callback.name.to_string(),
|
||||
function: Box::new(move |_, seq, req| {
|
||||
(callback.function)(
|
||||
&WryDispatcher {
|
||||
inner: dispatcher_handle.clone(),
|
||||
current_window: window_id,
|
||||
},
|
||||
seq,
|
||||
req,
|
||||
)
|
||||
function: Box::new(move |dispatcher, seq, req| {
|
||||
(callback.function)(WryDispatcher(Arc::new(Mutex::new(dispatcher))), seq, req)
|
||||
}),
|
||||
};
|
||||
wry_callbacks.push(callback);
|
||||
}
|
||||
|
||||
self
|
||||
let dispatcher = self
|
||||
.inner
|
||||
.create_webview(window, webview_builder.finish()?, Some(wry_callbacks))
|
||||
.create_webview(webview_builder.finish()?, Some(wry_callbacks))
|
||||
.map_err(|_| crate::Error::CreateWebview)?;
|
||||
Ok(())
|
||||
Ok(WryDispatcher(Arc::new(Mutex::new(dispatcher))))
|
||||
}
|
||||
|
||||
fn run(self) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use super::{ApplicationDispatcherExt, Icon, Message};
|
||||
use super::{ApplicationDispatcherExt, Icon};
|
||||
use crate::async_runtime::Mutex;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
@@ -48,182 +49,165 @@ impl<A: ApplicationDispatcherExt> WebviewDispatcher<A> {
|
||||
}
|
||||
|
||||
/// Evaluates a JS script.
|
||||
pub fn eval(&self, js: &str) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::EvalScript(js.to_string()))
|
||||
pub fn eval(&self, js: &str) -> crate::Result<()> {
|
||||
self.dispatcher.eval_script(js)
|
||||
}
|
||||
|
||||
/// Updates the window resizable flag.
|
||||
pub fn set_resizable(&self, resizable: bool) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::SetResizable(resizable))
|
||||
pub fn set_resizable(&self, resizable: bool) -> crate::Result<()> {
|
||||
self.dispatcher.set_resizable(resizable)
|
||||
}
|
||||
|
||||
/// Updates the window title.
|
||||
pub fn set_title(&self, title: &str) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::SetTitle(title.to_string()))
|
||||
pub fn set_title(&self, title: &str) -> crate::Result<()> {
|
||||
self.dispatcher.set_title(title.to_string())
|
||||
}
|
||||
|
||||
/// Maximizes the window.
|
||||
pub fn maximize(&self) {
|
||||
self.dispatcher.send_message(Message::Maximize)
|
||||
pub fn maximize(&self) -> crate::Result<()> {
|
||||
self.dispatcher.maximize()
|
||||
}
|
||||
|
||||
/// Unmaximizes the window.
|
||||
pub fn unmaximize(&self) {
|
||||
self.dispatcher.send_message(Message::Unmaximize)
|
||||
pub fn unmaximize(&self) -> crate::Result<()> {
|
||||
self.dispatcher.unmaximize()
|
||||
}
|
||||
|
||||
/// Minimizes the window.
|
||||
pub fn minimize(&self) {
|
||||
self.dispatcher.send_message(Message::Minimize)
|
||||
pub fn minimize(&self) -> crate::Result<()> {
|
||||
self.dispatcher.minimize()
|
||||
}
|
||||
|
||||
/// Unminimizes the window.
|
||||
pub fn unminimize(&self) {
|
||||
self.dispatcher.send_message(Message::Unminimize)
|
||||
pub fn unminimize(&self) -> crate::Result<()> {
|
||||
self.dispatcher.unminimize()
|
||||
}
|
||||
|
||||
/// Sets the window visibility to true.
|
||||
pub fn show(&self) {
|
||||
self.dispatcher.send_message(Message::Show)
|
||||
pub fn show(&self) -> crate::Result<()> {
|
||||
self.dispatcher.show()
|
||||
}
|
||||
|
||||
/// Sets the window visibility to false.
|
||||
pub fn hide(&self) {
|
||||
self.dispatcher.send_message(Message::Hide)
|
||||
pub fn hide(&self) -> crate::Result<()> {
|
||||
self.dispatcher.hide()
|
||||
}
|
||||
|
||||
/// Sets the window transparent flag.
|
||||
pub fn set_transparent(&self, transparent: bool) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::SetTransparent(transparent))
|
||||
pub fn set_transparent(&self, transparent: bool) -> crate::Result<()> {
|
||||
self.dispatcher.set_transparent(transparent)
|
||||
}
|
||||
|
||||
/// Whether the window should have borders and bars.
|
||||
pub fn set_decorations(&self, decorations: bool) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::SetDecorations(decorations))
|
||||
pub fn set_decorations(&self, decorations: bool) -> crate::Result<()> {
|
||||
self.dispatcher.set_decorations(decorations)
|
||||
}
|
||||
|
||||
/// Whether the window should always be on top of other windows.
|
||||
pub fn set_always_on_top(&self, always_on_top: bool) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::SetAlwaysOnTop(always_on_top))
|
||||
pub fn set_always_on_top(&self, always_on_top: bool) -> crate::Result<()> {
|
||||
self.dispatcher.set_always_on_top(always_on_top)
|
||||
}
|
||||
|
||||
/// Sets the window width.
|
||||
pub fn set_width(&self, width: impl Into<f64>) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::SetWidth(width.into()))
|
||||
pub fn set_width(&self, width: impl Into<f64>) -> crate::Result<()> {
|
||||
self.dispatcher.set_width(width.into())
|
||||
}
|
||||
|
||||
/// Sets the window height.
|
||||
pub fn set_height(&self, height: impl Into<f64>) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::SetHeight(height.into()))
|
||||
pub fn set_height(&self, height: impl Into<f64>) -> crate::Result<()> {
|
||||
self.dispatcher.set_height(height.into())
|
||||
}
|
||||
|
||||
/// Resizes the window.
|
||||
pub fn resize(&self, width: impl Into<f64>, height: impl Into<f64>) {
|
||||
self.dispatcher.send_message(Message::Resize {
|
||||
width: width.into(),
|
||||
height: height.into(),
|
||||
})
|
||||
pub fn resize(&self, width: impl Into<f64>, height: impl Into<f64>) -> crate::Result<()> {
|
||||
self.dispatcher.resize(width.into(), height.into())
|
||||
}
|
||||
|
||||
/// Sets the window min size.
|
||||
pub fn set_min_size(&self, min_width: impl Into<f64>, min_height: impl Into<f64>) {
|
||||
self.dispatcher.send_message(Message::SetMinSize {
|
||||
min_width: min_width.into(),
|
||||
min_height: min_height.into(),
|
||||
})
|
||||
pub fn set_min_size(
|
||||
&self,
|
||||
min_width: impl Into<f64>,
|
||||
min_height: impl Into<f64>,
|
||||
) -> crate::Result<()> {
|
||||
self
|
||||
.dispatcher
|
||||
.set_min_size(min_width.into(), min_height.into())
|
||||
}
|
||||
|
||||
/// Sets the window max size.
|
||||
pub fn set_max_size(&self, max_width: impl Into<f64>, max_height: impl Into<f64>) {
|
||||
self.dispatcher.send_message(Message::SetMaxSize {
|
||||
max_width: max_width.into(),
|
||||
max_height: max_height.into(),
|
||||
})
|
||||
pub fn set_max_size(
|
||||
&self,
|
||||
max_width: impl Into<f64>,
|
||||
max_height: impl Into<f64>,
|
||||
) -> crate::Result<()> {
|
||||
self
|
||||
.dispatcher
|
||||
.set_max_size(max_width.into(), max_height.into())
|
||||
}
|
||||
|
||||
/// Sets the window x position.
|
||||
pub fn set_x(&self, x: impl Into<f64>) {
|
||||
self.dispatcher.send_message(Message::SetX(x.into()))
|
||||
pub fn set_x(&self, x: impl Into<f64>) -> crate::Result<()> {
|
||||
self.dispatcher.set_x(x.into())
|
||||
}
|
||||
|
||||
/// Sets the window y position.
|
||||
pub fn set_y(&self, y: impl Into<f64>) {
|
||||
self.dispatcher.send_message(Message::SetY(y.into()))
|
||||
pub fn set_y(&self, y: impl Into<f64>) -> crate::Result<()> {
|
||||
self.dispatcher.set_y(y.into())
|
||||
}
|
||||
|
||||
/// Sets the window position.
|
||||
pub fn set_position(&self, x: impl Into<f64>, y: impl Into<f64>) {
|
||||
self.dispatcher.send_message(Message::SetPosition {
|
||||
x: x.into(),
|
||||
y: y.into(),
|
||||
})
|
||||
pub fn set_position(&self, x: impl Into<f64>, y: impl Into<f64>) -> crate::Result<()> {
|
||||
self.dispatcher.set_position(x.into(), y.into())
|
||||
}
|
||||
|
||||
/// Sets the window fullscreen state.
|
||||
pub fn set_fullscreen(&self, fullscreen: bool) {
|
||||
self
|
||||
.dispatcher
|
||||
.send_message(Message::SetFullscreen(fullscreen))
|
||||
pub fn set_fullscreen(&self, fullscreen: bool) -> crate::Result<()> {
|
||||
self.dispatcher.set_fullscreen(fullscreen)
|
||||
}
|
||||
|
||||
/// Sets the window icon.
|
||||
pub fn set_icon(&self, icon: Icon) {
|
||||
self.dispatcher.send_message(Message::SetIcon(icon))
|
||||
pub fn set_icon(&self, icon: Icon) -> crate::Result<()> {
|
||||
self.dispatcher.set_icon(icon)
|
||||
}
|
||||
}
|
||||
|
||||
/// The webview manager.
|
||||
#[derive(Clone)]
|
||||
pub struct WebviewManager<A: Clone> {
|
||||
dispatchers: HashMap<String, WebviewDispatcher<A>>,
|
||||
dispatchers: Arc<Mutex<HashMap<String, WebviewDispatcher<A>>>>,
|
||||
current_webview_window_label: String,
|
||||
}
|
||||
|
||||
impl<A: ApplicationDispatcherExt> WebviewManager<A> {
|
||||
pub(crate) fn new(dispatchers: HashMap<String, WebviewDispatcher<A>>, label: String) -> Self {
|
||||
pub(crate) fn new(
|
||||
dispatchers: Arc<Mutex<HashMap<String, WebviewDispatcher<A>>>>,
|
||||
label: String,
|
||||
) -> Self {
|
||||
Self {
|
||||
dispatchers,
|
||||
current_webview_window_label: label,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the map of the current webviews.
|
||||
pub fn webviews(&self) -> &HashMap<String, WebviewDispatcher<A>> {
|
||||
&self.dispatchers
|
||||
}
|
||||
|
||||
/// Returns the label of the window associated with the current context.
|
||||
pub fn current_window_label(&self) -> &str {
|
||||
&self.current_webview_window_label
|
||||
}
|
||||
|
||||
/// Gets the webview associated with the current context.
|
||||
pub fn current_webview(&self) -> crate::Result<&WebviewDispatcher<A>> {
|
||||
self.get_webview(&self.current_webview_window_label)
|
||||
pub async fn current_webview(&self) -> crate::Result<WebviewDispatcher<A>> {
|
||||
self.get_webview(&self.current_webview_window_label).await
|
||||
}
|
||||
|
||||
/// Gets the webview associated with the given window label.
|
||||
pub fn get_webview(&self, window_label: &str) -> crate::Result<&WebviewDispatcher<A>> {
|
||||
pub async fn get_webview(&self, window_label: &str) -> crate::Result<WebviewDispatcher<A>> {
|
||||
self
|
||||
.dispatchers
|
||||
.lock()
|
||||
.await
|
||||
.get(window_label)
|
||||
.ok_or(crate::Error::WebviewNotFound)
|
||||
.map(|d| d.clone())
|
||||
}
|
||||
|
||||
/// Listen to a global event.
|
||||
@@ -237,12 +221,12 @@ impl<A: ApplicationDispatcherExt> WebviewManager<A> {
|
||||
}
|
||||
|
||||
/// Emits an event to all webviews.
|
||||
pub fn emit<S: Serialize + Clone>(
|
||||
pub async fn emit<S: Serialize + Clone>(
|
||||
&self,
|
||||
event: impl AsRef<str>,
|
||||
payload: Option<S>,
|
||||
) -> crate::Result<()> {
|
||||
for dispatcher in self.dispatchers.values() {
|
||||
for dispatcher in self.dispatchers.lock().await.values() {
|
||||
super::event::emit(&dispatcher, event.as_ref(), payload.clone())?;
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -36,7 +36,7 @@ impl Cmd {
|
||||
once,
|
||||
} => {
|
||||
let js_string = listen_fn(event, handler, once)?;
|
||||
webview_manager.current_webview()?.eval(&js_string);
|
||||
webview_manager.current_webview().await?.eval(&js_string)?;
|
||||
Ok(JsonValue::Null)
|
||||
}
|
||||
Self::Emit {
|
||||
@@ -45,7 +45,7 @@ impl Cmd {
|
||||
payload,
|
||||
} => {
|
||||
if let Some(label) = window_label {
|
||||
let dispatcher = webview_manager.get_webview(&label)?;
|
||||
let dispatcher = webview_manager.get_webview(&label).await?;
|
||||
// dispatch the event to Rust listeners
|
||||
dispatcher.on_event(event.to_string(), payload.clone());
|
||||
// dispatch the event to JS listeners
|
||||
@@ -54,7 +54,7 @@ impl Cmd {
|
||||
// dispatch the event to Rust listeners
|
||||
webview_manager.on_event(event.to_string(), payload.clone());
|
||||
// dispatch the event to JS listeners
|
||||
webview_manager.emit(event, payload)?;
|
||||
webview_manager.emit(event, payload).await?;
|
||||
}
|
||||
Ok(JsonValue::Null)
|
||||
}
|
||||
|
||||
@@ -34,12 +34,12 @@ impl Cmd {
|
||||
#[cfg(global_shortcut)]
|
||||
match self {
|
||||
Self::Register { shortcut, handler } => {
|
||||
let dispatcher = webview_manager.current_webview()?.clone();
|
||||
let dispatcher = webview_manager.current_webview().await?.clone();
|
||||
let mut manager = manager_handle().lock().await;
|
||||
manager.register_shortcut(shortcut, move || {
|
||||
let callback_string =
|
||||
crate::api::rpc::format_callback(handler.to_string(), serde_json::Value::Null);
|
||||
dispatcher.eval(callback_string.as_str());
|
||||
let _ = dispatcher.eval(callback_string.as_str());
|
||||
})?;
|
||||
Ok(JsonValue::Null)
|
||||
}
|
||||
|
||||
@@ -90,35 +90,37 @@ impl Cmd {
|
||||
if cfg!(not(window)) {
|
||||
Err(crate::Error::ApiNotAllowlisted("setTitle".to_string()))
|
||||
} else {
|
||||
let current_webview = webview_manager.current_webview()?;
|
||||
let current_webview = webview_manager.current_webview().await?;
|
||||
match self {
|
||||
Self::SetResizable { resizable } => current_webview.set_resizable(resizable),
|
||||
Self::SetTitle { title } => current_webview.set_title(&title),
|
||||
Self::Maximize => current_webview.maximize(),
|
||||
Self::Unmaximize => current_webview.unmaximize(),
|
||||
Self::Minimize => current_webview.minimize(),
|
||||
Self::Unminimize => current_webview.unminimize(),
|
||||
Self::Show => current_webview.show(),
|
||||
Self::Hide => current_webview.hide(),
|
||||
Self::SetTransparent { transparent } => current_webview.set_transparent(transparent),
|
||||
Self::SetDecorations { decorations } => current_webview.set_decorations(decorations),
|
||||
Self::SetAlwaysOnTop { always_on_top } => current_webview.set_always_on_top(always_on_top),
|
||||
Self::SetWidth { width } => current_webview.set_width(width),
|
||||
Self::SetHeight { height } => current_webview.set_height(height),
|
||||
Self::Resize { width, height } => current_webview.resize(width, height),
|
||||
Self::SetResizable { resizable } => current_webview.set_resizable(resizable)?,
|
||||
Self::SetTitle { title } => current_webview.set_title(&title)?,
|
||||
Self::Maximize => current_webview.maximize()?,
|
||||
Self::Unmaximize => current_webview.unmaximize()?,
|
||||
Self::Minimize => current_webview.minimize()?,
|
||||
Self::Unminimize => current_webview.unminimize()?,
|
||||
Self::Show => current_webview.show()?,
|
||||
Self::Hide => current_webview.hide()?,
|
||||
Self::SetTransparent { transparent } => current_webview.set_transparent(transparent)?,
|
||||
Self::SetDecorations { decorations } => current_webview.set_decorations(decorations)?,
|
||||
Self::SetAlwaysOnTop { always_on_top } => {
|
||||
current_webview.set_always_on_top(always_on_top)?
|
||||
}
|
||||
Self::SetWidth { width } => current_webview.set_width(width)?,
|
||||
Self::SetHeight { height } => current_webview.set_height(height)?,
|
||||
Self::Resize { width, height } => current_webview.resize(width, height)?,
|
||||
Self::SetMinSize {
|
||||
min_width,
|
||||
min_height,
|
||||
} => current_webview.set_min_size(min_width, min_height),
|
||||
} => current_webview.set_min_size(min_width, min_height)?,
|
||||
Self::SetMaxSize {
|
||||
max_width,
|
||||
max_height,
|
||||
} => current_webview.set_max_size(max_width, max_height),
|
||||
Self::SetX { x } => current_webview.set_x(x),
|
||||
Self::SetY { y } => current_webview.set_y(y),
|
||||
Self::SetPosition { x, y } => current_webview.set_position(x, y),
|
||||
Self::SetFullscreen { fullscreen } => current_webview.set_fullscreen(fullscreen),
|
||||
Self::SetIcon { icon } => current_webview.set_icon(icon.into()),
|
||||
} => current_webview.set_max_size(max_width, max_height)?,
|
||||
Self::SetX { x } => current_webview.set_x(x)?,
|
||||
Self::SetY { y } => current_webview.set_y(y)?,
|
||||
Self::SetPosition { x, y } => current_webview.set_position(x, y)?,
|
||||
Self::SetFullscreen { fullscreen } => current_webview.set_fullscreen(fullscreen)?,
|
||||
Self::SetIcon { icon } => current_webview.set_icon(icon.into())?,
|
||||
}
|
||||
Ok(JsonValue::Null)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@ pub enum Error {
|
||||
/// Can't access webview dispatcher because the webview was closed or not found.
|
||||
#[error("webview not found: invalid label or it was closed")]
|
||||
WebviewNotFound,
|
||||
/// Failed to send message to webview.
|
||||
#[error("failed to send message to the webview")]
|
||||
FailedToSendMessage,
|
||||
/// Embedded asset not found.
|
||||
#[error("asset not found: {0}")]
|
||||
AssetNotFound(String),
|
||||
|
||||
Reference in New Issue
Block a user