Skip to content

Commit 46b6598

Browse files
vonPBamrbashir
andauthored
fix: target specific window for window events (#8826)
* fix: target specific window for CLOSE_REQUESTED_EVENT emission * fix: use emit_filter() instead of emit_to() * fix: try sending event regardless of existing js listener * cleanups * change file * emit_self -> emit_to_window --------- Co-authored-by: amrbashir <amr.bashir2015@gmail.com>
1 parent cf3e40c commit 46b6598

File tree

3 files changed

+56
-34
lines changed

3 files changed

+56
-34
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'tauri': 'patch:bug'
3+
---
4+
5+
Fix JS `onCloseRequested` catching close event from other windows.

core/tauri/src/lib.rs

+17-15
Original file line numberDiff line numberDiff line change
@@ -713,21 +713,23 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
713713
#[cfg(feature = "tracing")]
714714
tracing::Span::current().record("target", format!("{target:?}"));
715715

716-
self.manager().emit_filter(event, payload, |s| match s {
717-
t @ EventTarget::Window { label }
718-
| t @ EventTarget::Webview { label }
719-
| t @ EventTarget::WebviewWindow { label } => {
720-
if let EventTarget::AnyLabel {
721-
label: target_label,
722-
} = &target
723-
{
724-
label == target_label
725-
} else {
726-
t == &target
727-
}
728-
}
729-
t => t == &target,
730-
})
716+
match target {
717+
// if targeting all, emit to all using emit without filter
718+
EventTarget::Any => self.manager().emit(event, payload),
719+
720+
// if targeting any label, emit using emit_filter and filter labels
721+
EventTarget::AnyLabel {
722+
label: target_label,
723+
} => self.manager().emit_filter(event, payload, |t| match t {
724+
EventTarget::Window { label }
725+
| EventTarget::Webview { label }
726+
| EventTarget::WebviewWindow { label } => label == &target_label,
727+
_ => false,
728+
}),
729+
730+
// otherwise match same target
731+
_ => self.manager().emit_filter(event, payload, |t| t == &target),
732+
}
731733
}
732734

733735
/// Emits an event to all [targets](EventTarget) based on the given filter.

core/tauri/src/manager/window.rs

+34-19
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,27 @@ impl<R: Runtime> WindowManager<R> {
130130
}
131131
}
132132

133+
impl<R: Runtime> Window<R> {
134+
/// Emits event to [`EventTarget::Window`] and [`EventTarget::WebviewWindow`]
135+
fn emit_to_window<S: Serialize + Clone>(&self, event: &str, payload: S) -> crate::Result<()> {
136+
let window_label = self.label();
137+
self.emit_filter(event, payload, |target| match target {
138+
EventTarget::Window { label } | EventTarget::WebviewWindow { label } => label == window_label,
139+
_ => false,
140+
})
141+
}
142+
143+
/// Checks whether has js listener for [`EventTarget::Window`] or [`EventTarget::WebviewWindow`]
144+
fn has_js_listener(&self, event: &str) -> bool {
145+
let window_label = self.label();
146+
let listeners = self.manager().listeners();
147+
listeners.has_js_listener(event, |target| match target {
148+
EventTarget::Window { label } | EventTarget::WebviewWindow { label } => label == window_label,
149+
_ => false,
150+
})
151+
}
152+
}
153+
133154
#[derive(Serialize, Clone)]
134155
struct FileDropPayload<'a> {
135156
paths: &'a Vec<PathBuf>,
@@ -142,24 +163,16 @@ fn on_window_event<R: Runtime>(
142163
event: &WindowEvent,
143164
) -> crate::Result<()> {
144165
match event {
145-
WindowEvent::Resized(size) => window.emit(WINDOW_RESIZED_EVENT, size)?,
146-
WindowEvent::Moved(position) => window.emit(WINDOW_MOVED_EVENT, position)?,
166+
WindowEvent::Resized(size) => window.emit_to_window(WINDOW_RESIZED_EVENT, size)?,
167+
WindowEvent::Moved(position) => window.emit_to_window(WINDOW_MOVED_EVENT, position)?,
147168
WindowEvent::CloseRequested { api } => {
148-
let listeners = window.manager().listeners();
149-
let has_js_listener =
150-
listeners.has_js_listener(WINDOW_CLOSE_REQUESTED_EVENT, |target| match target {
151-
EventTarget::Window { label } | EventTarget::WebviewWindow { label } => {
152-
label == window.label()
153-
}
154-
_ => false,
155-
});
156-
if has_js_listener {
169+
if window.has_js_listener(WINDOW_CLOSE_REQUESTED_EVENT) {
157170
api.prevent_close();
158171
}
159-
window.emit(WINDOW_CLOSE_REQUESTED_EVENT, ())?;
172+
window.emit_to_window(WINDOW_CLOSE_REQUESTED_EVENT, ())?;
160173
}
161174
WindowEvent::Destroyed => {
162-
window.emit(WINDOW_DESTROYED_EVENT, ())?;
175+
window.emit_to_window(WINDOW_DESTROYED_EVENT, ())?;
163176
let label = window.label();
164177
let webviews_map = manager.webview.webviews_lock();
165178
let webviews = webviews_map.values();
@@ -169,7 +182,7 @@ fn on_window_event<R: Runtime>(
169182
))?;
170183
}
171184
}
172-
WindowEvent::Focused(focused) => window.emit(
185+
WindowEvent::Focused(focused) => window.emit_to_window(
173186
if *focused {
174187
WINDOW_FOCUS_EVENT
175188
} else {
@@ -181,7 +194,7 @@ fn on_window_event<R: Runtime>(
181194
scale_factor,
182195
new_inner_size,
183196
..
184-
} => window.emit(
197+
} => window.emit_to_window(
185198
WINDOW_SCALE_FACTOR_CHANGED_EVENT,
186199
ScaleFactorChanged {
187200
scale_factor: *scale_factor,
@@ -191,7 +204,7 @@ fn on_window_event<R: Runtime>(
191204
WindowEvent::FileDrop(event) => match event {
192205
FileDropEvent::Hovered { paths, position } => {
193206
let payload = FileDropPayload { paths, position };
194-
window.emit(WINDOW_FILE_DROP_HOVER_EVENT, payload)?
207+
window.emit_to_window(WINDOW_FILE_DROP_HOVER_EVENT, payload)?
195208
}
196209
FileDropEvent::Dropped { paths, position } => {
197210
let scopes = window.state::<Scopes>();
@@ -203,12 +216,14 @@ fn on_window_event<R: Runtime>(
203216
}
204217
}
205218
let payload = FileDropPayload { paths, position };
206-
window.emit(WINDOW_FILE_DROP_EVENT, payload)?
219+
window.emit_to_window(WINDOW_FILE_DROP_EVENT, payload)?
207220
}
208-
FileDropEvent::Cancelled => window.emit(WINDOW_FILE_DROP_CANCELLED_EVENT, ())?,
221+
FileDropEvent::Cancelled => window.emit_to_window(WINDOW_FILE_DROP_CANCELLED_EVENT, ())?,
209222
_ => unimplemented!(),
210223
},
211-
WindowEvent::ThemeChanged(theme) => window.emit(WINDOW_THEME_CHANGED, theme.to_string())?,
224+
WindowEvent::ThemeChanged(theme) => {
225+
window.emit_to_window(WINDOW_THEME_CHANGED, theme.to_string())?
226+
}
212227
}
213228
Ok(())
214229
}

0 commit comments

Comments
 (0)