From c559d31dad0a8b7a0e2cdc8931677c751702cf42 Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Fri, 25 Sep 2026 20:43:00 -0400 Subject: [PATCH] Size TextRow's field box from the field's height, so its label shows Every TextRow drew a field and a hint but no name: "Filename template" and "Destination" on the settings page and in the export sheet, the two storage budgets, the export size fields. The label was there, painted behind the entry, with a clipped "ws" of "Thumbnails and previews" poking out beside the thumbnail field. The field sits in a Rectangle so the row can dim it and watch it lose focus, and that Rectangle took its height from `field.preferred-height`. `Field` sets its own `height` outright and has no layout inside it, so its preferred height is zero. The box was zero tall, the row around it took its height from the unit label beside it, and the field, centred on an empty box, sat half its own height above the row, on top of the FieldRow. Segmented never showed it because its chips live in a layout that reports a real height. Reading `field.height` instead gives the box the height the field actually draws at, so the row reserves it and the label sits above. The note on `Field.label` that recorded the fault now records the trap. --- ui/dr-ui/ui/controls.slint | 8 +++++++- ui/dr-ui/ui/widgets.slint | 10 +++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ui/dr-ui/ui/controls.slint b/ui/dr-ui/ui/controls.slint index df73df5..482c4e2 100644 --- a/ui/dr-ui/ui/controls.slint +++ b/ui/dr-ui/ui/controls.slint @@ -759,7 +759,13 @@ export component TextRow inherits VerticalLayout { Rectangle { width: root.field-width; - height: field.preferred-height; + // The field's own height, not its `preferred-height`. `Field` is + // a Rectangle whose height is set outright rather than reported + // by a layout inside it, so its preferred height is zero; a + // zero-tall box here centres the field on its top edge, half a + // field above the row — which is where the label was, so from 0.9.0 + // every `TextRow` drew its name behind its entry. + height: field.height; opacity: root.enabled ? 1.0 : 0.4; field := Field { diff --git a/ui/dr-ui/ui/widgets.slint b/ui/dr-ui/ui/widgets.slint index 3fbfd9a..9992514 100644 --- a/ui/dr-ui/ui/widgets.slint +++ b/ui/dr-ui/ui/widgets.slint @@ -764,11 +764,11 @@ export component Field inherits Rectangle { /// carried a second time, here, where the accessibility tree can attach it /// to the control the user is actually typing into. /// - /// That second copy is not redundant even where the caption renders. It is - /// the *only* copy where the caption does not: `TextRow`'s label draws - /// behind its own field on the settings page and has done since 0.9.0, so - /// a sighted user reading that page today has less to go on than a screen - /// reader does. + /// **Anything wrapping this sizes itself from `height`, not + /// `preferred-height`.** The height is set outright, so there is no layout + /// inside to report a preferred one and it reads zero. `TextRow` sized its + /// box from it from 0.9.0 to 0.15.0, the field centred itself half a field + /// above that empty box, and every `TextRow` label drew behind its entry. in property label; in property placeholder; /// Masks the entry, for a credential that should not be readable over the