Skip to content

Commit

Permalink
fix(core): actually fire WindowEvent::Destroyed (#3797)
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasfernog committed Mar 29, 2022
1 parent a073f27 commit 169b503
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 40 deletions.
6 changes: 6 additions & 0 deletions .changes/fix-wry-window-destroyed-event.md
@@ -0,0 +1,6 @@
---
"tauri-runtime-wry": patch
"tauri": patch
---

Fixes `WindowEvent::Destroyed` not firing.
82 changes: 42 additions & 40 deletions core/tauri-runtime-wry/src/lib.rs
Expand Up @@ -586,13 +586,19 @@ impl TryFrom<WindowIcon> for WryIcon {
struct WindowEventWrapper(Option<WindowEvent>);

impl WindowEventWrapper {
fn parse(webview: &WindowHandle, event: &WryWindowEvent<'_>) -> Self {
fn parse(webview: &Option<WindowHandle>, event: &WryWindowEvent<'_>) -> Self {
match event {
// resized event from tao doesn't include a reliable size on macOS
// because wry replaces the NSView
WryWindowEvent::Resized(_) => Self(Some(WindowEvent::Resized(
PhysicalSizeWrapper(webview.inner_size()).into(),
))),
WryWindowEvent::Resized(_) => {
if let Some(webview) = webview {
Self(Some(WindowEvent::Resized(
PhysicalSizeWrapper(webview.inner_size()).into(),
)))
} else {
Self(None)
}
}
e => e.into(),
}
}
Expand Down Expand Up @@ -1536,7 +1542,7 @@ impl WindowHandle {
#[derive(Debug)]
pub struct WindowWrapper {
label: String,
inner: WindowHandle,
inner: Option<WindowHandle>,
menu_items: Option<HashMap<u16, WryCustomMenuItem>>,
}

Expand Down Expand Up @@ -2008,28 +2014,29 @@ fn handle_user_message<T: UserEvent>(
match message {
Message::Task(task) => task(),
Message::Window(id, window_message) => {
if let Some(webview) = windows
if let Some((Some(window_handle), menu_items)) = windows
.lock()
.expect("poisoned webview collection")
.get_mut(&id)
.map(|w| (w.inner.as_ref(), &mut w.menu_items))
{
let window = webview.inner.window();
let window = window_handle.window();
match window_message {
#[cfg(any(debug_assertions, feature = "devtools"))]
WindowMessage::OpenDevTools => {
if let WindowHandle::Webview(w) = &webview.inner {
if let WindowHandle::Webview(w) = &window_handle {
w.open_devtools();
}
}
#[cfg(any(debug_assertions, feature = "devtools"))]
WindowMessage::CloseDevTools => {
if let WindowHandle::Webview(w) = &webview.inner {
if let WindowHandle::Webview(w) = &window_handle {
w.close_devtools();
}
}
#[cfg(any(debug_assertions, feature = "devtools"))]
WindowMessage::IsDevToolsOpen(tx) => {
if let WindowHandle::Webview(w) = &webview.inner {
if let WindowHandle::Webview(w) = &window_handle {
tx.send(w.is_devtools_open()).unwrap();
} else {
tx.send(false).unwrap();
Expand All @@ -2054,7 +2061,7 @@ fn handle_user_message<T: UserEvent>(
)
.unwrap(),
WindowMessage::InnerSize(tx) => tx
.send(PhysicalSizeWrapper(webview.inner.inner_size()).into())
.send(PhysicalSizeWrapper(window_handle.inner_size()).into())
.unwrap(),
WindowMessage::OuterSize(tx) => tx
.send(PhysicalSizeWrapper(window.outer_size()).into())
Expand Down Expand Up @@ -2084,7 +2091,7 @@ fn handle_user_message<T: UserEvent>(
WindowMessage::GtkWindow(tx) => tx.send(GtkWindow(window.gtk_window().clone())).unwrap(),
// Setters
WindowMessage::Center(tx) => {
tx.send(center_window(window, webview.inner.inner_size()))
tx.send(center_window(window, window_handle.inner_size()))
.unwrap();
}
WindowMessage::RequestUserAttention(request_type) => {
Expand Down Expand Up @@ -2136,7 +2143,7 @@ fn handle_user_message<T: UserEvent>(
let _ = window.drag_window();
}
WindowMessage::UpdateMenuItem(id, update) => {
if let Some(menu_items) = webview.menu_items.as_mut() {
if let Some(menu_items) = menu_items.as_mut() {
let item = menu_items.get_mut(&id).expect("menu item not found");
match update {
MenuUpdate::SetEnabled(enabled) => item.set_enabled(enabled),
Expand All @@ -2161,7 +2168,7 @@ fn handle_user_message<T: UserEvent>(
.lock()
.expect("poisoned webview collection")
.get(&id)
.map(|w| &w.inner)
.and_then(|w| w.inner.as_ref())
{
if let Err(e) = webview.evaluate_script(&script) {
#[cfg(debug_assertions)]
Expand All @@ -2174,7 +2181,7 @@ fn handle_user_message<T: UserEvent>(
.lock()
.expect("poisoned webview collection")
.get(&id)
.map(|w| &w.inner)
.and_then(|w| w.inner.as_ref())
{
let _ = webview.print();
}
Expand Down Expand Up @@ -2226,7 +2233,7 @@ fn handle_user_message<T: UserEvent>(
window_id,
WindowWrapper {
label,
inner: WindowHandle::Window(w.clone()),
inner: Some(WindowHandle::Window(w.clone())),
menu_items: Default::default(),
},
);
Expand Down Expand Up @@ -2445,7 +2452,7 @@ fn handle_event_loop<T: UserEvent>(
.lock()
.expect("poisoned webview collection")
.get(&window_id)
.map(|w| &w.inner)
.and_then(|w| w.inner.as_ref())
{
// only focus the webview if the window is visible
// somehow tao is sending a Focused(true) event even when the window is invisible,
Expand Down Expand Up @@ -2494,16 +2501,18 @@ fn handle_event_loop<T: UserEvent>(
);
}
WryWindowEvent::Destroyed => {
let is_empty = windows.lock().unwrap().is_empty();
if is_empty {
let (tx, rx) = channel();
callback(RunEvent::ExitRequested { tx });
if windows.lock().unwrap().remove(&window_id).is_some() {
let is_empty = windows.lock().unwrap().is_empty();
if is_empty {
let (tx, rx) = channel();
callback(RunEvent::ExitRequested { tx });

let recv = rx.try_recv();
let should_prevent = matches!(recv, Ok(ExitRequestedEventAction::Prevent));
let recv = rx.try_recv();
let should_prevent = matches!(recv, Ok(ExitRequestedEventAction::Prevent));

if !should_prevent {
*control_flow = ControlFlow::Exit;
if !should_prevent {
*control_flow = ControlFlow::Exit;
}
}
}
}
Expand All @@ -2512,7 +2521,7 @@ fn handle_event_loop<T: UserEvent>(
.lock()
.expect("poisoned webview collection")
.get(&window_id)
.map(|w| &w.inner)
.and_then(|w| w.inner.as_ref())
{
if let Err(e) = webview.resize() {
#[cfg(debug_assertions)]
Expand Down Expand Up @@ -2564,7 +2573,7 @@ fn on_close_requested<'a, T: UserEvent>(
windows: Arc<Mutex<HashMap<WebviewId, WindowWrapper>>>,
window_event_listeners: &WindowEventListeners,
menu_event_listeners: MenuEventListeners,
) -> Option<WindowWrapper> {
) {
let (tx, rx) = channel();
let windows_guard = windows.lock().expect("poisoned webview collection");
if let Some(w) = windows_guard.get(&window_id) {
Expand All @@ -2588,32 +2597,25 @@ fn on_close_requested<'a, T: UserEvent>(
event: WindowEvent::CloseRequested { signal_tx: tx },
});
if let Ok(true) = rx.try_recv() {
None
} else {
on_window_close(
window_id,
windows.lock().expect("poisoned webview collection"),
menu_event_listeners,
)
);
}
} else {
None
}
}

fn on_window_close(
window_id: WebviewId,
mut windows: MutexGuard<'_, HashMap<WebviewId, WindowWrapper>>,
menu_event_listeners: MenuEventListeners,
) -> Option<WindowWrapper> {
#[allow(unused_mut)]
let w = if let Some(mut webview) = windows.remove(&window_id) {
) {
if let Some(mut window_wrapper) = windows.get_mut(&window_id) {
window_wrapper.inner = None;
menu_event_listeners.lock().unwrap().remove(&window_id);
Some(webview)
} else {
None
};
w
}
}

fn center_window(window: &Window, window_size: WryPhysicalSize<u32>) -> Result<()> {
Expand Down Expand Up @@ -2803,7 +2805,7 @@ fn create_webview<T: UserEvent>(

Ok(WindowWrapper {
label,
inner: WindowHandle::Webview(webview),
inner: Some(WindowHandle::Webview(webview)),
menu_items,
})
}
Expand Down

0 comments on commit 169b503

Please sign in to comment.