GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
fix: a dropdown's trigger text names its font
A dropdown painted as a stamp by another widget took that widget's font,
and its menu then opened in the control font. The trigger's text and
arrow now carry control_label_font_detached on the prim, as the menu's do.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CLAUDE.md | 17 +++++++++++++++++
src/widget/input/dropdown.rs | 10 ++++++++--
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/CLAUDE.md b/CLAUDE.md
index 6c47ff1..b6e5eda 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -300,6 +300,23 @@ app sees the press (`close_popovers_missed_by_press`) — and a popover covered
outer popover's claim always misses — so the dropdown may already have taken the press
by the time the app is asked.
+### A dropdown's text names its font (since 2026-10-01)
+
+The trigger's text and ▼ are emitted with `control_label_font_detached()` named on the
+prim, where they used to leave the font to the host. Through the widget walk the
+adapter attached `widget_font` and nothing changed; but a dropdown painted as a STAMP
+by another widget (the designer's palette paints its choice rows so) took that
+widget's font, and the menu `draw_popover` grows out of it — which has always named
+the font — opened in a different one. The whole configured string is passed, family
+and size together (`Berkeley Mono 14`): the runner parses both and the size wins over
+the prim's, which is how the menu's hard-coded 12 px rows and 10 px ▼ come out at the
+trigger's size. Passing the family alone breaks exactly that.
+
+A host that draws an open dropdown should hand `render_popover` a real `PaintCtx`, as
+cce-files does: a `PopoverCollector` keeps fills as plain rects, so the grown plate
+loses its relief and its corners (`inset_plate` degrades to a flat fill there). The
+designer's params pane went through one until the same day.
+
### A row can open a submenu (since 2026-09-29)
`context_menu::set_row_submenu(idx, SubmenuSpec { options, header_count, sliders })`,
diff --git a/src/widget/input/dropdown.rs b/src/widget/input/dropdown.rs
index d1ea2e0..717854b 100644
--- a/src/widget/input/dropdown.rs
+++ b/src/widget/input/dropdown.rs
@@ -781,7 +781,13 @@ impl Dropdown {
};
if !skip_char && !piece.trim().is_empty() {
- ctx.text(piece, cur_x, text_y, font_size, color);
+ // The font named here and not left to the host: a dropdown
+ // painted as a stamp by another widget (the designer's
+ // palette paints its choice rows so) took that widget's
+ // font, and its menu then opened in this one. The whole
+ // configured string, as `widget_font` and `draw_popover`
+ // pass it — the runner reads its size too.
+ ctx.text_with(piece, cur_x, text_y, font_size, color, Some(crate::layout::control_label_font_detached()), None);
}
}
@@ -795,7 +801,7 @@ impl Dropdown {
crate::layout::center_text_y(content.y, content.height, 10.0),
10.0,
[0x83, 0x83, 0x8a],
- None,
+ Some(crate::layout::control_label_font_detached()),
Some([content.x, content.y, content.x + content.width, content.y + content.height]),
);
}