这是indexloc提供的服务,不要输入任何密码
Skip to content

content_size for internal nodes incorrectly includes the node's left/top border. #871

@wlott

Description

@wlott

It appears that for internal nodes the left/top border is included in the content_size, not just the padding. Leaf nodes, on the other hand, only include padding, not the border.

I'm pretty sure this is a bug and not the desired behavior because the original PR that added content_size (#573) explicitly calls out that the padding should be and border should not be included in content_size. It is also it is strange that there would be this left/top vs right/bottom asymmetry and difference in behavior between leaf and internal nodes.

taffy version

I tested this behavior against both taffy 0.7.7 (as used by Bevy 0.17) and 0.9.1 (latest at this moment).

Platform

Linux desktop, but nothing that I uncovered looks to depend on the platform.

What you did

I was trying to add a scrollbar to a Bevy UI and got some oddities that prompted me to dig into the implementation. Specifically, I was scrolling a grid that had both padding and border, a known number of rows, and all the rows given a fixed height. When I subtracted off nrows*rowheight, I was unable to match the result to my padding and border numbers. In digging through the implementation to try to explain the numbers I was getting, I tracked it down to the subject of this issue.

What went wrong

main.rs.txt is a simple testbed that highlights this. (Renamed to a supported extension.) It creates several fixed-sized leaf nodes and wraps them with boxes having various border and padding settings then prints out the results of layout:

TREE
└──  FLEX COL [x: 0    y: 0    w: 226  h: 328  content_w: 226  content_h: 328  border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967308))
    ├──  FLEX ROW [x: 0    y: 0    w: 226  h: 50   content_w: 200  content_h: 50   border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967298))
    │   └──  LEAF [x: 0    y: 0    w: 200  h: 50   content_w: 200  content_h: 50   border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967297))
    ├──  FLEX ROW [x: 0    y: 50   w: 226  h: 53   content_w: 203  content_h: 53   border: l:0 r:0 t:0 b:0, padding: l:1 r:2 t:1 b:2] (NodeId(4294967300))
    │   └──  LEAF [x: 1    y: 1    w: 200  h: 50   content_w: 200  content_h: 50   border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967299))
    ├──  FLEX ROW [x: 0    y: 103  w: 226  h: 73   content_w: 211  content_h: 61   border: l:11 r:12 t:11 b:12, padding: l:0 r:0 t:0 b:0] (NodeId(4294967302))
    │   └──  LEAF [x: 11   y: 11   w: 200  h: 50   content_w: 200  content_h: 50   border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967301))
    ├──  FLEX ROW [x: 0    y: 176  w: 226  h: 76   content_w: 214  content_h: 64   border: l:11 r:12 t:11 b:12, padding: l:1 r:2 t:1 b:2] (NodeId(4294967304))
    │   └──  LEAF [x: 12   y: 12   w: 200  h: 50   content_w: 200  content_h: 50   border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967303))
    └──  FLEX ROW [x: 0    y: 252  w: 226  h: 76   content_w: 226  content_h: 76   border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967307))
        └──  FLEX ROW [x: 0    y: 0    w: 226  h: 76   content_w: 214  content_h: 64   border: l:11 r:12 t:11 b:12, padding: l:1 r:2 t:1 b:2] (NodeId(4294967306))
            └──  LEAF [x: 12   y: 12   w: 200  h: 50   content_w: 200  content_h: 50   border: l:0 r:0 t:0 b:0, padding: l:0 r:0 t:0 b:0] (NodeId(4294967305))

(I used the oddball padding/border values so that one could which values got added together.)

The first FLEX ROW (without any padding/border) has the exact same content_size as the leaf node. This is as expected.

The second FLEX ROW (with padding but no border) has the content_size inflated by the padding. Again, as expected.

The third FLEX ROW (with border but no padding) has the content_size inflated by just the left/top values. My expectation is that the content_size would stay the same.

The fourth FLEX ROW (with both) exhibits the sum of the two individual cases.

The last two FLEX ROWs show nesting an incorrectly content_sized box inside a box with no padding/border: the outer boxes content_size includes both the inner boxes padding and border--as it should. So at least the incorrect value is contained at the immediate parent and doesn't bleed further up the tree.

Additional information

I believe that this code is responsible for the above results. content_size starts out as zero then gets maxed with each item's right/bottom content extent. So it is a measure from the container's border box upper left to the lower right corner of the content. The lines referenced then expand the content_size by the container's right padding (calculated by subtracting the border and scrollbar gutter from the inset, which is the sum of the padding, border, and scrollbar gutter).

My supposition is that it should also subtract off the container's left/top border. (I'd also suggest renaming that accumulator something like content_extent to indicate that it is the max extent of the content, not the desired final content_size.)

This is just the flexbox case. I suspect that the other containers exhibit the same but I haven't explored them.

And finally, I'd be happy to put together a PR to address this (and the other containers) if this is in fact a bug and not desired behavior.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions