Skip to content

Commit cc2f39a

Browse files
authored
feat(core): add on_event hook on the Plugin trait (#2656)
1 parent 8599313 commit cc2f39a

3 files changed

Lines changed: 64 additions & 29 deletions

File tree

.changes/plugin-on_event.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri": patch
3+
---
4+
5+
Added `on_event` on the `Plugin` trait, which allows a plugin to react to the event loop.

core/tauri/src/app.rs

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -431,29 +431,10 @@ impl<R: Runtime> App<R> {
431431
self.runtime.take().unwrap().run(move |event| match event {
432432
RunEvent::Exit => {
433433
app_handle.cleanup_before_exit();
434-
callback(&app_handle, Event::Exit);
434+
on_event_loop_event(&app_handle, RunEvent::Exit, &manager, Some(&callback));
435435
}
436436
_ => {
437-
on_event_loop_event(&event, &manager);
438-
callback(
439-
&app_handle,
440-
match event {
441-
RunEvent::Exit => Event::Exit,
442-
RunEvent::ExitRequested { window_label, tx } => Event::ExitRequested {
443-
window_label,
444-
api: ExitRequestApi(tx),
445-
},
446-
RunEvent::CloseRequested { label, signal_tx } => Event::CloseRequested {
447-
label,
448-
api: CloseRequestApi(signal_tx),
449-
},
450-
RunEvent::WindowClose(label) => Event::WindowClosed(label),
451-
RunEvent::Ready => Event::Ready,
452-
RunEvent::Resumed => Event::Resumed,
453-
RunEvent::MainEventsCleared => Event::MainEventsCleared,
454-
_ => unimplemented!(),
455-
},
456-
);
437+
on_event_loop_event(&app_handle, event, &manager, Some(&callback));
457438
}
458439
});
459440
}
@@ -481,11 +462,15 @@ impl<R: Runtime> App<R> {
481462
#[cfg(any(target_os = "windows", target_os = "macos"))]
482463
pub fn run_iteration(&mut self) -> crate::runtime::RunIteration {
483464
let manager = self.manager.clone();
484-
self
485-
.runtime
486-
.as_mut()
487-
.unwrap()
488-
.run_iteration(move |event| on_event_loop_event(&event, &manager))
465+
let app_handle = self.handle();
466+
self.runtime.as_mut().unwrap().run_iteration(move |event| {
467+
on_event_loop_event(
468+
&app_handle,
469+
event,
470+
&manager,
471+
Option::<&Box<dyn Fn(&AppHandle<R>, Event)>>::None,
472+
)
473+
})
489474
}
490475
}
491476

@@ -1042,10 +1027,43 @@ impl<R: Runtime> Builder<R> {
10421027
}
10431028
}
10441029

1045-
fn on_event_loop_event<R: Runtime>(event: &RunEvent, manager: &WindowManager<R>) {
1046-
if let RunEvent::WindowClose(label) = event {
1030+
fn on_event_loop_event<R: Runtime, F: Fn(&AppHandle<R>, Event) + 'static>(
1031+
app_handle: &AppHandle<R>,
1032+
event: RunEvent,
1033+
manager: &WindowManager<R>,
1034+
callback: Option<&F>,
1035+
) {
1036+
if let RunEvent::WindowClose(label) = &event {
10471037
manager.on_window_close(label);
10481038
}
1039+
1040+
let event = match event {
1041+
RunEvent::Exit => Event::Exit,
1042+
RunEvent::ExitRequested { window_label, tx } => Event::ExitRequested {
1043+
window_label,
1044+
api: ExitRequestApi(tx),
1045+
},
1046+
RunEvent::CloseRequested { label, signal_tx } => Event::CloseRequested {
1047+
label,
1048+
api: CloseRequestApi(signal_tx),
1049+
},
1050+
RunEvent::WindowClose(label) => Event::WindowClosed(label),
1051+
RunEvent::Ready => Event::Ready,
1052+
RunEvent::Resumed => Event::Resumed,
1053+
RunEvent::MainEventsCleared => Event::MainEventsCleared,
1054+
_ => unimplemented!(),
1055+
};
1056+
1057+
manager
1058+
.inner
1059+
.plugins
1060+
.lock()
1061+
.expect("poisoned plugin store")
1062+
.on_event(app_handle, &event);
1063+
1064+
if let Some(c) = callback {
1065+
c(app_handle, event);
1066+
}
10491067
}
10501068

10511069
/// Make `Wry` the default `Runtime` for `Builder`

core/tauri/src/plugin.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
//! The Tauri plugin extension to expand Tauri functionality.
66
77
use crate::{
8-
runtime::Runtime, utils::config::PluginConfig, AppHandle, Invoke, PageLoadPayload, Window,
8+
runtime::Runtime, utils::config::PluginConfig, AppHandle, Event, Invoke, PageLoadPayload, Window,
99
};
1010
use serde_json::Value as JsonValue;
1111
use tauri_macros::default_runtime;
@@ -43,6 +43,10 @@ pub trait Plugin<R: Runtime>: Send {
4343
#[allow(unused_variables)]
4444
fn on_page_load(&mut self, window: Window<R>, payload: PageLoadPayload) {}
4545

46+
/// Callback invoked when the event loop receives a new event.
47+
#[allow(unused_variables)]
48+
fn on_event(&mut self, app: &AppHandle<R>, event: &Event) {}
49+
4650
/// Extend commands to [`crate::Builder::invoke_handler`].
4751
#[allow(unused_variables)]
4852
fn extend_api(&mut self, invoke: Invoke<R>) {}
@@ -121,6 +125,14 @@ impl<R: Runtime> PluginStore<R> {
121125
.for_each(|plugin| plugin.on_page_load(window.clone(), payload.clone()))
122126
}
123127

128+
/// Runs the on_event hook for all plugins in the store.
129+
pub(crate) fn on_event(&mut self, app: &AppHandle<R>, event: &Event) {
130+
self
131+
.store
132+
.values_mut()
133+
.for_each(|plugin| plugin.on_event(app, event))
134+
}
135+
124136
pub(crate) fn extend_api(&mut self, mut invoke: Invoke<R>) {
125137
let command = invoke.message.command.replace("plugin:", "");
126138
let mut tokens = command.split('|');

0 commit comments

Comments
 (0)