fix(wry): menu event is now tied to the window (#2048)

This commit is contained in:
Lucas Fernandes Nogueira 2021-06-23 11:29:30 -03:00 committed by GitHub
parent 160fb0529f
commit c9b11001f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 4 deletions

View File

@ -737,6 +737,10 @@ impl Dispatch for WryDispatcher {
.menu_event_listeners
.lock()
.unwrap()
.get(&self.window_id)
.unwrap()
.lock()
.unwrap()
.insert(id, Box::new(f));
id
}
@ -852,6 +856,7 @@ impl Dispatch for WryDispatcher {
let (tx, rx) = channel();
let label = pending.label.clone();
let context = self.context.clone();
self
.context
.proxy
@ -863,6 +868,7 @@ impl Dispatch for WryDispatcher {
))
.map_err(|_| Error::FailedToSendMessage)?;
let window_id = rx.recv().unwrap();
let dispatcher = WryDispatcher {
window_id,
context: self.context.clone(),
@ -1168,6 +1174,7 @@ impl RuntimeHandle for WryHandle {
))
.map_err(|_| Error::FailedToSendMessage)?;
let window_id = rx.recv().unwrap();
let dispatcher = WryDispatcher {
window_id,
context: self.dispatcher_context.clone(),
@ -1454,18 +1461,23 @@ fn handle_event_loop(
}
#[cfg(feature = "menu")]
Event::MenuEvent {
window_id,
menu_id,
origin: MenuType::MenuBar,
} => {
let window_id = window_id.unwrap(); // always Some on MenuBar event
let event = MenuEvent {
menu_item_id: menu_id.0,
};
for handler in menu_event_listeners.lock().unwrap().values() {
let listeners = menu_event_listeners.lock().unwrap();
let window_menu_event_listeners = listeners.get(&window_id).cloned().unwrap_or_default();
for handler in window_menu_event_listeners.lock().unwrap().values() {
handler(&event);
}
}
#[cfg(feature = "system-tray")]
Event::MenuEvent {
window_id: _,
menu_id,
origin: MenuType::ContextMenu,
} => {
@ -1501,7 +1513,13 @@ fn handle_event_loop(
}
match event {
WryWindowEvent::CloseRequested => {
on_window_close(callback, window_id, &mut webviews, control_flow);
on_window_close(
callback,
window_id,
&mut webviews,
menu_event_listeners.clone(),
control_flow,
);
}
WryWindowEvent::Resized(_) => {
if let Err(e) = webviews[&window_id].inner.resize() {
@ -1590,7 +1608,13 @@ fn handle_event_loop(
WindowMessage::Show => window.set_visible(true),
WindowMessage::Hide => window.set_visible(false),
WindowMessage::Close => {
on_window_close(callback, id, &mut webviews, control_flow);
on_window_close(
callback,
id,
&mut webviews,
menu_event_listeners.clone(),
control_flow,
);
}
WindowMessage::SetDecorations(decorations) => window.set_decorations(decorations),
WindowMessage::SetAlwaysOnTop(always_on_top) => window.set_always_on_top(always_on_top),
@ -1762,9 +1786,11 @@ fn on_window_close<'a>(
callback: &'a (dyn Fn(RunEvent) + 'static),
window_id: WindowId,
webviews: &mut MutexGuard<'a, HashMap<WindowId, WebviewWrapper>>,
menu_event_listeners: MenuEventListeners,
control_flow: &mut ControlFlow,
) {
if let Some(webview) = webviews.remove(&window_id) {
menu_event_listeners.lock().unwrap().remove(&window_id);
callback(RunEvent::WindowClose(webview.label));
}
if webviews.is_empty() {
@ -1811,6 +1837,14 @@ fn create_webview<P: Params<Runtime = Wry>>(
menu_items
};
let window = window_builder.inner.build(event_loop).unwrap();
#[cfg(feature = "menu")]
context
.menu_event_listeners
.lock()
.unwrap()
.insert(window.id(), WindowMenuEventListeners::default());
if window_builder.center {
let _ = center_window(&window);
}

View File

@ -18,6 +18,7 @@ pub use wry::application::{
MenuId as WryMenuId, MenuItem as WryMenuItem, MenuItemAttributes as WryMenuItemAttributes,
MenuType,
},
window::WindowId,
};
#[cfg(target_os = "macos")]
@ -38,7 +39,8 @@ use std::{
};
pub type MenuEventHandler = Box<dyn Fn(&MenuEvent) + Send>;
pub type MenuEventListeners = Arc<Mutex<HashMap<Uuid, MenuEventHandler>>>;
pub type MenuEventListeners = Arc<Mutex<HashMap<WindowId, WindowMenuEventListeners>>>;
pub type WindowMenuEventListeners = Arc<Mutex<HashMap<Uuid, MenuEventHandler>>>;
#[cfg(feature = "system-tray")]
pub type SystemTrayEventHandler = Box<dyn Fn(&SystemTrayEvent) + Send>;