This commit is contained in:
Claude committed 2026-10-11 11:47:26 +00:00
commit 96988afe6d
4 files changed
+54 -1

No files matched your search

+13
View File
@@ -175,6 +175,19 @@ impl HeadlessView {
}
/// Every piece of text the last frame painted (labels, tooltips, values), in paint order.
/// Every shape of the last frame, with `Shape::Vec` flattened.
pub fn painted_shapes(&self) -> Vec<egui::epaint::Shape> {
fn flat(shape: &egui::epaint::Shape, out: &mut Vec<egui::epaint::Shape>) {
match shape {
egui::epaint::Shape::Vec(shapes) => shapes.iter().for_each(|shape| flat(shape, out)),
other => out.push(other.clone()),
}
}
let mut out = Vec::new();
self.shapes.iter().for_each(|s| flat(&s.shape, &mut out));
out
}
pub fn painted_text(&self) -> Vec<String> {
fn texts(shape: &egui::epaint::Shape, out: &mut Vec<String>) {
match shape {
+4
View File
@@ -86,10 +86,14 @@ pub fn level(ui: &mut Ui, depth: usize, bar_bottom: Option<f32>, rows: impl FnOn
// The popup's `Ui` is only as tall as the popup was last frame (egui's default area size on
// the first), and a scroll area never grows past that. Ask for the room the window has;
// auto-shrink then fits the area to its rows, so a menu scrolls only when they don't fit.
// No scrollbar: the ▲ / ▼ strips, the wheel and dragging scroll a menu, like native menus.
// egui's floating bar is drawn over the rows' right edge, where the shortcut text ends, and in
// its wide (hovered) state its background hides the last character (issue #691).
let out = egui::ScrollArea::vertical()
.id_salt(("menu-level", depth))
.max_height(height)
.min_scrolled_height(height)
.scroll_bar_visibility(egui::scroll_area::ScrollBarVisibility::AlwaysHidden)
.scroll_source(egui::containers::scroll_area::ScrollSource::ALL)
.show(ui, rows);
let down = over.then(|| ui.allocate_exact_size(vec2(0.0, ARROW), Sense::hover()).0);
+36
View File
@@ -145,3 +145,39 @@ fn click_outside_and_escape_close_the_open_menu() {
h.settle(SETTLE);
assert_eq!(open_menu(&h), None, "Escape");
}
// ---- a scrolled menu draws no scrollbar over its rows (issue #691)
/// egui's floating scrollbar sat on the rows' right edge, where the shortcut text ends, and in
/// its wide (hovered) state its background hid the last character. With the pointer resting on
/// the menu, no tall narrow rectangle (a bar's handle or track) is painted along the level's
/// right edge, in a menu that scrolls as in one that fits, and the level is as wide in both.
#[test]
fn a_scrolled_menu_draws_no_scrollbar_over_its_shortcuts() {
let mut widths = Vec::new();
for (size, scrolls) in [([1600.0, 700.0], true), ([1600.0, 1400.0], false)] {
let what = format!("{} pt window", size[1]);
let mut h = app(size);
go(&mut h, "ui.clickWidget", "menu:View");
go(&mut h, "ui.hoverWidget", "menu-level:1");
let level = widget(&h, "menu-level:1").unwrap_or_else(|| panic!("{what}: no View menu"));
let rows = widgets_with(&h, "menusub:");
assert!(!rows.is_empty(), "{what}: no submenu rows registered");
assert_eq!(rows.iter().any(|(_, r)| !level.contains_rect(*r)), scrolls, "{what}: scrolls = {scrolls}, level {level:?}");
widths.push(level.width());
// a row's hover highlight spans the level; a separator is one point tall; the ▸ of a
// submenu row and the text are not rectangles: only a scrollbar is tall and narrow there
let bars: Vec<egui::Rect> = h
.view
.painted_shapes()
.iter()
.filter_map(|s| match s {
egui::epaint::Shape::Rect(r) => Some(r.rect),
_ => None,
})
.filter(|r| r.width() <= 14.0 && r.height() > 30.0 && r.left() >= level.right() - 16.0 && r.right() <= level.right() + 0.5)
.collect();
assert!(bars.is_empty(), "{what}: a scrollbar is drawn along the menu's right edge: {bars:?}");
}
assert!((widths[0] - widths[1]).abs() < 0.5, "a scrolled menu is as wide as one that fits: {widths:?}");
}
+1 -1
View File
@@ -481,7 +481,7 @@ visible menu bar yet: the menu model is only exposed through the control channel
| Id | Feature | Tier | Status | Evidence | Missing / notes |
|---|---|---|---|---|---|
| MENU-BAR | Menu bar rendering | P1 | ✅ | `crates/ui-egui/src/menubar.rs`, `apps/lightcraft/src/native_menu.rs` | native macOS menu bar (muda) with live labels/enabled/checked; in-window menus on web/Windows/Linux (with one menu open, the pointer on another title switches to it, as in native menu bars); ⌫ and X stay egui-handled (contextual), so they show no key in the native menu |
| MENU-BAR | Menu bar rendering | P1 | ✅ | `crates/ui-egui/src/menubar.rs`, `apps/lightcraft/src/native_menu.rs` | native macOS menu bar (muda) with live labels/enabled/checked; in-window menus on web/Windows/Linux (with one menu open, the pointer on another title switches to it, as in native menu bars); ⌫ and X stay egui-handled (contextual), so they show no key in the native menu; a scrolled menu draws no scrollbar over its rows: the ▲ / ▼ strips, the wheel and dragging scroll it (issue #691: egui's floating bar hid the shortcut text's last character; `crates/ui-egui/src/tests_menubar.rs`) |
| MENU-APP-ABOUT | About | P2 | ✅ | `cmd:app.about` | |
| MENU-APP-SETTINGS | Settings… | P0 | ✅ | `cmd:app.settings` | app menu on macOS, Edit menu elsewhere |
| MENU-APP-UPDATES | Check for updates | P2 | ⬜ | | |