git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commite92ee16afabc4f429e2f09820ebb990b796dcc31
parentcef6d02843
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-01 20:27
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]),
         );
     }