mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-12-28 21:45:00 +03:00
refactor(core): simplify usage of app event and window label types (#1623)
Co-authored-by: chip reed <chip@chip.sh>
This commit is contained in:
parent
af6411d5f8
commit
181e132aee
5
.changes/simplify-tag-label-usage.md
Normal file
5
.changes/simplify-tag-label-usage.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": patch
|
||||
---
|
||||
|
||||
Simplify usage of app event and window label types.
|
@ -52,12 +52,12 @@ impl Cmd {
|
||||
});
|
||||
|
||||
// dispatch the event to Rust listeners
|
||||
window.trigger(e.clone(), payload.clone());
|
||||
window.trigger(&e, payload.clone());
|
||||
|
||||
if let Some(target) = window_label {
|
||||
window.emit_to(&target, e, payload)?;
|
||||
window.emit_to(&target, &e, payload)?;
|
||||
} else {
|
||||
window.emit_all(e, payload)?;
|
||||
window.emit_all(&e, payload)?;
|
||||
}
|
||||
Ok(().into())
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ struct WindowCreatedEvent {
|
||||
|
||||
impl Cmd {
|
||||
#[allow(dead_code)]
|
||||
pub async fn run<M: Params>(self, window: Window<M>) -> crate::Result<InvokeResponse> {
|
||||
pub async fn run<P: Params>(self, window: Window<P>) -> crate::Result<InvokeResponse> {
|
||||
if cfg!(not(window_all)) {
|
||||
Err(crate::Error::ApiNotAllowlisted("window > all".to_string()))
|
||||
} else {
|
||||
@ -114,7 +114,7 @@ impl Cmd {
|
||||
Self::CreateWebview { options } => {
|
||||
let mut window = window;
|
||||
// Panic if the user's `Tag` type decided to return an error while parsing.
|
||||
let label: M::Label = options.label.parse().unwrap_or_else(|_| {
|
||||
let label: P::Label = options.label.parse().unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"Window module received unknown window label: {}",
|
||||
options.label
|
||||
@ -124,13 +124,15 @@ impl Cmd {
|
||||
let url = options.url.clone();
|
||||
let pending =
|
||||
crate::runtime::window::PendingWindow::with_config(options, label.clone(), url);
|
||||
window.create_window(pending)?.emit_others_internal(
|
||||
"tauri://window-created".to_string(),
|
||||
|
||||
window.create_window(pending)?.emit_others(
|
||||
&crate::runtime::manager::tauri_event::<P::Event>("tauri://window-created"),
|
||||
Some(WindowCreatedEvent {
|
||||
label: label.to_string(),
|
||||
}),
|
||||
)?;
|
||||
}
|
||||
|
||||
Self::SetResizable { resizable } => window.set_resizable(resizable)?,
|
||||
Self::SetTitle { title } => window.set_title(&title)?,
|
||||
Self::Maximize => window.maximize()?,
|
||||
|
@ -2,8 +2,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::runtime::tag::Tag;
|
||||
use crate::runtime::tag::{Tag, TagRef};
|
||||
use std::{
|
||||
borrow::Borrow,
|
||||
boxed::Box,
|
||||
collections::HashMap,
|
||||
fmt,
|
||||
@ -134,7 +135,7 @@ impl<Event: Tag, Window: Tag> Listeners<Event, Window> {
|
||||
match action {
|
||||
Pending::Unlisten(id) => self.unlisten(id),
|
||||
Pending::Listen(id, event, handler) => self.listen_(id, event, handler),
|
||||
Pending::Trigger(event, window, payload) => self.trigger(event, window, payload),
|
||||
Pending::Trigger(ref event, window, payload) => self.trigger(event, window, payload),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -191,12 +192,16 @@ impl<Event: Tag, Window: Tag> Listeners<Event, Window> {
|
||||
}
|
||||
|
||||
/// Triggers the given global event with its payload.
|
||||
pub(crate) fn trigger(&self, event: Event, window: Option<Window>, payload: Option<String>) {
|
||||
pub(crate) fn trigger<E>(&self, event: &E, window: Option<Window>, payload: Option<String>)
|
||||
where
|
||||
E: TagRef<Event> + ?Sized,
|
||||
Event: Borrow<E>,
|
||||
{
|
||||
let mut maybe_pending = false;
|
||||
match self.inner.handlers.try_lock() {
|
||||
Err(_) => self.insert_pending(Pending::Trigger(event, window, payload)),
|
||||
Err(_) => self.insert_pending(Pending::Trigger(event.to_owned(), window, payload)),
|
||||
Ok(lock) => {
|
||||
if let Some(handlers) = lock.get(&event) {
|
||||
if let Some(handlers) = lock.get(event) {
|
||||
for (&id, handler) in handlers {
|
||||
if window.is_none() || window == handler.window {
|
||||
maybe_pending = true;
|
||||
@ -280,7 +285,7 @@ mod test {
|
||||
// call listen with e and the event_fn dummy func
|
||||
listeners.listen(e.clone(), None, event_fn);
|
||||
// call on event with e and d.
|
||||
listeners.trigger(e, None, Some(d));
|
||||
listeners.trigger(&e, None, Some(d));
|
||||
|
||||
// lock the mutex
|
||||
let l = listeners.inner.handlers.lock().unwrap();
|
||||
|
@ -39,7 +39,7 @@ pub type SyncTask = Box<dyn FnOnce() + Send>;
|
||||
use crate::api::assets::Assets;
|
||||
use crate::api::config::Config;
|
||||
use crate::event::{Event, EventHandler};
|
||||
use crate::runtime::tag::Tag;
|
||||
use crate::runtime::tag::{Tag, TagRef};
|
||||
use crate::runtime::window::PendingWindow;
|
||||
use crate::runtime::{Dispatch, Runtime};
|
||||
use serde::Serialize;
|
||||
@ -51,10 +51,12 @@ pub use {
|
||||
api::config::WindowUrl,
|
||||
hooks::{InvokeHandler, InvokeMessage, OnPageLoad, PageLoadPayload, SetupHook},
|
||||
runtime::app::{App, Builder},
|
||||
runtime::flavors::wry::Wry,
|
||||
runtime::webview::Attributes,
|
||||
runtime::window::export::Window,
|
||||
};
|
||||
|
||||
use std::borrow::Borrow;
|
||||
/// 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
|
||||
@ -130,31 +132,39 @@ pub trait Params: sealed::ParamsBase {
|
||||
/// Manages a running application.
|
||||
///
|
||||
/// TODO: expand these docs
|
||||
pub trait Manager<M: Params>: sealed::ManagerBase<M> {
|
||||
pub trait Manager<P: Params>: sealed::ManagerBase<P> {
|
||||
/// 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<()> {
|
||||
fn emit_all<E, S>(&self, event: &E, payload: Option<S>) -> Result<()>
|
||||
where
|
||||
E: TagRef<P::Event> + ?Sized,
|
||||
S: Serialize + Clone,
|
||||
{
|
||||
self.manager().emit_filter(event, payload, |_| true)
|
||||
}
|
||||
|
||||
/// Emits an event to a window with the specified label.
|
||||
fn emit_to<S: Serialize + Clone>(
|
||||
fn emit_to<E, L, S: Serialize + Clone>(
|
||||
&self,
|
||||
label: &M::Label,
|
||||
event: M::Event,
|
||||
label: &L,
|
||||
event: &E,
|
||||
payload: Option<S>,
|
||||
) -> Result<()> {
|
||||
) -> Result<()>
|
||||
where
|
||||
L: TagRef<P::Label> + ?Sized,
|
||||
E: TagRef<P::Event> + ?Sized,
|
||||
{
|
||||
self
|
||||
.manager()
|
||||
.emit_filter(event, payload, |w| w.label() == label)
|
||||
.emit_filter(event, payload, |w| label == w.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>> {
|
||||
fn create_window(&mut self, pending: PendingWindow<P>) -> Result<Window<P>> {
|
||||
use sealed::RuntimeOrDispatch::*;
|
||||
|
||||
let labels = self.manager().labels().into_iter().collect::<Vec<_>>();
|
||||
@ -167,23 +177,27 @@ pub trait Manager<M: Params>: sealed::ManagerBase<M> {
|
||||
}
|
||||
|
||||
/// Listen to a global event.
|
||||
fn listen_global<F>(&self, event: M::Event, handler: F) -> EventHandler
|
||||
fn listen_global<E: Into<P::Event>, F>(&self, event: E, handler: F) -> EventHandler
|
||||
where
|
||||
F: Fn(Event) + Send + 'static,
|
||||
{
|
||||
self.manager().listen(event, None, handler)
|
||||
self.manager().listen(event.into(), None, handler)
|
||||
}
|
||||
|
||||
/// Listen to a global event only once.
|
||||
fn once_global<F>(&self, event: M::Event, handler: F) -> EventHandler
|
||||
fn once_global<E: Into<P::Event>, F>(&self, event: E, handler: F) -> EventHandler
|
||||
where
|
||||
F: Fn(Event) + Send + 'static,
|
||||
{
|
||||
self.manager().once(event, None, handler)
|
||||
self.manager().once(event.into(), None, handler)
|
||||
}
|
||||
|
||||
/// Trigger a global event.
|
||||
fn trigger_global(&self, event: M::Event, data: Option<String>) {
|
||||
fn trigger_global<E>(&self, event: &E, data: Option<String>)
|
||||
where
|
||||
E: TagRef<P::Event> + ?Sized,
|
||||
P::Event: Borrow<E>,
|
||||
{
|
||||
self.manager().trigger(event, None, data)
|
||||
}
|
||||
|
||||
@ -193,12 +207,16 @@ pub trait Manager<M: Params>: sealed::ManagerBase<M> {
|
||||
}
|
||||
|
||||
/// Fetch a single window from the manager.
|
||||
fn get_window(&self, label: &M::Label) -> Option<Window<M>> {
|
||||
fn get_window<L>(&self, label: &L) -> Option<Window<P>>
|
||||
where
|
||||
L: TagRef<P::Label> + ?Sized,
|
||||
P::Label: Borrow<L>,
|
||||
{
|
||||
self.manager().get_window(label)
|
||||
}
|
||||
|
||||
/// Fetch all managed windows.
|
||||
fn windows(&self) -> HashMap<M::Label, Window<M>> {
|
||||
fn windows(&self) -> HashMap<P::Label, Window<P>> {
|
||||
self.manager().windows()
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ impl<M: Params> App<M> {
|
||||
// invoke the Event `tauri://update` from JS or rust side.
|
||||
main_window.listen(
|
||||
updater::EVENT_CHECK_UPDATE
|
||||
.parse()
|
||||
.parse::<M::Event>()
|
||||
.unwrap_or_else(|_| panic!("bad label")),
|
||||
move |_msg| {
|
||||
let window = event_window.clone();
|
||||
|
@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::runtime::tag::TagRef;
|
||||
use crate::{
|
||||
api::{
|
||||
assets::Assets,
|
||||
@ -13,7 +14,7 @@ use crate::{
|
||||
hooks::{InvokeHandler, InvokeMessage, InvokePayload, OnPageLoad, PageLoadPayload},
|
||||
plugin::PluginStore,
|
||||
runtime::{
|
||||
tag::{tags_to_javascript_array, Tag, ToJavascript},
|
||||
tag::{tags_to_javascript_array, Tag, ToJsString},
|
||||
webview::{Attributes, CustomProtocol, FileDropEvent, FileDropHandler, WebviewRpcHandler},
|
||||
window::{DetachedWindow, PendingWindow},
|
||||
Dispatch, Icon, Runtime,
|
||||
@ -23,6 +24,7 @@ use crate::{
|
||||
};
|
||||
use serde::Serialize;
|
||||
use serde_json::Value as JsonValue;
|
||||
use std::borrow::Borrow;
|
||||
use std::marker::PhantomData;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
@ -33,6 +35,20 @@ use std::{
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
/// Parse a string representing an internal tauri event into [`Params::Event`]
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This will panic if the `FromStr` implementation of [`Params::Event`] returns an error.
|
||||
pub(crate) fn tauri_event<Event: Tag>(tauri_event: &str) -> Event {
|
||||
tauri_event.parse().unwrap_or_else(|_| {
|
||||
panic!(
|
||||
"failed to parse internal tauri event into Params::Event: {}",
|
||||
tauri_event
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub struct InnerWindowManager<P: Params> {
|
||||
windows: Mutex<HashMap<P::Label, Window<P>>>,
|
||||
plugins: Mutex<PluginStore<P>>,
|
||||
@ -168,7 +184,7 @@ impl<P: Params> WindowManager<P> {
|
||||
window.__TAURI__.__currentWindow = {{ label: {current_window_label} }}
|
||||
"#,
|
||||
window_labels_array = tags_to_javascript_array(pending_labels)?,
|
||||
current_window_label = label.to_javascript()?,
|
||||
current_window_label = label.to_js_string()?,
|
||||
));
|
||||
|
||||
if !attributes.has_icon() {
|
||||
@ -281,14 +297,16 @@ impl<P: Params> WindowManager<P> {
|
||||
let window = manager.attach_window(window);
|
||||
let _ = match event {
|
||||
FileDropEvent::Hovered(paths) => {
|
||||
window.emit_internal("tauri://file-drop".to_string(), Some(paths))
|
||||
}
|
||||
FileDropEvent::Dropped(paths) => {
|
||||
window.emit_internal("tauri://file-drop-hover".to_string(), Some(paths))
|
||||
}
|
||||
FileDropEvent::Cancelled => {
|
||||
window.emit_internal("tauri://file-drop-cancelled".to_string(), Some(()))
|
||||
window.emit_internal(&tauri_event::<P::Event>("tauri://file-drop"), Some(paths))
|
||||
}
|
||||
FileDropEvent::Dropped(paths) => window.emit_internal(
|
||||
&tauri_event::<P::Event>("tauri://file-drop-hover"),
|
||||
Some(paths),
|
||||
),
|
||||
FileDropEvent::Cancelled => window.emit_internal(
|
||||
&tauri_event::<P::Event>("tauri://file-drop-cancelled"),
|
||||
Some(()),
|
||||
),
|
||||
};
|
||||
});
|
||||
true
|
||||
@ -474,30 +492,20 @@ impl<P: Params> WindowManager<P> {
|
||||
|
||||
window
|
||||
}
|
||||
pub fn emit_filter_internal<S: Serialize + Clone, F: Fn(&Window<P>) -> bool>(
|
||||
&self,
|
||||
event: String,
|
||||
payload: Option<S>,
|
||||
filter: F,
|
||||
) -> crate::Result<()> {
|
||||
|
||||
pub fn emit_filter<E, S, F>(&self, event: &E, payload: Option<S>, filter: F) -> crate::Result<()>
|
||||
where
|
||||
E: TagRef<P::Event> + ?Sized,
|
||||
S: Serialize + Clone,
|
||||
F: Fn(&Window<P>) -> bool,
|
||||
{
|
||||
self
|
||||
.windows_lock()
|
||||
.values()
|
||||
.filter(|&w| filter(w))
|
||||
.try_for_each(|window| window.emit_internal(event.clone(), payload.clone()))
|
||||
}
|
||||
pub fn emit_filter<S: Serialize + Clone, F: Fn(&Window<P>) -> bool>(
|
||||
&self,
|
||||
event: P::Event,
|
||||
payload: Option<S>,
|
||||
filter: F,
|
||||
) -> crate::Result<()> {
|
||||
self
|
||||
.windows_lock()
|
||||
.values()
|
||||
.filter(|&w| filter(w))
|
||||
.try_for_each(|window| window.emit(&event, payload.clone()))
|
||||
.try_for_each(|window| window.emit(event, payload.clone()))
|
||||
}
|
||||
|
||||
pub fn labels(&self) -> HashSet<P::Label> {
|
||||
self.windows_lock().keys().cloned().collect()
|
||||
}
|
||||
@ -510,9 +518,15 @@ impl<P: Params> WindowManager<P> {
|
||||
pub fn unlisten(&self, handler_id: EventHandler) {
|
||||
self.inner.listeners.unlisten(handler_id)
|
||||
}
|
||||
pub fn trigger(&self, event: P::Event, window: Option<P::Label>, data: Option<String>) {
|
||||
|
||||
pub fn trigger<E>(&self, event: &E, window: Option<P::Label>, data: Option<String>)
|
||||
where
|
||||
E: TagRef<P::Event> + ?Sized,
|
||||
P::Event: Borrow<E>,
|
||||
{
|
||||
self.inner.listeners.trigger(event, window, data)
|
||||
}
|
||||
|
||||
pub fn listen<F: Fn(Event) + Send + 'static>(
|
||||
&self,
|
||||
event: P::Event,
|
||||
@ -563,9 +577,15 @@ impl<P: Params> WindowManager<P> {
|
||||
.expect("poisoned salt mutex")
|
||||
.remove(&uuid)
|
||||
}
|
||||
pub fn get_window(&self, label: &P::Label) -> Option<Window<P>> {
|
||||
|
||||
pub fn get_window<L>(&self, label: &L) -> Option<Window<P>>
|
||||
where
|
||||
L: TagRef<P::Label> + ?Sized,
|
||||
P::Label: Borrow<L>,
|
||||
{
|
||||
self.windows_lock().get(label).cloned()
|
||||
}
|
||||
|
||||
pub fn windows(&self) -> HashMap<P::Label, Window<P>> {
|
||||
self.windows_lock().clone()
|
||||
}
|
||||
|
@ -85,6 +85,20 @@ impl<T, E: Debug> Tag for T where
|
||||
{
|
||||
}
|
||||
|
||||
/// A reference to a [`Tag`].
|
||||
///
|
||||
/// * [`Display`] so that we can still convert this tag to a JavaScript string.
|
||||
/// * [`ToOwned`] to make sure we can clone it into the owned tag in specific cases.
|
||||
/// * [`PartialEq`] so that we can compare refs to the owned tags easily.
|
||||
/// * [`Hash`] + [`Eq`] because we want to be able to use a ref as a key to internal hashmaps.
|
||||
pub trait TagRef<T: Tag>: Display + ToOwned<Owned = T> + PartialEq<T> + Eq + Hash {}
|
||||
|
||||
/// Automatically implement [`TagRef`] for all types that fit the requirements.
|
||||
impl<T: Tag, R> TagRef<T> for R where
|
||||
R: Display + ToOwned<Owned = T> + PartialEq<T> + Eq + Hash + ?Sized
|
||||
{
|
||||
}
|
||||
|
||||
/// Private helper to turn [`Tag`] related things into JavaScript, safely.
|
||||
///
|
||||
/// The main concern is string escaping, so we rely on [`serde_json`] to handle all serialization
|
||||
@ -93,13 +107,13 @@ impl<T, E: Debug> Tag for T where
|
||||
///
|
||||
/// We don't want downstream users to implement this trait so that [`Tag`]s cannot be turned into
|
||||
/// invalid JavaScript - regardless of their content.
|
||||
pub(crate) trait ToJavascript {
|
||||
fn to_javascript(&self) -> crate::Result<String>;
|
||||
pub(crate) trait ToJsString {
|
||||
fn to_js_string(&self) -> crate::Result<String>;
|
||||
}
|
||||
|
||||
impl<T: Tag> ToJavascript for T {
|
||||
impl<D: Display> ToJsString for D {
|
||||
/// Turn any [`Tag`] into the JavaScript representation of a string.
|
||||
fn to_javascript(&self) -> crate::Result<String> {
|
||||
fn to_js_string(&self) -> crate::Result<String> {
|
||||
Ok(serde_json::to_string(&self.to_string())?)
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use crate::{
|
||||
event::{Event, EventHandler},
|
||||
hooks::{InvokeMessage, InvokePayload, PageLoadPayload},
|
||||
runtime::{
|
||||
tag::ToJavascript,
|
||||
tag::ToJsString,
|
||||
webview::{FileDropHandler, WebviewRpcHandler},
|
||||
Dispatch, Runtime,
|
||||
},
|
||||
@ -107,7 +107,8 @@ impl<M: Params> PartialEq for 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::*;
|
||||
use crate::runtime::manager::WindowManager;
|
||||
use crate::runtime::{manager::WindowManager, tag::TagRef};
|
||||
use std::borrow::Borrow;
|
||||
|
||||
/// A webview window managed by Tauri.
|
||||
///
|
||||
@ -195,11 +196,11 @@ pub(crate) mod export {
|
||||
&self.window.label
|
||||
}
|
||||
|
||||
pub(crate) fn emit_internal<E: ToJavascript, S: Serialize>(
|
||||
&self,
|
||||
event: E,
|
||||
payload: Option<S>,
|
||||
) -> crate::Result<()> {
|
||||
pub(crate) fn emit_internal<E, S>(&self, event: &E, payload: Option<S>) -> crate::Result<()>
|
||||
where
|
||||
E: TagRef<P::Event> + ?Sized,
|
||||
S: Serialize,
|
||||
{
|
||||
let js_payload = match payload {
|
||||
Some(payload_value) => serde_json::to_value(payload_value)?,
|
||||
None => JsonValue::Null,
|
||||
@ -208,7 +209,7 @@ pub(crate) mod export {
|
||||
self.eval(&format!(
|
||||
"window['{}']({{event: {}, payload: {}}}, '{}')",
|
||||
self.manager.event_emit_function_name(),
|
||||
event.to_javascript()?,
|
||||
event.to_js_string()?,
|
||||
js_payload,
|
||||
self.manager.generate_salt(),
|
||||
))?;
|
||||
@ -217,50 +218,47 @@ pub(crate) mod export {
|
||||
}
|
||||
|
||||
/// Emits an event to the current window.
|
||||
pub fn emit<S: Serialize>(&self, event: &P::Event, payload: Option<S>) -> crate::Result<()> {
|
||||
self.emit_internal(event.clone(), payload)
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
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)
|
||||
pub fn emit<E, S>(&self, event: &E, payload: Option<S>) -> crate::Result<()>
|
||||
where
|
||||
E: TagRef<P::Event> + ?Sized,
|
||||
S: Serialize,
|
||||
{
|
||||
self.emit_internal(event, payload)
|
||||
}
|
||||
|
||||
/// Emits an event on all windows except this one.
|
||||
pub fn emit_others<S: Serialize + Clone>(
|
||||
pub fn emit_others<E: TagRef<P::Event> + ?Sized, S: Serialize + Clone>(
|
||||
&self,
|
||||
event: P::Event,
|
||||
event: &E,
|
||||
payload: Option<S>,
|
||||
) -> crate::Result<()> {
|
||||
self.manager.emit_filter(event, payload, |w| w != self)
|
||||
}
|
||||
|
||||
/// Listen to an event on this window.
|
||||
pub fn listen<F>(&self, event: P::Event, handler: F) -> EventHandler
|
||||
pub fn listen<E: Into<P::Event>, F>(&self, event: E, handler: F) -> EventHandler
|
||||
where
|
||||
F: Fn(Event) + Send + 'static,
|
||||
{
|
||||
let label = self.window.label.clone();
|
||||
self.manager.listen(event, Some(label), handler)
|
||||
self.manager.listen(event.into(), Some(label), handler)
|
||||
}
|
||||
|
||||
/// Listen to a an event on this window a single time.
|
||||
pub fn once<F>(&self, event: P::Event, handler: F) -> EventHandler
|
||||
pub fn once<E: Into<P::Event>, F>(&self, event: E, handler: F) -> EventHandler
|
||||
where
|
||||
F: Fn(Event) + Send + 'static,
|
||||
{
|
||||
let label = self.window.label.clone();
|
||||
self.manager.once(event, Some(label), handler)
|
||||
self.manager.once(event.into(), Some(label), handler)
|
||||
}
|
||||
|
||||
/// Triggers an event on this window.
|
||||
pub fn trigger(&self, event: P::Event, data: Option<String>) {
|
||||
pub fn trigger<E>(&self, event: &E, data: Option<String>)
|
||||
where
|
||||
E: TagRef<P::Event> + ?Sized,
|
||||
P::Event: Borrow<E>,
|
||||
{
|
||||
let label = self.window.label.clone();
|
||||
self.manager.trigger(event, Some(label), data)
|
||||
}
|
||||
|
@ -339,6 +339,7 @@ mod error;
|
||||
|
||||
pub use self::error::Error;
|
||||
|
||||
use crate::runtime::manager::tauri_event;
|
||||
use crate::{
|
||||
api::{
|
||||
app::restart_application,
|
||||
@ -434,7 +435,7 @@ pub(crate) fn listener<M: Params>(
|
||||
// Wait to receive the event `"tauri://update"`
|
||||
window.listen(
|
||||
EVENT_CHECK_UPDATE
|
||||
.parse()
|
||||
.parse::<M::Event>()
|
||||
.unwrap_or_else(|_| panic!("bad label")),
|
||||
move |_msg| {
|
||||
let window = isolated_window.clone();
|
||||
@ -468,9 +469,7 @@ pub(crate) fn listener<M: Params>(
|
||||
|
||||
// Emit `tauri://update-available`
|
||||
let _ = window.emit(
|
||||
&EVENT_UPDATE_AVAILABLE
|
||||
.parse()
|
||||
.unwrap_or_else(|_| panic!("bad label")),
|
||||
&tauri_event::<M::Event>(EVENT_UPDATE_AVAILABLE),
|
||||
Some(UpdateManifest {
|
||||
body,
|
||||
date: updater.date.clone(),
|
||||
@ -481,7 +480,7 @@ pub(crate) fn listener<M: Params>(
|
||||
// Listen for `tauri://update-install`
|
||||
window.once(
|
||||
EVENT_INSTALL_UPDATE
|
||||
.parse()
|
||||
.parse::<M::Event>()
|
||||
.unwrap_or_else(|_| panic!("bad label")),
|
||||
move |_msg| {
|
||||
let window = window_isolation.clone();
|
||||
@ -524,8 +523,8 @@ pub(crate) fn listener<M: Params>(
|
||||
|
||||
// Send a status update via `tauri://update-status` event.
|
||||
fn send_status_update<M: Params>(window: Window<M>, status: &str, error: Option<String>) {
|
||||
let _ = window.emit_internal(
|
||||
EVENT_STATUS_UPDATE.to_string(),
|
||||
let _ = window.emit(
|
||||
&tauri_event::<M::Event>(EVENT_STATUS_UPDATE),
|
||||
Some(StatusEvent {
|
||||
error,
|
||||
status: String::from(status),
|
||||
|
@ -20,14 +20,14 @@ fn main() {
|
||||
tauri::Builder::default()
|
||||
.on_page_load(|window, _| {
|
||||
let window_ = window.clone();
|
||||
window.listen("js-event".into(), move |event| {
|
||||
window.listen("js-event", move |event| {
|
||||
println!("got js-event with message '{:?}'", event.payload());
|
||||
let reply = Reply {
|
||||
data: "something else".to_string(),
|
||||
};
|
||||
|
||||
window_
|
||||
.emit(&"rust-event".into(), Some(reply))
|
||||
.emit("rust-event", Some(reply))
|
||||
.expect("failed to emit");
|
||||
});
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user