feat(core): add on_window_event (global) API to app::Builder (#1759)

This commit is contained in:
Lucas Fernandes Nogueira 2021-05-09 22:22:06 -03:00 committed by GitHub
parent 455c550f34
commit 34b6032df7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 3 deletions

View File

@ -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<P> = Box<dyn Fn(WindowMenuEvent<P>) + Send + Sync>;
pub(crate) type GlobalWindowEventListener<P> = Box<dyn Fn(GlobalWindowEvent<P>) + Send + Sync>;
type SystemTrayEventListener<P> =
Box<dyn Fn(&AppHandle<P>, SystemTrayEvent<<P as Params>::SystemTrayMenuId>) + Send + Sync>;
@ -58,6 +59,24 @@ impl<P: Params> WindowMenuEvent<P> {
}
}
/// A window event that was triggered on the specified window.
pub struct GlobalWindowEvent<P: Params> {
pub(crate) event: WindowEvent,
pub(crate) window: Window<P>,
}
impl<P: Params> GlobalWindowEvent<P> {
/// The eventpayload.
pub fn event(&self) -> &WindowEvent {
&self.event
}
/// The window that the menu belongs to.
pub fn window(&self) -> &Window<P> {
&self.window
}
}
/// A handle to the currently running application.
pub struct AppHandle<P: Params> {
manager: WindowManager<P>,
@ -206,6 +225,9 @@ where
/// Menu event handlers that listens to all windows.
menu_event_listeners: Vec<GlobalMenuEventListener<Args<E, L, MID, TID, A, R>>>,
/// Window event handlers that listens to all windows.
window_event_listeners: Vec<GlobalWindowEventListener<Args<E, L, MID, TID, A, R>>>,
/// The app system tray menu items.
system_tray: Vec<SystemTrayMenuItem<TID>>,
@ -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<Args<E, L, MID, TID, A, R>>) + 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<Args<E, L, MID, TID, A, R>>, SystemTrayEvent<TID>) + 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

View File

@ -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,

View File

@ -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<P: Params> {
menu: Vec<Menu<P::MenuId>>,
/// Menu event listeners to all windows.
menu_event_listeners: Arc<Vec<GlobalMenuEventListener<P>>>,
/// Window event listeners to all windows.
window_event_listeners: Arc<Vec<GlobalWindowEventListener<P>>>,
menu_ids: HashMap<u32, P::MenuId>,
}
@ -169,6 +171,7 @@ impl<P: Params> WindowManager<P> {
state: StateManager,
menu: Vec<Menu<P::MenuId>>,
menu_event_listeners: Vec<GlobalMenuEventListener<P>>,
window_event_listeners: Vec<GlobalWindowEventListener<P>>,
) -> Self {
let menu_ids = get_menu_ids(&menu);
Self {
@ -187,6 +190,7 @@ impl<P: Params> WindowManager<P> {
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<P: Params> WindowManager<P> {
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();