authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-10-02 12:49:27-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-10-02 13:35:43-07:00
log5a7c56cdaa6c4de435f0f0c28d29c72b980348bd
tree23cc5b087faf1e9060956465d811b17fb1a74093
parent021a7246820757dd105aa45223eec7b9add63f79
signature Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU

fix: a box laid out inverted paints empty instead of failing the frame

A box with its bottom above its top failed the whole frame as an invalid primitive ("Canvas drawing failed: InvalidPrimitive"), as the rename field over a just-created section tab did. Such a box, or one smaller than its inset, now paints empty. Assisted-by: claude-opus-5.5

2 files changed, 31 insertions(+), 6 deletions(-)

crates/ui/src/lib.rs+4-6
......@@ -1589,12 +1589,10 @@ impl Ui {
15891589 });
15901590 let border = blend(node.border, node.hover_border);
15911591 let [left, top, right, bottom] = node.inset;
1592 let painted = [
1593 rect[0] + left,
1594 rect[1] + top,
1595 rect[2] - right,
1596 rect[3] - bottom,
1597 ];
1592 // A box squeezed smaller than its inset, or than nothing as it eases shut, paints
1593 // empty rather than inverted.
1594 let [x, y] = [rect[0] + left, rect[1] + top];
1595 let painted = [x, y, (rect[2] - right).max(x), (rect[3] - bottom).max(y)];
15981596 let size = [painted[2] - painted[0], painted[3] - painted[1]];
15991597 if let Some(color) = node.shadow {
16001598 let (own, menu);
crates/ui/src/tests.rs+27
......@@ -3127,3 +3127,30 @@ fn a_loose_dialog_fits_its_contents_to_the_window_and_its_side_stretches_to_its_
31273127 "row 10 at {row}, the list's top at {top}"
31283128 );
31293129}
3130
3131#[test]
3132fn a_box_squeezed_past_its_inset_paints_empty_not_inverted() {
3133 let mut ui = Ui::new(Theme::light(), DOUBLE_CLICK);
3134 frame(&mut ui, |ui| {
3135 ui.leaf(
3136 "row",
3137 Spec {
3138 size: [px(100.0), px(4.0)],
3139 fill: Some([1.0; 4]),
3140 gradient: Some([0.5, 0.5, 0.5, 1.0]),
3141 inset: [0.0, 0.0, 0.0, 10.0],
3142 ..Spec::default()
3143 },
3144 );
3145 });
3146 let rect = ui.display.iter().find_map(|item| match item {
3147 Display::Rect { rect, .. } => Some(*rect),
3148 _ => None,
3149 });
3150 let [left, top, right, bottom] = rect.expect("the row paints");
3151 assert!(
3152 right >= left && bottom >= top,
3153 "{:?}",
3154 [left, top, right, bottom]
3155 );
3156}