diff --git a/rust/Cargo.lock b/rust/Cargo.lock index b17e8c8..dc2fda6 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -3723,6 +3723,8 @@ dependencies = [ "image", "libc", "nexus-core", + "objc2 0.6.5", + "objc2-app-kit 0.3.2", "parking_lot", "regex", "rfd", diff --git a/rust/app/Cargo.toml b/rust/app/Cargo.toml index a411085..5cfc91f 100644 --- a/rust/app/Cargo.toml +++ b/rust/app/Cargo.toml @@ -35,3 +35,7 @@ winresource = "0.1" [target.'cfg(unix)'.dependencies] libc = "0.2" + +[target.'cfg(target_os = "macos")'.dependencies] +objc2 = "0.6.4" +objc2-app-kit = { version = "0.3.2", default-features = false, features = ["std", "NSApplication", "NSResponder"] } diff --git a/rust/app/src/chrome.rs b/rust/app/src/chrome.rs index 22a53f3..dd85176 100644 --- a/rust/app/src/chrome.rs +++ b/rust/app/src/chrome.rs @@ -238,7 +238,7 @@ fn window_controls(ui: &mut Ui, area: Rect) { ui.painter().text(r.center(), Align2::CENTER_CENTER, glyph, egui::FontId::proportional(14.0), c); if resp.clicked() { match k { - 0 => ctx.send_viewport_cmd(ViewportCommand::Minimized(true)), + 0 => minimize_window(&ctx), 1 => ctx.send_viewport_cmd(ViewportCommand::Maximized(!max)), _ => ctx.send_viewport_cmd(ViewportCommand::Close), } @@ -246,6 +246,19 @@ fn window_controls(ui: &mut Ui, area: Rect) { } } +/// `ViewportCommand::Minimized(true)` can leave eframe unresponsive after restore on macOS. +/// Hiding the app follows the normal macOS app lifecycle and avoids that minimize event path. +fn minimize_window(_ctx: &egui::Context) { + #[cfg(target_os = "macos")] + { + if let Some(mtm) = objc2::MainThreadMarker::new() { + objc2_app_kit::NSApplication::sharedApplication(mtm).hide(None); + } + } + #[cfg(not(target_os = "macos"))] + _ctx.send_viewport_cmd(ViewportCommand::Minimized(true)); +} + /// Invisible window edges that resize the undecorated window. pub fn resize_edges(ctx: &egui::Context) { use egui::{CursorIcon, ResizeDirection as D};