Fix #830: the control channel's app.quit says when it asks first

Raw app.quit closed the window and answered null at once, so a client
couldn't tell that a save prompt was waiting. It now runs the menu's
Quit: {"pending": "saveChanges"} while a modified document is asked
about, as file.close and file.closeAll answer and the protocol
documentation says; otherwise null, and the window closes.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
bflatasticandClaude Opus 5.5 committed 2026-10-10 10:27:47 +07:00
1 parent 1ba987ee7a
commit db8be89052
2 files changed
+22 -4

No files matched your search

+3 -4
View File
@@ -335,10 +335,9 @@ pub fn handle(app: &mut VectorcraftApp, ctx: &egui::Context, req: &ControlReques
// No save dialog for an agent: the bytes come back, as in headless mode.
None => wrap(app.run("document.export", p.clone())),
},
"app.quit" => {
ctx.send_viewport_cmd(egui::ViewportCommand::Close);
ok(Value::Null)
}
// As the menu's Quit: `{"pending": "saveChanges"}` while a modified document is asked
// about; otherwise null, and the host closes the window (#830).
"app.quit" => wrap(app.run("app.quit", json!({}))),
other => err(format!("unknown method `{other}`")),
}
}
+19
View File
@@ -206,4 +206,23 @@ mod tests {
app.run("app.quit", json!({})).unwrap();
assert_eq!(app.ui.status, "quit");
}
#[test]
fn the_control_channels_quit_says_when_it_asks_first() {
// #830: it answered null at once, before the question.
let (mut app, _) = app();
let ctx = egui::Context::default();
let quit = |app: &mut VectorcraftApp| {
let (req, _rx) = crate::control::ControlRequest::new("app.quit", json!({}));
let crate::control::Outcome::Done(r) = crate::control::handle(app, &ctx, &req) else { panic!("not done") };
r
};
new_doc(&mut app, true);
assert_eq!(quit(&mut app), json!({"ok": true, "result": {"pending": KIND}}));
assert_eq!((pending(&app), app.ui.status.as_str()), (Some(0), ""));
app.ui.dialog = None;
app.run("file.save", json!({"path": "/docs/saved.vectorcraft"})).unwrap();
assert_eq!(quit(&mut app), json!({"ok": true, "result": null}));
assert_eq!(app.ui.status, "quit");
}
}