diff --git a/crates/ui-egui/src/opening.rs b/crates/ui-egui/src/opening.rs index 1a816f2d8..fb2949dd4 100644 --- a/crates/ui-egui/src/opening.rs +++ b/crates/ui-egui/src/opening.rs @@ -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; + } } } diff --git a/crates/ui-egui/src/opening/tests.rs b/crates/ui-egui/src/opening/tests.rs index ee5d0a224..fa90d3cd5 100644 --- a/crates/ui-egui/src/opening/tests.rs +++ b/crates/ui-egui/src/opening/tests.rs @@ -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"); +}