diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index d8c40e7b..316cd4eb 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -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 { - 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")); + } +}