Scripts: the read after a script left the folder asks for a frame when it ends

When File › Scripts runs a listed script that is no longer in the Scripts folder, the folder is read again on a thread. That read now has the window's context, so it asks for a frame when it ends and an idle window takes in the new listing (and the macOS menu bar follows it) without waiting for the next input event.
This commit is contained in:
dotCooCoo
2026-11-10 19:24:35 -08:00
parent 259bd8ee25
commit d7a89d3243
2 changed files with 24 additions and 1 deletions
+2 -1
View File
@@ -246,7 +246,8 @@ pub fn readable(p: &Value) -> bool {
pub fn run(app: &mut VectorcraftApp, p: &Value) -> Result<Value, String> {
let path = p.get("path").and_then(Value::as_str).ok_or("missing `path`")?;
let source = app.session.installed_script(path).map_err(|e| {
refresh(app, None);
let ctx = app.ui_ctx.clone();
refresh(app, ctx.as_ref());
e.to_string()
})?;
app.run("script.run", json!({"source": source, "name": vectorcraft_engine::cmd::fileio::file_name(path)}))
+22
View File
@@ -200,6 +200,28 @@ fn a_script_that_left_the_folder_is_not_run_and_the_folder_is_read_again() {
let _ = std::fs::remove_dir_all(dir);
}
#[test]
fn the_read_after_a_script_that_left_the_folder_asks_for_a_frame() {
let dir = folder("gone-frame");
let mut app = app(&dir);
let gone = write(&dir, "gone.js", DRAW);
read(&app);
std::fs::remove_file(&gone).unwrap();
let ctx = egui::Context::default();
let (tx, frames) = std::sync::mpsc::channel();
ctx.set_request_repaint_callback(move |_| {
let _ = tx.send(());
});
app.ui_ctx = Some(ctx);
assert!(menus::run_ui_command(&mut app, scripts_menu::COMMAND, &json!({ "path": gone })).unwrap().is_err());
// With the app's copy of the context dropped, only the read's thread can still ask for a
// frame; the channel closes without one when that thread ends without asking.
app.ui_ctx = None;
assert_eq!(frames.recv(), Ok(()), "the finished read asks for a frame so an idle window takes it in");
scripts_menu::wait();
let _ = std::fs::remove_dir_all(dir);
}
#[test]
fn the_menu_notes_a_listing_that_stopped_and_a_folder_it_cannot_read() {
let dir = folder("notes");