From 9ce599d978d8bebc2361e9ca59d89704ec326d39 Mon Sep 17 00:00:00 2001 From: Hector Villarreal Date: Tue, 3 Nov 2026 03:25:52 -0600 Subject: [PATCH] #941: a control key tip expands a collapsed ribbon before it opens the control Addresses CodeRabbit review on #3250, "Expand the ribbon for a same-tab control request": with the Insert tab chosen but the ribbon collapsed, Alt+I, S went to the same-tab branch and the Symbol gallery was never drawn. A collapsed ribbon is now expanded like a tab switch, and the request waits for the frame that draws the control. Test: legacy_keytips::alt_i_s_expands_a_collapsed_ribbon_on_the_insert_tab. Co-Authored-By: Claude Opus 5.5 --- crates/ui-egui/src/app/keys.rs | 8 ++++++-- crates/ui-egui/tests/it/legacy_keytips.rs | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/crates/ui-egui/src/app/keys.rs b/crates/ui-egui/src/app/keys.rs index b490d8557..1facc5a4f 100644 --- a/crates/ui-egui/src/app/keys.rs +++ b/crates/ui-egui/src/app/keys.rs @@ -63,8 +63,12 @@ impl SheetApp { // A control on another tab (a legacy menu key such as Alt+I, S for the Symbol // gallery) shows its tab first, so the control is drawn and takes the request. keytips::Action::Control(id) => { - if let Some(tab) = gridcraft_engine::find_command(id).and_then(|c| c.menu.first()).filter(|t| **t != self.ui.ribbon_tab) { - self.run_or_alert("ui.ribbonTab", json!({"tab": tab})); + // A collapsed ribbon draws no controls either: it is expanded the same way. + let other_tab = gridcraft_engine::find_command(id).and_then(|c| c.menu.first()).filter(|t| **t != self.ui.ribbon_tab); + if other_tab.is_some() || self.ui.ribbon_collapsed { + if let Some(tab) = other_tab { + self.run_or_alert("ui.ribbonTab", json!({"tab": tab})); + } self.ui.ribbon_collapsed = false; self.ui.keytip_invoke_next = Some(id); } else { diff --git a/crates/ui-egui/tests/it/legacy_keytips.rs b/crates/ui-egui/tests/it/legacy_keytips.rs index fa6ca37ed..c2490f2bf 100644 --- a/crates/ui-egui/tests/it/legacy_keytips.rs +++ b/crates/ui-egui/tests/it/legacy_keytips.rs @@ -31,3 +31,22 @@ fn alt_i_s_opens_the_symbol_gallery_and_leaves_the_cell_alone() { assert_eq!(h.state().ui.ribbon_tab, "Insert"); assert!(h.query_by_label("€").is_some(), "the Symbol gallery is open"); } + +#[test] +fn alt_i_s_expands_a_collapsed_ribbon_on_the_insert_tab() { + // With the Insert tab already chosen but the ribbon collapsed, the gallery's control isn't + // drawn: the keys expand the ribbon first. + let mut s = Session::new(); + s.new_workbook(); + let mut h = crate::common::os_harness(s, OperatingSystem::Nix); + h.state_mut().run("ui.ribbonTab", json!({"tab": "Insert"})).unwrap(); + h.state_mut().ui.ribbon_collapsed = true; + h.run_steps(4); + for key in [Key::F10, Key::I, Key::S] { + press(&mut h, key); + } + h.run_steps(4); + assert!(!h.state().ui.ribbon_collapsed); + assert!(h.query_by_label("€").is_some(), "the Symbol gallery is open"); + assert!(!h.state().session.journal.iter().any(|(id, _)| id == "insert.symbol")); +}