mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-24 10:08:00 -06:00
* fix(macos): Cmd+Q asks about unsaved changes (#1136) winit's default app menu sends Quit (Cmd+Q) straight to -[NSApplication terminate:], so PdfCraft quit without asking and unsaved edits were lost; the close button and Dock > Quit already ask. Install craft-quit's app menu (storytold/craft-libs#21) from the app creator. Its Quit sends ViewportCommand::Close, which guard_quit handles like the close button. If the menu can't be built, winit's menu stays and a warning is logged. craft-quit is pinned to the head of craft-libs#21 until #5 and #21 are merged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(macos): closing the window quits through terminate: (#1136) On Touch Bar Macs the close button crashed PdfCraft (exit 133, -[_NSTouchBarFinderObservation invalidate]): eframe drops the window inside AppKit's run loop. craft_quit::on_close_request, right after guard_quit in `logic`, cancels an allowed close and quits through -[NSApplication terminate:] instead. A close that guard_quit holds for the unsaved-changes prompt is left alone. Elsewhere it does nothing. craft-quit moves to the workspace dependencies, pinned to craft-libs main (f58bc1a, with #5 and #21 merged) instead of #21's head. The on_close_request change and its Touch Bar test are from jmacek. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
Brandon Thomas
parent
7461c29791
commit
41809cf765
Generated
+51
@@ -1154,6 +1154,18 @@ dependencies = [
|
||||
"winsafe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "craft-quit"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=f58bc1a3df490992d633393d0898af0588ce882c#f58bc1a3df490992d633393d0898af0588ce882c"
|
||||
dependencies = [
|
||||
"dispatch2",
|
||||
"egui",
|
||||
"muda",
|
||||
"objc2 0.6.4",
|
||||
"objc2-app-kit 0.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "craft-ui"
|
||||
version = "0.1.0"
|
||||
@@ -1184,6 +1196,15 @@ dependencies = [
|
||||
"x509-cert",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "98b0cc327b5bc766e7fda9c9260cc0fa81b43a8e240440422dff70788e3f9ef1"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.8"
|
||||
@@ -3005,6 +3026,16 @@ dependencies = [
|
||||
"cpufeatures 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "keyboard-types"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d"
|
||||
dependencies = [
|
||||
"bitflags 2.13.2",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "khronos-egl"
|
||||
version = "6.0.0"
|
||||
@@ -3248,6 +3279,24 @@ dependencies = [
|
||||
"pxfm",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "muda"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4340e89c178916e62879c5c36b7f699019369be413e496178a6983ce91b8bc03"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"dpi",
|
||||
"keyboard-types",
|
||||
"objc2 0.6.4",
|
||||
"objc2-app-kit 0.3.2",
|
||||
"objc2-core-foundation",
|
||||
"objc2-foundation 0.3.2",
|
||||
"png 0.18.1",
|
||||
"thiserror 2.0.21",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "multiversion_no_op"
|
||||
version = "1.0.0"
|
||||
@@ -3877,6 +3926,7 @@ dependencies = [
|
||||
name = "pdfcraft"
|
||||
version = "0.8.0"
|
||||
dependencies = [
|
||||
"craft-quit",
|
||||
"eframe",
|
||||
"egui",
|
||||
"fmv-macos-events",
|
||||
@@ -4291,6 +4341,7 @@ dependencies = [
|
||||
"arboard",
|
||||
"base64 0.22.1",
|
||||
"bytemuck",
|
||||
"craft-quit",
|
||||
"craft-ui",
|
||||
"eframe",
|
||||
"egui",
|
||||
|
||||
@@ -14,6 +14,8 @@ repository = "https://github.com/storytold/pdfcraft"
|
||||
[workspace.dependencies]
|
||||
# Shared frontend components; engines remain independent of egui.
|
||||
craft-ui = { git = "https://github.com/storytold/craft-libs", version = "0.1.0", rev = "5c874d51eeb3de70e735c8ce87a59a7dedd47675", features = ["serde"] }
|
||||
# Quit the macOS way (#1136): ⌘Q asks about unsaved changes, and closing quits through `terminate:`.
|
||||
craft-quit = { git = "https://github.com/storytold/craft-libs", version = "0.1.0", rev = "f58bc1a3df490992d633393d0898af0588ce882c" }
|
||||
# Shared system spooler; document composition remains in pdfcraft-print.
|
||||
craft-print = { git = "https://github.com/storytold/craft-libs", version = "0.1.0", rev = "666c358065261a2816b376fa3bb10538dbf53040" }
|
||||
# internal
|
||||
|
||||
@@ -29,6 +29,9 @@ log = { workspace = true }
|
||||
# crate registers the handler (Objective-C interop needs unsafe, which our workspace forbids)
|
||||
# behind a safe API. Same version as PhotoCraft. Pinned exactly: review the diff before bumping.
|
||||
fmv-macos-events = "=0.1.0"
|
||||
# ⌘Q asks about unsaved changes like the close button (#1136): an app menu whose Quit asks the
|
||||
# window to close instead of winit's, which ends the process without asking.
|
||||
craft-quit = { workspace = true, features = ["menu"] }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
# Asks the Wayland compositor which GPU it draws with (linux-dmabuf feedback), so the window is
|
||||
|
||||
@@ -379,6 +379,11 @@ fn app_creator<'a>(
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
app.os_events = Some(apple_events.connect(&cc.egui_ctx));
|
||||
// winit's Quit (⌘Q) ends the process without asking about unsaved changes (#1136). This
|
||||
// menu's Quit closes the window instead, so `guard_quit` asks, as for the close button.
|
||||
if let Err(e) = craft_quit::install_app_menu(&cc.egui_ctx, "PdfCraft") {
|
||||
log::warn!("couldn't install the app menu, so ⌘Q quits without asking to save: {e}");
|
||||
}
|
||||
}
|
||||
if let Some(server) = instance {
|
||||
app.os_events = Some(server.connect(&cc.egui_ctx, native_wayland(cc)));
|
||||
|
||||
@@ -11,6 +11,8 @@ workspace = true
|
||||
|
||||
[dependencies]
|
||||
craft-ui = { workspace = true }
|
||||
# macOS: a window close quits through `terminate:` (the Touch Bar crash, #1136); elsewhere a no-op.
|
||||
craft-quit = { workspace = true, features = ["egui"] }
|
||||
pdfcraft-fonts = { workspace = true }
|
||||
pdfcraft-engine = { workspace = true }
|
||||
pdfcraft-cos = { workspace = true }
|
||||
|
||||
@@ -3013,6 +3013,8 @@ impl eframe::App for PdfCraftApp {
|
||||
self.control = Some(control);
|
||||
}
|
||||
self.guard_quit(ctx);
|
||||
// macOS: quit through `terminate:` instead of dropping the window (Touch Bar crash, #1136).
|
||||
craft_quit::on_close_request(ctx);
|
||||
let now = ctx.input(|i| i.time);
|
||||
self.autosave_tick(now);
|
||||
// Reload documents whose files a build rewrote (#431).
|
||||
|
||||
Reference in New Issue
Block a user