Found by DeslanStudio milestone 4b (the desktop shell — lib/ui's first real consumer), building the transport toolbar's `BPM` / time-display labels.
Repro (headless, gfx stubbed like tests/test_ui.eigs):
root is panel of ["root", 0, 0, 800, 600]
tb is toolbar of ["tb", 0, 0, 800]
add_child of [tb, label of ["l1", 0, 0, "BPM"]]
_layout of [root, 0, 0]
Error line 142: cannot apply '-' to num and null
142 | child.y is floor of ((widget.h - child.h) / 2)
at _layout_toolbar (line 142)
label is the only text widget without w/h in its constructor dict — _layout_toolbar and _layout_box read child.w/child.h unconditionally, so a label (the most natural toolbar child: captions, time displays, status text) crashes the layout engine. badge and checkbox already compute w from text_width; label should do the same (w = text_width(text, scale) + pad, h = char_h).
Related friction from the same consumer: _layout_toolbar ignores flex, so there is no equivalent of Qt's addStretch() / right-aligned flexible toolbar label — every toolbar row must be hand-measured. Fine to split out if you'd rather keep this issue to the crash.
Downstream workaround (visible, DeslanStudio src/client/shell.eigs): a local label helper stamps w/h after construction.
Found by DeslanStudio milestone 4b (the desktop shell — lib/ui's first real consumer), building the transport toolbar's `BPM` / time-display labels.
Repro (headless, gfx stubbed like tests/test_ui.eigs):
labelis the only text widget withoutw/hin its constructor dict —_layout_toolbarand_layout_boxreadchild.w/child.hunconditionally, so a label (the most natural toolbar child: captions, time displays, status text) crashes the layout engine.badgeandcheckboxalready computewfromtext_width;labelshould do the same (w = text_width(text, scale) + pad,h = char_h).Related friction from the same consumer:
_layout_toolbarignoresflex, so there is no equivalent of Qt'saddStretch()/ right-aligned flexible toolbar label — every toolbar row must be hand-measured. Fine to split out if you'd rather keep this issue to the crash.Downstream workaround (visible, DeslanStudio
src/client/shell.eigs): a local label helper stampsw/hafter construction.