mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-31 15:48:33 +00:00
Fix #341: answered file dialogs run before the close decision
The close decision moved to App::logic, which runs before App::ui, while the queued file-dialog answers still ran in ui. An answer that arrived in the frame that closed the window changed the project after the decision, so the window could close without asking to save. The answers now run in logic, before the decision.
This commit is contained in:
1 parent
eff747897d
commit
ce0ae4e387
2 files changed
+20
-1
No files matched your search
@@ -1623,7 +1623,6 @@ impl EffectcraftApp {
|
||||
fn frame(&mut self, ui: &mut egui::Ui) {
|
||||
let ctx = ui.ctx().clone();
|
||||
self.apply_gpu_failure(&ctx);
|
||||
self.run_dialog_answers();
|
||||
self.auto.begin_frame();
|
||||
self.frames.set_context(&ctx);
|
||||
if self.session.render_job.is_some() {
|
||||
@@ -1920,6 +1919,8 @@ impl eframe::App for EffectcraftApp {
|
||||
// window while AppKit's run loop is running (#341).
|
||||
craft_quit::on_close_request(ctx);
|
||||
} else {
|
||||
// An answered file dialog can change the project, so it runs before the close decision.
|
||||
self.run_dialog_answers();
|
||||
panels::unsaved::close_or_quit(self, ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,4 +406,22 @@ mod tests {
|
||||
assert!(canceled, "the close is canceled");
|
||||
assert_eq!(app.dialog, Some(Dialog::UnsavedChanges));
|
||||
}
|
||||
|
||||
/// A file dialog answered in the frame that closes the window runs its command before the
|
||||
/// close decision, so a change it makes is asked about.
|
||||
#[test]
|
||||
fn a_dialog_answer_runs_before_the_close_decision() {
|
||||
let (mut app, ctx) = app();
|
||||
assert!(!app.session.is_dirty());
|
||||
let answer = crate::DialogAnswer { command: "comp.new".into(), key: "name", params: json!({"width": 64, "height": 64}), paths: vec!["Main".into()] };
|
||||
app.dialog_answers.0.send(answer).unwrap();
|
||||
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!(app.session.is_dirty(), "the answer ran");
|
||||
assert!(canceled, "the close is canceled");
|
||||
assert_eq!(app.dialog, Some(Dialog::UnsavedChanges));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user