Make iris ask for the frame a resize needs

`update` redrew everything when `resized` was set, but `needs_redraw` --
which is what decides whether to request a frame at all -- did not know
about `resized`. A condition in one and not the other is a frame nobody
asks for and a stale window. The two share one `needs_redraw_all` now.

Latent on Wayland, because winit requests a redraw after a resize by
itself; a resize changes neither the root nor any widget, so nothing else
here would have asked. It stops being latent on Android, where the
surface work will not have winit underneath it and every rotation and
keyboard open is a resize.

This is not a fix for the startup defect recorded in RUST.md, where the
window keeps its pre-configure layout: that reproduces with this change
in place, and the frame it needs is requested and drawn.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-13 00:26:19 -04:00
1 parent fae21a1991
commit 6884160bfe
1 file changed
+29 -2
+29 -2
View File
@@ -52,7 +52,7 @@ impl UiRenderState {
);
}
let root = root.into();
if self.root_changed(root) || self.resized {
if self.needs_redraw_all(root) {
self.redraw_all(root, rsc);
self.old_root = root.map(|r| r.id());
self.resized = false;
@@ -218,12 +218,24 @@ impl UiRenderState {
root.into().map(|r| r.id()) != self.old_root
}
/// What `update` will redraw everything for. Named and shared with
/// `needs_redraw` rather than written out twice, because the two must
/// agree: `needs_redraw` is what asks for the frame that `update` would
/// draw, so a condition in one and not the other is a frame nobody
/// requests and a stale window. `resized` was missing from `needs_redraw`,
/// which is latent on Wayland only because winit asks for a redraw after a
/// resize by itself -- a resize changes neither the root nor any widget,
/// so nothing else here would have asked.
fn needs_redraw_all<'a>(&self, root: impl Into<Option<&'a StrongWidget>>) -> bool {
self.root_changed(root) || self.resized
}
pub fn needs_redraw<'a>(
&self,
root: impl Into<Option<&'a StrongWidget>>,
widgets: &Widgets,
) -> bool {
self.root_changed(root) || widgets.has_updates()
self.needs_redraw_all(root) || widgets.has_updates()
}
pub fn active_widgets(&self) -> usize {
@@ -317,3 +329,18 @@ impl Default for UiRenderState {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_resize_requests_a_frame_without_widget_changes() {
let widgets = Widgets::new();
let mut state = UiRenderState::new();
assert!(!state.needs_redraw(None::<&StrongWidget>, &widgets));
state.resize((800, 600));
assert!(state.needs_redraw(None::<&StrongWidget>, &widgets));
}
}