diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index 3c91db762..3b36de7f7 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -12,7 +12,7 @@ use crate::{ menu::{Menu, MenuId, SystemTrayMenuItem}, tag::Tag, webview::{CustomProtocol, WebviewAttributes, WindowBuilder}, - window::PendingWindow, + window::{PendingWindow, WindowEvent}, Dispatch, Params, Runtime, }, sealed::{ManagerBase, RuntimeOrDispatch}, @@ -25,6 +25,7 @@ use std::{collections::HashMap, sync::Arc}; use crate::updater; pub(crate) type GlobalMenuEventListener

= Box) + Send + Sync>; +pub(crate) type GlobalWindowEventListener

= Box) + Send + Sync>; type SystemTrayEventListener

= Box, SystemTrayEvent<

::SystemTrayMenuId>) + Send + Sync>; @@ -58,6 +59,24 @@ impl WindowMenuEvent

{ } } +/// A window event that was triggered on the specified window. +pub struct GlobalWindowEvent { + pub(crate) event: WindowEvent, + pub(crate) window: Window

, +} + +impl GlobalWindowEvent

{ + /// The eventpayload. + pub fn event(&self) -> &WindowEvent { + &self.event + } + + /// The window that the menu belongs to. + pub fn window(&self) -> &Window

{ + &self.window + } +} + /// A handle to the currently running application. pub struct AppHandle { manager: WindowManager

, @@ -206,6 +225,9 @@ where /// Menu event handlers that listens to all windows. menu_event_listeners: Vec>>, + /// Window event handlers that listens to all windows. + window_event_listeners: Vec>>, + /// The app system tray menu items. system_tray: Vec>, @@ -234,6 +256,7 @@ where state: StateManager::new(), menu: Vec::new(), menu_event_listeners: Vec::new(), + window_event_listeners: Vec::new(), system_tray: Vec::new(), system_tray_event_listeners: Vec::new(), } @@ -372,6 +395,17 @@ where self } + /// Registers a window event handler for all windows. + pub fn on_window_event< + F: Fn(GlobalWindowEvent>) + Send + Sync + 'static, + >( + mut self, + handler: F, + ) -> Self { + self.window_event_listeners.push(Box::new(handler)); + self + } + /// Registers a system tray event handler. pub fn on_system_tray_event< F: Fn(&AppHandle>, SystemTrayEvent) + Send + Sync + 'static, @@ -421,6 +455,7 @@ where self.state, self.menu, self.menu_event_listeners, + self.window_event_listeners, ); // set up all the windows defined in the config diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index dfd9dd5b9..e05f5fa5d 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -56,7 +56,7 @@ use std::{borrow::Borrow, collections::HashMap, path::PathBuf, sync::Arc}; pub use { self::api::assets::Assets, self::api::config::{Config, WindowUrl}, - self::app::{App, Builder, SystemTrayEvent, WindowMenuEvent}, + self::app::{App, Builder, GlobalWindowEvent, SystemTrayEvent, WindowMenuEvent}, self::hooks::{ Invoke, InvokeError, InvokeHandler, InvokeMessage, InvokeResolver, InvokeResponse, OnPageLoad, PageLoadPayload, SetupHook, diff --git a/core/tauri/src/manager.rs b/core/tauri/src/manager.rs index ab96bf151..e68a26ae7 100644 --- a/core/tauri/src/manager.rs +++ b/core/tauri/src/manager.rs @@ -9,7 +9,7 @@ use crate::{ path::{resolve_path, BaseDirectory}, PackageInfo, }, - app::{GlobalMenuEventListener, WindowMenuEvent}, + app::{GlobalMenuEventListener, GlobalWindowEvent, GlobalWindowEventListener, WindowMenuEvent}, event::{Event, EventHandler, Listeners}, hooks::{InvokeHandler, OnPageLoad, PageLoadPayload}, plugin::PluginStore, @@ -86,6 +86,8 @@ pub struct InnerWindowManager { menu: Vec>, /// Menu event listeners to all windows. menu_event_listeners: Arc>>, + /// Window event listeners to all windows. + window_event_listeners: Arc>>, menu_ids: HashMap, } @@ -169,6 +171,7 @@ impl WindowManager

{ state: StateManager, menu: Vec>, menu_event_listeners: Vec>, + window_event_listeners: Vec>, ) -> Self { let menu_ids = get_menu_ids(&menu); Self { @@ -187,6 +190,7 @@ impl WindowManager

{ uri_scheme_protocols, menu, menu_event_listeners: Arc::new(menu_event_listeners), + window_event_listeners: Arc::new(window_event_listeners), menu_ids, }), _marker: Args::default(), @@ -468,6 +472,7 @@ mod test { StateManager::new(), Vec::new(), Default::default(), + Default::default(), ); #[cfg(custom_protocol)] @@ -549,8 +554,15 @@ impl WindowManager

{ let window = Window::new(self.clone(), window); let window_ = window.clone(); + let window_event_listeners = self.inner.window_event_listeners.clone(); window.on_window_event(move |event| { let _ = on_window_event(&window_, event); + for handler in window_event_listeners.iter() { + handler(GlobalWindowEvent { + window: window_.clone(), + event: event.clone(), + }); + } }); let window_ = window.clone(); let menu_event_listeners = self.inner.menu_event_listeners.clone();