opening::poll stops once a file it opens asks a question

Of two files read off the UI thread and ready in the same frame, the
first could open and ask about its links or fonts, and the second then
became the active document under that dialog. poll now checks
may_switch after each file it opens too, and leaves the rest for a
later frame.

The queued-reopen test also checks that a later queued activation
stays queued.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ruchirguitar
2026-11-04 08:13:04 +07:00
committed by bflatastic
co-authored by Claude Opus 5.5
parent e2c8c503c1
commit 079f5389a6
2 changed files with 38 additions and 2 deletions
+4
View File
@@ -132,6 +132,10 @@ pub fn poll(app: &mut VectorcraftApp) {
app.ui.status.clear();
}
p.scope.run(|| finish(app, &p.path, r));
// A file that opened and asks about its links or fonts holds back the others too.
if !may_switch(app) {
return;
}
}
}
+34 -2
View File
@@ -359,14 +359,19 @@ fn a_queued_reopen_that_asks_holds_back_files_ready_to_open() {
std::fs::create_dir_all(&dir).unwrap();
let mut app = VectorcraftApp::new(Session::new(), Services::default());
app.services.read = Some(Box::new(|p: &str| std::fs::read(p).map_err(|e| e.to_string())));
let doc = dir.join("doc.vectorcraft").to_string_lossy().into_owned();
let (doc, other) = (dir.join("doc.vectorcraft"), dir.join("other.vectorcraft"));
let (doc, other) = (doc.to_string_lossy().into_owned(), other.to_string_lossy().into_owned());
app.run("file.new", json!({"width": 400, "height": 300})).unwrap();
app.run("text.create", json!({"x": 10, "y": 40, "text": "Type", "font": "No Such Font Family"})).unwrap();
app.run("document.save", json!({"path": doc})).unwrap();
app.run("file.new", json!({})).unwrap();
app.run("document.save", json!({"path": other})).unwrap();
app.run("file.new", json!({})).unwrap();
app.ui.dialog = Some(crate::state::Dialog::new(crate::dialogs::save_options::KIND, json!({})));
crate::io::open_reporting(&mut app, &doc).unwrap();
assert_eq!(app.opening.activate.len(), 1);
crate::io::open_reporting(&mut app, &other).unwrap();
assert_eq!(app.opening.activate.len(), 2);
app.session.execute("file.close", &json!({"index": 1})).unwrap();
app.session.execute("file.close", &json!({"index": 0})).unwrap();
start(&mut app, "/art/Other.vectorcraft", vectorcraft_format::save(&vectorcraft_doc::Document::new(120.0, 80.0), false)).unwrap();
// Time for the other file to be read; it waits for the dialog meanwhile.
@@ -380,6 +385,33 @@ fn a_queued_reopen_that_asks_holds_back_files_ready_to_open() {
poll(&mut app);
assert_eq!(app.ui.dialog.as_ref().map(|d| d.kind.as_str()), Some(crate::dialogs::missing_fonts::KIND));
assert_eq!(app.session.doc().unwrap().path.as_deref(), Some(&*doc), "the dialog's document stays active");
assert_eq!(app.opening.activate.first().map(|(p, _)| p), Some(&other), "the later activation waits");
assert_eq!(app.opening.pending.len(), 1, "the other file waits");
let _ = std::fs::remove_dir_all(dir);
}
/// Of two files read off the UI thread and ready in the same frame, the first that opens and asks
/// about its fonts holds back the second, so the question acts on its own document (#5369).
#[test]
fn a_file_that_opens_and_asks_holds_back_the_next_one_ready() {
let mut app = VectorcraftApp::new(Session::new(), Services::default());
app.run("file.new", json!({"width": 400, "height": 300})).unwrap();
app.run("text.create", json!({"x": 10, "y": 40, "text": "Type", "font": "No Such Font Family"})).unwrap();
let asks = vectorcraft_format::save(&app.session.doc().unwrap().doc, false);
app.session.execute("file.close", &json!({})).unwrap();
app.ui.dialog = Some(crate::state::Dialog::new(crate::dialogs::save_options::KIND, json!({})));
start(&mut app, "/art/Asks.vectorcraft", asks).unwrap();
start(&mut app, "/art/Plain.vectorcraft", vectorcraft_format::save(&vectorcraft_doc::Document::new(120.0, 80.0), false)).unwrap();
// Time for both files to be read; they wait for the dialog meanwhile.
let t0 = std::time::Instant::now();
while t0.elapsed().as_millis() < 500 {
poll(&mut app);
std::thread::yield_now();
}
assert_eq!(app.opening.pending.len(), 2);
app.ui.dialog = None;
poll(&mut app);
assert_eq!(app.ui.dialog.as_ref().map(|d| d.kind.as_str()), Some(crate::dialogs::missing_fonts::KIND));
assert_eq!(app.session.doc().unwrap().path.as_deref(), Some("/art/Asks.vectorcraft"), "the dialog's document stays active");
assert_eq!(app.opening.pending.len(), 1, "the next file waits");
}