Skip to content

Commit

Permalink
fix(core): immediately listen to window-created, closes #3297 (#3298)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Feb 5, 2022
1 parent 2bade5e commit 878b8b9
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 65 deletions.
5 changes: 5 additions & 0 deletions .changes/fix-window-created-listen.md
@@ -0,0 +1,5 @@
---
"tauri": patch
---

Immediately listen to `tauri://window-created` event to catch it before the application triggers it.
17 changes: 5 additions & 12 deletions core/tauri/scripts/core.js
Expand Up @@ -150,18 +150,11 @@
}
})

window.__TAURI_INVOKE__('tauri', {
__tauriModule: 'Event',
message: {
cmd: 'listen',
event: 'tauri://window-created',
handler: window.__TAURI__.transformCallback(function (event) {
if (event.payload) {
var windowLabel = event.payload.label
window.__TAURI_METADATA__.__windows.push({
label: windowLabel
})
}
listen('tauri://window-created', function (event) {
if (event.payload) {
var windowLabel = event.payload.label
window.__TAURI_METADATA__.__windows.push({
label: windowLabel
})
}
})
Expand Down
2 changes: 2 additions & 0 deletions core/tauri/scripts/init.js
Expand Up @@ -9,6 +9,8 @@
__RAW_bundle_script__
})()

__RAW_listen_function__

__RAW_core_script__

__RAW_event_initialization_script__
Expand Down
4 changes: 2 additions & 2 deletions core/tauri/src/app.rs
Expand Up @@ -1156,7 +1156,7 @@ impl<R: Runtime> Builder<R> {

app.manager.initialize_plugins(&app.handle())?;

let pending_labels = self
let window_labels = self
.pending_windows
.iter()
.map(|p| p.label.clone())
Expand All @@ -1168,7 +1168,7 @@ impl<R: Runtime> Builder<R> {
for pending in self.pending_windows {
let pending = app
.manager
.prepare_window(app.handle.clone(), pending, &pending_labels)?;
.prepare_window(app.handle.clone(), pending, &window_labels)?;
let detached = app.runtime.as_ref().unwrap().create_window(pending)?;
let _window = app.manager.attach_window(app.handle(), detached);
#[cfg(feature = "updater")]
Expand Down
59 changes: 12 additions & 47 deletions core/tauri/src/endpoints/event.rs
Expand Up @@ -4,7 +4,11 @@

use super::InvokeContext;
use crate::{
api::ipc::CallbackFn, event::is_event_name_valid, sealed::ManagerBase, Manager, Runtime, Window,
api::ipc::CallbackFn,
event::is_event_name_valid,
event::{listen_js, unlisten_js},
sealed::ManagerBase,
Manager, Runtime,
};
use serde::{de::Deserializer, Deserialize};
use tauri_macros::CommandModule;
Expand Down Expand Up @@ -54,19 +58,20 @@ impl Cmd {
) -> crate::Result<u64> {
let event_id = rand::random();
context.window.eval(&listen_js(
&context.window,
event.0.clone(),
context.window.manager().event_listeners_object_name(),
format!("'{}'", event.0),
event_id,
handler,
format!("window['_{}']", handler.0),
))?;
context.window.register_js_listener(event.0, event_id);
Ok(event_id)
}

fn unlisten<R: Runtime>(context: InvokeContext<R>, event_id: u64) -> crate::Result<()> {
context
.window
.eval(&unlisten_js(&context.window, event_id))?;
context.window.eval(&unlisten_js(
context.window.manager().event_listeners_object_name(),
event_id,
))?;
context.window.unregister_js_listener(event_id);
Ok(())
}
Expand All @@ -88,43 +93,3 @@ impl Cmd {
Ok(())
}
}

pub fn unlisten_js<R: Runtime>(window: &Window<R>, event_id: u64) -> String {
format!(
"
for (var event in (window['{listeners}'] || {{}})) {{
var listeners = (window['{listeners}'] || {{}})[event]
if (listeners) {{
window['{listeners}'][event] = window['{listeners}'][event].filter(function (e) {{ return e.id !== {event_id} }})
}}
}}
",
listeners = window.manager().event_listeners_object_name(),
event_id = event_id,
)
}

pub fn listen_js<R: Runtime>(
window: &Window<R>,
event: String,
event_id: u64,
handler: CallbackFn,
) -> String {
format!(
"if (window['{listeners}'] === void 0) {{
window['{listeners}'] = Object.create(null)
}}
if (window['{listeners}']['{event}'] === void 0) {{
window['{listeners}']['{event}'] = []
}}
window['{listeners}']['{event}'].push({{
id: {event_id},
handler: window['_{handler}']
}});
",
listeners = window.manager().event_listeners_object_name(),
event = event,
event_id = event_id,
handler = handler.0
)
}
40 changes: 40 additions & 0 deletions core/tauri/src/event.rs
Expand Up @@ -286,3 +286,43 @@ mod test {
}
}
}

pub fn unlisten_js(listeners_object_name: String, event_id: u64) -> String {
format!(
"
for (var event in (window['{listeners}'] || {{}})) {{
var listeners = (window['{listeners}'] || {{}})[event]
if (listeners) {{
window['{listeners}'][event] = window['{listeners}'][event].filter(function (e) {{ return e.id !== {event_id} }})
}}
}}
",
listeners = listeners_object_name,
event_id = event_id,
)
}

pub fn listen_js(
listeners_object_name: String,
event: String,
event_id: u64,
handler: String,
) -> String {
format!(
"if (window['{listeners}'] === void 0) {{
window['{listeners}'] = Object.create(null)
}}
if (window['{listeners}'][{event}] === void 0) {{
window['{listeners}'][{event}] = []
}}
window['{listeners}'][{event}].push({{
id: {event_id},
handler: {handler}
}});
",
listeners = listeners_object_name,
event = event,
event_id = event_id,
handler = handler
)
}
25 changes: 21 additions & 4 deletions core/tauri/src/manager.rs
Expand Up @@ -395,7 +395,7 @@ impl<R: Runtime> WindowManager<R> {
&self,
mut pending: PendingWindow<R>,
label: &str,
pending_labels: &[String],
window_labels: &[String],
app_handle: AppHandle<R>,
) -> crate::Result<PendingWindow<R>> {
let is_init_global = self.inner.config.build.with_global_tauri;
Expand All @@ -422,6 +422,11 @@ impl<R: Runtime> WindowManager<R> {

let mut webview_attributes = pending.webview_attributes;

let mut window_labels = window_labels.to_vec();
let l = label.to_string();
if !window_labels.contains(&l) {
window_labels.push(l);
}
webview_attributes = webview_attributes
.initialization_script(&self.inner.invoke_initialization_script)
.initialization_script(&format!(
Expand All @@ -433,7 +438,7 @@ impl<R: Runtime> WindowManager<R> {
}}
}})
"#,
window_labels_array = serde_json::to_string(pending_labels)?,
window_labels_array = serde_json::to_string(&window_labels)?,
current_window_label = serde_json::to_string(&label)?,
))
.initialization_script(&self.initialization_script(&ipc_init,&pattern_init,&plugin_init, is_init_global)?)
Expand Down Expand Up @@ -809,6 +814,9 @@ impl<R: Runtime> WindowManager<R> {
ipc_script: &'a str,
#[raw]
bundle_script: &'a str,
// A function to immediately listen to an event.
#[raw]
listen_function: &'a str,
#[raw]
core_script: &'a str,
#[raw]
Expand Down Expand Up @@ -836,6 +844,15 @@ impl<R: Runtime> WindowManager<R> {
pattern_script,
ipc_script,
bundle_script,
listen_function: &format!(
"function listen(eventName, cb) {{ {} }}",
crate::event::listen_js(
self.event_listeners_object_name(),
"eventName".into(),
0,
"window['_' + window.__TAURI__.transformCallback(cb) ]".into()
)
),
core_script: include_str!("../scripts/core.js"),
event_initialization_script: &self.event_initialization_script(),
plugin_initialization_script,
Expand Down Expand Up @@ -930,7 +947,7 @@ impl<R: Runtime> WindowManager<R> {
&self,
app_handle: AppHandle<R>,
mut pending: PendingWindow<R>,
pending_labels: &[String],
window_labels: &[String],
) -> crate::Result<PendingWindow<R>> {
if self.windows_lock().contains_key(&pending.label) {
return Err(crate::Error::WindowLabelAlreadyExists(pending.label));
Expand Down Expand Up @@ -982,7 +999,7 @@ impl<R: Runtime> WindowManager<R> {

if is_local {
let label = pending.label.clone();
pending = self.prepare_pending_window(pending, &label, pending_labels, app_handle.clone())?;
pending = self.prepare_pending_window(pending, &label, window_labels, app_handle.clone())?;
pending.ipc_handler = Some(self.prepare_ipc_handler(app_handle.clone()));
}

Expand Down

0 comments on commit 878b8b9

Please sign in to comment.