Open New Tracks and Bounce only from the menu.

engine.execute and app.run of ui.new_tracks_dialog and ui.bounce_dialog were opening modal dialogs, so a script could not create tracks or bounce without a window. Those ids now return an error unless the menu invokes them.
This commit is contained in:
Vikram Bhaskaran
2026-10-10 17:39:46 +11:00
parent 522e59f8f5
commit 30347ee42f
+32 -4
View File
@@ -390,6 +390,15 @@ pub fn invoke_menu(app: &mut SoundApp, id: &str, path: &str) {
if wants_dialog(id) && app.dialogs.open_for_command(&app.engine, id) {
return;
}
// These ids only exist to open a dialog from the menu. Programmatic `app.run` refuses them.
if id == "ui.new_tracks_dialog" {
let _ = app.dialogs.open_for_command(&app.engine, "track.new");
return;
}
if id == "ui.bounce_dialog" {
let _ = app.dialogs.open_for_command(&app.engine, "file.bounce_mix");
return;
}
let params = params_for(path, id);
let _ = app.run(id, params);
}
@@ -524,12 +533,10 @@ pub fn run_ui_command(app: &mut SoundApp, id: &str, p: &Value) -> Option<Result<
json!({"mix_views": app.ui.mix_views})
}
"ui.new_tracks_dialog" => {
let _ = app.dialogs.open_for_command(&app.engine, "track.new");
json!({})
return Some(Err("ui.new_tracks_dialog opens a dialog from the menu only; call track.new with parameters".into()));
}
"ui.bounce_dialog" => {
let _ = app.dialogs.open_for_command(&app.engine, "file.bounce_mix");
json!({})
return Some(Err("ui.bounce_dialog opens a dialog from the menu only; call file.bounce_mix with a path".into()));
}
"ui.theme" => {
let Some(mode) = p.get("mode").and_then(Value::as_str) else {
@@ -571,3 +578,24 @@ pub fn parity() -> Value {
let extra = ui_aliases();
catalog::parity_with(&extra)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Services, SoundApp};
#[test]
fn programmatic_dialog_commands_stay_closed_and_the_menu_opens_them() {
let mut app = SoundApp::new(soundcraft_engine::Engine::default(), None, Services::default());
let err = app.run("ui.new_tracks_dialog", json!({})).unwrap_err();
assert!(err.contains("track.new"), "{err}");
let err = app.run("ui.bounce_dialog", json!({})).unwrap_err();
assert!(err.contains("file.bounce_mix"), "{err}");
assert!(app.dialogs.open_name().is_none());
invoke_menu(&mut app, "ui.new_tracks_dialog", "Track > New...");
assert_eq!(app.dialogs.open_name(), Some("new_tracks"));
app.dialogs.open = None;
invoke_menu(&mut app, "ui.bounce_dialog", "File > Bounce Mix...");
assert_eq!(app.dialogs.open_name(), Some("bounce"));
}
}