Skip to content

Commit eeb6be5

Browse files
feat(core): Manager::emit_filter and optimize serialization (#7512)
Co-authored-by: Lucas Nogueira <lucas@tauri.studio>
1 parent a6b52e4 commit eeb6be5

4 files changed

Lines changed: 57 additions & 13 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'tauri': 'minor:feat'
3+
---
4+
5+
Add `tauri::Manager::emit_filter` and only serialize once when emitting to multiple windows.

core/tauri/src/lib.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
610610
self.manager().config()
611611
}
612612

613-
/// Emits a event to all windows.
613+
/// Emits an event to all windows.
614614
///
615615
/// Only the webviews receives this event.
616616
/// To trigger Rust listeners, use [`Self::trigger_global`], [`Window::trigger`] or [`Window::emit_and_trigger`].
@@ -629,6 +629,26 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
629629
self.manager().emit_filter(event, None, payload, |_| true)
630630
}
631631

632+
/// Emits an event to windows matching the filter critera.
633+
///
634+
/// # Examples
635+
/// ```
636+
/// use tauri::Manager;
637+
///
638+
/// #[tauri::command]
639+
/// fn synchronize(app: tauri::AppHandle) {
640+
/// // emits the synchronized event to all windows
641+
/// app.emit_filter("synchronized", (), |w| w.label().starts_with("foo-"));
642+
/// }
643+
/// ```
644+
fn emit_filter<S, F>(&self, event: &str, payload: S, filter: F) -> Result<()>
645+
where
646+
S: Serialize + Clone,
647+
F: Fn(&Window<R>) -> bool,
648+
{
649+
self.manager().emit_filter(event, None, payload, filter)
650+
}
651+
632652
/// Emits an event to the window with the specified label.
633653
///
634654
/// # Examples

core/tauri/src/manager.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use tauri_utils::{
2525
html::{SCRIPT_NONCE_TOKEN, STYLE_NONCE_TOKEN},
2626
};
2727

28-
use crate::app::{GlobalMenuEventListener, WindowMenuEvent};
2928
use crate::hooks::IpcJavascript;
3029
#[cfg(feature = "isolation")]
3130
use crate::hooks::IsolationJavascript;
@@ -51,6 +50,10 @@ use crate::{
5150
Context, EventLoopMessage, Icon, Invoke, Manager, Pattern, Runtime, Scopes, StateManager, Window,
5251
WindowEvent,
5352
};
53+
use crate::{
54+
app::{GlobalMenuEventListener, WindowMenuEvent},
55+
window::WindowEmitArgs,
56+
};
5457

5558
#[cfg(any(target_os = "linux", target_os = "windows"))]
5659
use crate::api::path::{resolve_path, BaseDirectory};
@@ -1102,12 +1105,13 @@ impl<R: Runtime> WindowManager<R> {
11021105
S: Serialize + Clone,
11031106
F: Fn(&Window<R>) -> bool,
11041107
{
1108+
let emit_args = WindowEmitArgs::from(event, source_window_label, payload)?;
11051109
assert_event_name_is_valid(event);
11061110
self
1107-
.windows_lock()
1111+
.windows()
11081112
.values()
11091113
.filter(|&w| filter(w))
1110-
.try_for_each(|window| window.emit_internal(event, source_window_label, payload.clone()))
1114+
.try_for_each(|window| window.emit_internal(&emit_args))
11111115
}
11121116

11131117
pub fn eval_script_all<S: Into<String>>(&self, script: S) -> crate::Result<()> {

core/tauri/src/window.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ struct WindowCreatedEvent {
5656
label: String,
5757
}
5858

59+
pub(crate) struct WindowEmitArgs {
60+
pub event: String,
61+
pub source_window_label: String,
62+
pub payload: String,
63+
}
64+
65+
impl WindowEmitArgs {
66+
pub fn from<S: Serialize>(
67+
event: &str,
68+
source_window_label: Option<&str>,
69+
payload: S,
70+
) -> crate::Result<Self> {
71+
Ok(WindowEmitArgs {
72+
event: serde_json::to_string(event)?,
73+
source_window_label: serde_json::to_string(&source_window_label)?,
74+
payload: serde_json::to_string(&payload)?,
75+
})
76+
}
77+
}
78+
5979
/// Monitor descriptor.
6080
#[derive(Debug, Clone, Serialize)]
6181
#[serde(rename_all = "camelCase")]
@@ -1764,18 +1784,13 @@ impl<R: Runtime> Window<R> {
17641784
self.emit(event, payload)
17651785
}
17661786

1767-
pub(crate) fn emit_internal<S: Serialize>(
1768-
&self,
1769-
event: &str,
1770-
source_window_label: Option<&str>,
1771-
payload: S,
1772-
) -> crate::Result<()> {
1787+
pub(crate) fn emit_internal(&self, emit_args: &WindowEmitArgs) -> crate::Result<()> {
17731788
self.eval(&format!(
17741789
"(function () {{ const fn = window['{}']; fn && fn({{event: {}, windowLabel: {}, payload: {}}}) }})()",
17751790
self.manager.event_emit_function_name(),
1776-
serde_json::to_string(event)?,
1777-
serde_json::to_string(&source_window_label)?,
1778-
serde_json::to_value(payload)?,
1791+
emit_args.event,
1792+
emit_args.source_window_label,
1793+
emit_args.payload
17791794
))?;
17801795
Ok(())
17811796
}

0 commit comments

Comments
 (0)