From f4c68e18fcd3e38d4122486c374e9d805cec8139 Mon Sep 17 00:00:00 2001 From: Elarionus <29511515+Elarionus@users.noreply.github.com> Date: Mon, 2 Nov 2026 13:26:04 -0800 Subject: [PATCH] macOS: Quit (Cmd+Q), the Dock's Quit and logout ask to save unsaved drawings (#2157) (#2620) Quit CADCraft in the app menu, the Dock's Quit and logout end the app through AppKit's terminate, which skipped the "Save changes to ...?" prompt, so unsaved work was lost. The event loop now turns termination into a close request for the window (the storytold winit fork's opt-in, as DesignCraft does), so it asks first, as the close button does. Cancel keeps the app open; Force Quit can't be intercepted. Co-authored-by: Ethan Dale Co-authored-by: Claude Opus 5.5 --- apps/cadcraft/Cargo.toml | 3 +++ apps/cadcraft/src/main.rs | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/apps/cadcraft/Cargo.toml b/apps/cadcraft/Cargo.toml index d8b4ef4c5..993668694 100644 --- a/apps/cadcraft/Cargo.toml +++ b/apps/cadcraft/Cargo.toml @@ -50,6 +50,9 @@ muda = { version = "0.21", default-features = false } # View ▸ Accessibility ▸ Animation Effects ▸ Use System Setting: the system's Reduce motion # (system_animations.rs). Already in Cargo.lock through muda. objc2-app-kit = { version = "0.3", default-features = false, features = ["std", "NSWorkspace", "NSAccessibility"] } +# The same winit eframe uses (the storytold fork, patched in the workspace): its opt-in that turns +# AppKit's terminate (Cmd+Q, Dock Quit) into a close request, so unsaved changes are asked about. +winit = { version = "0.30", default-features = false } # Rust HID backends: no proprietary SDK or C HID library. [target.'cfg(target_os = "windows")'.dependencies] diff --git a/apps/cadcraft/src/main.rs b/apps/cadcraft/src/main.rs index c591c10b3..98dd3c679 100644 --- a/apps/cadcraft/src/main.rs +++ b/apps/cadcraft/src/main.rs @@ -310,6 +310,16 @@ fn main() -> eframe::Result { b.with_x11(); })); } + // macOS: Quit CADCraft (Cmd+Q), the Dock's Quit and logout end the app through AppKit's + // terminate, which would skip the unsaved-changes prompt (#2157). winit turns each into a + // close request for the window instead, so it asks first, as the close button does. + #[cfg(target_os = "macos")] + { + options.event_loop_builder = Some(Box::new(|b| { + use winit::platform::macos::EventLoopBuilderExtMacOS; + b.with_close_requested_on_terminate(true); + })); + } eframe::run_native( "CADCraft", options,