mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 15:48:33 +00:00
Fix #341: the close decision runs in App::logic
eframe runs App::logic without App::ui while the window is minimized or hidden, and handles a close request then too. The unsaved-changes check, the device-loss close and craft_quit::on_close_request ran from ui, so such a close skipped the prompt and the macOS quit through terminate:. They now run at the end of logic, with the platform hook last, as craft-quit asks.
This commit is contained in:
1 parent
aa296cf273
commit
eff747897d
2 files changed
+25
-5
No files matched your search
@@ -1668,7 +1668,6 @@ impl EffectcraftApp {
|
||||
self.run_script_tasks(&ctx);
|
||||
self.apply_prefs(&ctx);
|
||||
self.handle_events(&ctx);
|
||||
panels::unsaved::close_or_quit(self, &ctx);
|
||||
let title = panels::unsaved::window_title(self);
|
||||
if title != self.window_title {
|
||||
ctx.send_viewport_cmd(egui::ViewportCommand::Title(title.clone()));
|
||||
@@ -1913,14 +1912,20 @@ impl eframe::App for EffectcraftApp {
|
||||
}
|
||||
self.issue_screenshots(ctx);
|
||||
self.collect_screenshots(ctx);
|
||||
// eframe runs `logic` without `ui` while the window is minimized or hidden, and handles a
|
||||
// close then too, so the close decision is made here, with the platform hook last.
|
||||
if self.gpu_failure_applied == Some(true) {
|
||||
self.close_after_device_loss(ctx);
|
||||
// On macOS the app quits through `-[NSApplication terminate:]` instead of closing the
|
||||
// window while AppKit's run loop is running (#341).
|
||||
craft_quit::on_close_request(ctx);
|
||||
} else {
|
||||
panels::unsaved::close_or_quit(self, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
fn ui(&mut self, ui: &mut egui::Ui, frame: &mut eframe::Frame) {
|
||||
if self.gpu_failure_applied == Some(true) {
|
||||
self.close_after_device_loss(ui.ctx());
|
||||
// On macOS the app quits through `-[NSApplication terminate:]` instead of closing the
|
||||
// window while AppKit's run loop is running (#341).
|
||||
craft_quit::on_close_request(ui.ctx());
|
||||
return;
|
||||
}
|
||||
self.init_gpu(frame);
|
||||
|
||||
@@ -391,4 +391,19 @@ mod tests {
|
||||
let macos = cfg!(target_os = "macos");
|
||||
assert_eq!(close_frame(&mut app, &ctx), (macos, macos), "Don't Save quits");
|
||||
}
|
||||
|
||||
/// While the window is minimized or hidden, eframe runs `App::logic` without `App::ui` and
|
||||
/// still handles a close: `logic` asks about a modified project.
|
||||
#[test]
|
||||
fn a_close_while_only_logic_runs_asks_about_a_modified_project() {
|
||||
let (mut app, ctx) = app();
|
||||
modified(&mut app);
|
||||
let mut raw = egui::RawInput::default();
|
||||
raw.viewports.entry(egui::ViewportId::ROOT).or_default().events.push(egui::ViewportEvent::Close);
|
||||
let mut frame = eframe::Frame::_new_kittest();
|
||||
let out = ctx.run_logic(&raw, |ctx| eframe::App::logic(&mut app, ctx, &mut frame));
|
||||
let canceled = out.viewport_commands.get(&egui::ViewportId::ROOT).is_some_and(|c| c.contains(&egui::ViewportCommand::CancelClose));
|
||||
assert!(canceled, "the close is canceled");
|
||||
assert_eq!(app.dialog, Some(Dialog::UnsavedChanges));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user