Skip to content

Commit b627b66

Browse files
committed
partial_renderer: Fix visible:true-expr item being always dirty
The issue is that an element with visibility creates a `Clip` item as a parent with a size of 0x0, and the clip property. When the visible property becomes true, the tracker for this Clip item will be dirty and will force everything inside to be re-drawn. But since the `Clip` itself is no longer clipping and its size is 0, the special code in `iterm_rendering::render_item_children` that handle the clip specially will not kick in, and the `Clip` itself will not go through the partial renderer, so its tracker will stay dirty forever
1 parent 5fd12cd commit b627b66

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

api/rs/slint/tests/partial_renderer.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ fn visibility() {
244244
slint::slint! {
245245
export component Ui inherits Window {
246246
in property <bool> c : true;
247+
in property <bool> another: false;
247248
background: black;
248249
Rectangle {
249250
x: 10phx;
@@ -255,6 +256,13 @@ fn visibility() {
255256
height: 13phx;
256257
background: red;
257258
visible: c;
259+
Rectangle {
260+
x: 3phx;
261+
y: 3phx;
262+
width: 3phx;
263+
height: 3phx;
264+
background: another ? blue: green;
265+
}
258266
}
259267
Rectangle {
260268
x: 50phx;
@@ -263,6 +271,13 @@ fn visibility() {
263271
height: 17phx;
264272
background: gray;
265273
visible: !c;
274+
Rectangle {
275+
x: 3phx;
276+
y: 3phx;
277+
width: 3phx;
278+
height: 3phx;
279+
background: another ? blue: green;
280+
}
266281
}
267282
}
268283
}
@@ -277,16 +292,28 @@ fn visibility() {
277292
do_test_render_region(renderer, 0, 0, 180, 260);
278293
}));
279294
assert!(!window.draw_if_needed(|_| { unreachable!() }));
295+
280296
ui.set_c(false);
281297
assert!(window.draw_if_needed(|renderer| {
282298
do_test_render_region(renderer, 10 + 5, 19 + 8, 10 + 50 + 15, 19 + 80 + 13);
283299
}));
284300
assert!(!window.draw_if_needed(|_| { unreachable!() }));
301+
ui.set_another(true);
302+
assert!(window.draw_if_needed(|renderer| {
303+
do_test_render_region(renderer, 10 + 50 + 3, 19 + 8 + 3, 10 + 50 + 6, 19 + 8 + 6);
304+
}));
305+
assert!(!window.draw_if_needed(|_| { unreachable!() }));
306+
285307
ui.set_c(true);
286308
assert!(window.draw_if_needed(|renderer| {
287309
do_test_render_region(renderer, 10 + 5, 19 + 8, 10 + 50 + 15, 19 + 80 + 13);
288310
}));
289311
assert!(!window.draw_if_needed(|_| { unreachable!() }));
312+
ui.set_another(false);
313+
assert!(window.draw_if_needed(|renderer| {
314+
do_test_render_region(renderer, 10 + 5 + 3, 19 + 80 + 3, 10 + 5 + 6, 19 + 80 + 6);
315+
}));
316+
assert!(!window.draw_if_needed(|_| { unreachable!() }));
290317
}
291318

292319
#[test]

internal/core/partial_renderer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,11 @@ impl<'a, T: ItemRenderer + ItemRendererFeatures> PartialRenderer<'a, T> {
432432
// When the opacity or the clip change, this will impact all the children, including
433433
// the ones outside the element, regardless if they are themselves dirty or not.
434434
new_state.must_refresh_children |= rendering_dirty || geometry_changed;
435+
436+
if rendering_dirty {
437+
// Destroy the tracker as we we might not re-render this clipped item but it would stay dirty
438+
*tracker = None;
439+
}
435440
}
436441

437442
if geometry_changed {

0 commit comments

Comments
 (0)