Hold a clipping widget to its box, and check that it is
`Scroll` reports `LEFTOVER` on both axes because it clips its content to its box: it can neither take less of one nor honestly ask for more. `Masked` is the other widget that clips and was passing its inner's size up, so a mask over something taller than its box asked to be placed at the length it had just cut off. It reports its box now, for the same reason. The `debug_assert` the handoff has been asking for is the one that would have caught both, narrowed to what is actually true: a widget that set a mask this draw has to report inside the box it drew in. Reported as "does not exceed the box" it fires on ordinary overflow instead -- measured, a hundred fuzzer trees produce thousands of them, every one a text too tall for the box it was offered, which is what a text is meant to say. `tests/cases/scroll.rs` has a clipping widget that reports its content, to show the assertion catches it. Checked: fmt, clippy, 104 tests, all five shrinker cases at 300 seeds, 100 generated seeds, five examples byte-identical at 1920x1200. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
bdab55824f
commit
95fb4f962c
3 files changed
+49
-1
No files matched your search
@@ -59,3 +59,26 @@ fn a_wheel_scrolls_the_content_and_stops_at_its_end() {
|
||||
h.frame();
|
||||
assert_corners!(h, top, (0, 0), (400, 200));
|
||||
}
|
||||
|
||||
/// A widget that clips to its box may not report more than the box: its
|
||||
/// parent would place the part it cut off, and the framework would put a
|
||||
/// drawing longer than its box somewhere. `Masked` is the second of these
|
||||
/// after `Scroll`, and the assertion in `draw_at` is what says so.
|
||||
#[test]
|
||||
#[should_panic = "clips to"]
|
||||
fn a_clipping_widget_reporting_more_than_its_box_is_caught() {
|
||||
struct Clipper(StrongWidget);
|
||||
|
||||
impl Widget for Clipper {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
painter.set_mask(painter.region());
|
||||
painter.widget(&self.0).size()
|
||||
}
|
||||
}
|
||||
|
||||
let mut h = Harness::new((100, 100));
|
||||
let tall = rect(Color::RED).height(400).add_strong(&mut h.rsc);
|
||||
let clipper = Clipper(tall).add(&mut h.rsc);
|
||||
h.set_root(clipper);
|
||||
h.frame();
|
||||
}
|
||||
Reference in new issue
Block a user