Explorar el Código

feat(core): add `on_event` hook on the `Plugin` trait (#2656)

Lucas Fernandes Nogueira hace 3 años
padre
commit
cc2f39a29f
Se han modificado 3 ficheros con 64 adiciones y 29 borrados
  1. 5 0
      .changes/plugin-on_event.md
  2. 46 28
      core/tauri/src/app.rs
  3. 13 1
      core/tauri/src/plugin.rs

+ 5 - 0
.changes/plugin-on_event.md

@@ -0,0 +1,5 @@
+---
+"tauri": patch
+---
+
+Added `on_event` on the `Plugin` trait, which allows a plugin to react to the event loop.

+ 46 - 28
core/tauri/src/app.rs

@@ -431,29 +431,10 @@ impl<R: Runtime> App<R> {
     self.runtime.take().unwrap().run(move |event| match event {
       RunEvent::Exit => {
         app_handle.cleanup_before_exit();
-        callback(&app_handle, Event::Exit);
+        on_event_loop_event(&app_handle, RunEvent::Exit, &manager, Some(&callback));
       }
       _ => {
-        on_event_loop_event(&event, &manager);
-        callback(
-          &app_handle,
-          match event {
-            RunEvent::Exit => Event::Exit,
-            RunEvent::ExitRequested { window_label, tx } => Event::ExitRequested {
-              window_label,
-              api: ExitRequestApi(tx),
-            },
-            RunEvent::CloseRequested { label, signal_tx } => Event::CloseRequested {
-              label,
-              api: CloseRequestApi(signal_tx),
-            },
-            RunEvent::WindowClose(label) => Event::WindowClosed(label),
-            RunEvent::Ready => Event::Ready,
-            RunEvent::Resumed => Event::Resumed,
-            RunEvent::MainEventsCleared => Event::MainEventsCleared,
-            _ => unimplemented!(),
-          },
-        );
+        on_event_loop_event(&app_handle, event, &manager, Some(&callback));
       }
     });
   }
@@ -481,11 +462,15 @@ impl<R: Runtime> App<R> {
   #[cfg(any(target_os = "windows", target_os = "macos"))]
   pub fn run_iteration(&mut self) -> crate::runtime::RunIteration {
     let manager = self.manager.clone();
-    self
-      .runtime
-      .as_mut()
-      .unwrap()
-      .run_iteration(move |event| on_event_loop_event(&event, &manager))
+    let app_handle = self.handle();
+    self.runtime.as_mut().unwrap().run_iteration(move |event| {
+      on_event_loop_event(
+        &app_handle,
+        event,
+        &manager,
+        Option::<&Box<dyn Fn(&AppHandle<R>, Event)>>::None,
+      )
+    })
   }
 }
 
@@ -1042,10 +1027,43 @@ impl<R: Runtime> Builder<R> {
   }
 }
 
-fn on_event_loop_event<R: Runtime>(event: &RunEvent, manager: &WindowManager<R>) {
-  if let RunEvent::WindowClose(label) = event {
+fn on_event_loop_event<R: Runtime, F: Fn(&AppHandle<R>, Event) + 'static>(
+  app_handle: &AppHandle<R>,
+  event: RunEvent,
+  manager: &WindowManager<R>,
+  callback: Option<&F>,
+) {
+  if let RunEvent::WindowClose(label) = &event {
     manager.on_window_close(label);
   }
+
+  let event = match event {
+    RunEvent::Exit => Event::Exit,
+    RunEvent::ExitRequested { window_label, tx } => Event::ExitRequested {
+      window_label,
+      api: ExitRequestApi(tx),
+    },
+    RunEvent::CloseRequested { label, signal_tx } => Event::CloseRequested {
+      label,
+      api: CloseRequestApi(signal_tx),
+    },
+    RunEvent::WindowClose(label) => Event::WindowClosed(label),
+    RunEvent::Ready => Event::Ready,
+    RunEvent::Resumed => Event::Resumed,
+    RunEvent::MainEventsCleared => Event::MainEventsCleared,
+    _ => unimplemented!(),
+  };
+
+  manager
+    .inner
+    .plugins
+    .lock()
+    .expect("poisoned plugin store")
+    .on_event(app_handle, &event);
+
+  if let Some(c) = callback {
+    c(app_handle, event);
+  }
 }
 
 /// Make `Wry` the default `Runtime` for `Builder`

+ 13 - 1
core/tauri/src/plugin.rs

@@ -5,7 +5,7 @@
 //! The Tauri plugin extension to expand Tauri functionality.
 
 use crate::{
-  runtime::Runtime, utils::config::PluginConfig, AppHandle, Invoke, PageLoadPayload, Window,
+  runtime::Runtime, utils::config::PluginConfig, AppHandle, Event, Invoke, PageLoadPayload, Window,
 };
 use serde_json::Value as JsonValue;
 use tauri_macros::default_runtime;
@@ -43,6 +43,10 @@ pub trait Plugin<R: Runtime>: Send {
   #[allow(unused_variables)]
   fn on_page_load(&mut self, window: Window<R>, payload: PageLoadPayload) {}
 
+  /// Callback invoked when the event loop receives a new event.
+  #[allow(unused_variables)]
+  fn on_event(&mut self, app: &AppHandle<R>, event: &Event) {}
+
   /// Extend commands to [`crate::Builder::invoke_handler`].
   #[allow(unused_variables)]
   fn extend_api(&mut self, invoke: Invoke<R>) {}
@@ -121,6 +125,14 @@ impl<R: Runtime> PluginStore<R> {
       .for_each(|plugin| plugin.on_page_load(window.clone(), payload.clone()))
   }
 
+  /// Runs the on_event hook for all plugins in the store.
+  pub(crate) fn on_event(&mut self, app: &AppHandle<R>, event: &Event) {
+    self
+      .store
+      .values_mut()
+      .for_each(|plugin| plugin.on_event(app, event))
+  }
+
   pub(crate) fn extend_api(&mut self, mut invoke: Invoke<R>) {
     let command = invoke.message.command.replace("plugin:", "");
     let mut tokens = command.split('|');