From 6c917ea3781ca623b8a71d76ebada00a0a706016 Mon Sep 17 00:00:00 2001 From: Zinadin Zidan Date: Sat, 7 Nov 2026 02:02:43 +0600 Subject: [PATCH] fix(ui): a MIDI editor behind another tab leaves the arrows to the Edit window (review) The piano roll's rect stayed recorded after its tab went behind another one, so with the pointer over the panel now in front, Left and Right still went to the hidden piano roll and the Edit window did not scroll. The rect is now recorded only by a frame that draws the MIDI panel. --- crates/ui-egui/src/docking.rs | 5 +++++ crates/ui-egui/tests/it/shortcuts.rs | 29 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/crates/ui-egui/src/docking.rs b/crates/ui-egui/src/docking.rs index 9d14cd55..91276156 100644 --- a/crates/ui-egui/src/docking.rs +++ b/crates/ui-egui/src/docking.rs @@ -472,6 +472,11 @@ pub fn show(app: &mut crate::SoundApp, ui: &mut egui::Ui, window: crate::MainWin // and bottom edges take frames (`drop_edges` keeps its default). style.new_dock_zones = true; style.side_edge_zones = false; + // The MIDI body's rect stands for a piano roll on screen (the arrow keys go to it), so only a + // frame that draws the panel records one: open behind another tab, the old rect is gone. + if edit { + ui.ctx().data_mut(|data| data.remove::(egui::Id::unique("soundcraft-midi-body"))); + } let output = DockArea::new(area(edit)).show_with_limits( ui, &workspace.layout, diff --git a/crates/ui-egui/tests/it/shortcuts.rs b/crates/ui-egui/tests/it/shortcuts.rs index 7422caa1..426717e0 100644 --- a/crates/ui-egui/tests/it/shortcuts.rs +++ b/crates/ui-egui/tests/it/shortcuts.rs @@ -190,3 +190,32 @@ fn the_piano_roll_keeps_the_plain_arrows() { assert!(note_start(&app) > before, "the note moved right"); assert_eq!(app.engine.session().edit.zoom.scroll, scroll, "the Edit window kept its view"); } + +/// The MIDI editor open behind another tab has no piano roll on screen: the panel in front of it takes no +/// arrows, so they centre the Edit window there as anywhere else. +#[test] +fn a_midi_editor_behind_another_tab_leaves_the_arrows_to_the_edit_window() { + let mut app = SoundApp::new(soundcraft_engine::demo::demo_engine(), None, Services::default()); + app.ui.show_midi_editor = true; + let (clip_id, clip) = app.engine.session().tracks.iter().flat_map(|t| t.clips()).find(|c| c.start > 100_000).map(|c| (c.id, c.range())).unwrap(); + app.run("view.zoom_set", json!({"samples_per_px": 10.0})).unwrap(); + app.run("view.scroll", json!({"to": 0})).unwrap(); + let ctx = egui::Context::default(); + for _ in 0..6 { + app_frame(&ctx, &mut app, vec![]); + } + let body = ctx.data(|d| d.get_temp::(egui::Id::unique("soundcraft-midi-body"))).unwrap(); + app.run("ui.dock", json!({"operation": "open", "panel": "history"})).unwrap(); + app.run("ui.dock", json!({"operation": "move", "panel": "history", "target": "midi", "zone": "tab"})).unwrap(); + for _ in 0..3 { + app_frame(&ctx, &mut app, vec![]); + } + assert!(app.ui.show_midi_editor, "the MIDI editor is still open"); + assert_ne!(app.ui.docking.layout.panel_state(&soundcraft_ui_egui::docking::Panel::Midi), craft_ui::docking::PanelState::Front); + app_frame(&ctx, &mut app, vec![egui::Event::PointerMoved(body.center())]); + app.run("edit.select", json!({"clips": [clip_id.0]})).unwrap(); + + app_frame(&ctx, &mut app, arrow(Key::ArrowLeft)); + let (x, middle) = x_and_middle(&app, clip.start); + assert!((x - middle).abs() < 1.0, "Left: the clip start at {x}, the middle at {middle}"); +}