diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ab96b005..83133e6f 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -1388,7 +1388,7 @@ pub fn run() { if let Err(e) = app_handle.save_window_state(StateFlags::all()) { warn!("Failed to save window state {e:?}"); } else { - debug!("Saved window state"); + info!("Saved window state"); }; } _ => {} diff --git a/src-tauri/src/window.rs b/src-tauri/src/window.rs index c7d31b60..ee3d4584 100644 --- a/src-tauri/src/window.rs +++ b/src-tauri/src/window.rs @@ -1,7 +1,6 @@ use crate::window_menu::app_menu; use log::{info, warn}; use rand::random; -use std::process::exit; use tauri::{ AppHandle, Emitter, LogicalSize, Manager, Runtime, WebviewUrl, WebviewWindow, WindowEvent, }; @@ -119,7 +118,7 @@ pub(crate) fn create_window( win.on_window_event(move |event| match event { WindowEvent::CloseRequested { .. } => { let tx = tx.clone(); - tauri::async_runtime::block_on(async move { + tauri::async_runtime::spawn(async move { tx.send(()).await.unwrap(); }); } @@ -135,7 +134,14 @@ pub(crate) fn create_window( let event_id = event.id().0.as_str(); match event_id { - "quit" => exit(0), + "hacked_quit" => { + // Cmd+Q on macOS doesn't trigger `CloseRequested` so we use a custom Quit menu + // and trigger close() for each window. + w.webview_windows().iter().for_each(|(_, w)| { + info!("Closing window {}", w.label()); + let _ = w.close(); + }); + } "close" => w.close().unwrap(), "zoom_reset" => w.emit("zoom_reset", true).unwrap(), "zoom_in" => w.emit("zoom_in", true).unwrap(), @@ -199,7 +205,13 @@ pub(crate) fn create_main_window(handle: &AppHandle, url: &str) -> WebviewWindow create_window(handle, config) } -pub(crate) fn create_child_window(parent_window: &WebviewWindow, url: &str, label: &str, title: &str, inner_size: (f64, f64)) -> WebviewWindow { +pub(crate) fn create_child_window( + parent_window: &WebviewWindow, + url: &str, + label: &str, + title: &str, + inner_size: (f64, f64), +) -> WebviewWindow { let app_handle = parent_window.app_handle(); let label = format!("{OTHER_WINDOW_PREFIX}_{label}"); let scale_factor = parent_window.scale_factor().unwrap(); @@ -247,7 +259,7 @@ pub(crate) fn create_child_window(parent_window: &WebviewWindow, url: &str, labe let child_window = child_window.clone(); parent_window.clone().on_window_event(move |e| match e { // When the parent window is closed, close the child - WindowEvent::CloseRequested { .. } => child_window.destroy().unwrap(), + WindowEvent::CloseRequested { .. } => child_window.close().unwrap(), // When the parent window is focused, bring the child above WindowEvent::Focused(focus) => { if *focus { @@ -259,6 +271,6 @@ pub(crate) fn create_child_window(parent_window: &WebviewWindow, url: &str, labe _ => {} }); } - + child_window } diff --git a/src-tauri/src/window_menu.rs b/src-tauri/src/window_menu.rs index 41281bee..1fb549d5 100644 --- a/src-tauri/src/window_menu.rs +++ b/src-tauri/src/window_menu.rs @@ -1,9 +1,9 @@ -use tauri::menu::{ - AboutMetadata, Menu, MenuItemBuilder, PredefinedMenuItem, Submenu, HELP_SUBMENU_ID, - WINDOW_SUBMENU_ID, -}; pub use tauri::AppHandle; use tauri::Runtime; +use tauri::menu::{ + AboutMetadata, HELP_SUBMENU_ID, Menu, MenuItemBuilder, PredefinedMenuItem, Submenu, + WINDOW_SUBMENU_ID, +}; pub fn app_menu(app_handle: &AppHandle) -> tauri::Result> { let pkg_info = app_handle.package_info(); @@ -64,7 +64,16 @@ pub fn app_menu(app_handle: &AppHandle) -> tauri::Result> &PredefinedMenuItem::hide(app_handle, None)?, &PredefinedMenuItem::hide_others(app_handle, None)?, &PredefinedMenuItem::separator(app_handle)?, - &PredefinedMenuItem::quit(app_handle, None)?, + // NOTE: Replace the predefined quit item with a custom one because, for some + // reason, ExitRequested events are not fired on cmd+Q. Perhaps this will be + // fixed in the future? + // https://github.com/tauri-apps/tauri/issues/9198 + &MenuItemBuilder::with_id( + "hacked_quit".to_string(), + format!("Quit {}", app_handle.package_info().name), + ) + .accelerator("CmdOrCtrl+q") + .build(app_handle)?, ], )?, #[cfg(not(any(