From 829713b9e211f120e3aba2cfe18ef1348aee43b7 Mon Sep 17 00:00:00 2001 From: edwloef Date: Sat, 30 May 2026 10:33:46 +0200 Subject: [PATCH 1/3] `diff` `scrollable` state based on `id` --- widget/src/scrollable.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index eccaa21115..9b97235fde 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -381,7 +381,7 @@ where } fn state(&self) -> tree::State { - tree::State::new(State::new()) + tree::State::new(State::new(self.id.clone())) } fn diff(&mut self, tree: &mut Tree) { @@ -396,6 +396,10 @@ where if self.direction.vertical().is_none() { self.height = self.height.enclose(size.height); } + + if tree.state.downcast_mut::().last_id != self.id { + tree.state = self.state(); + } } fn size(&self) -> Size { @@ -1489,7 +1493,7 @@ fn notify_viewport( true } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] struct State { offset_y: Offset, offset_x: Offset, @@ -1497,6 +1501,7 @@ struct State { keyboard_modifiers: keyboard::Modifiers, last_notified: Option, last_scrolled: Option, + last_id: Option, is_scrollbar_visible: bool, } @@ -1513,20 +1518,6 @@ enum Interaction { }, } -impl Default for State { - fn default() -> Self { - Self { - offset_y: Offset::Absolute(0.0), - offset_x: Offset::Absolute(0.0), - interaction: Interaction::None, - keyboard_modifiers: keyboard::Modifiers::default(), - last_notified: None, - last_scrolled: None, - is_scrollbar_visible: true, - } - } -} - impl operation::Scrollable for State { fn snap_to(&mut self, offset: RelativeOffset>) { State::snap_to(self, offset); @@ -1623,8 +1614,17 @@ impl Viewport { } impl State { - fn new() -> Self { - State::default() + fn new(last_id: Option) -> Self { + Self { + offset_y: Offset::Absolute(0.0), + offset_x: Offset::Absolute(0.0), + interaction: Interaction::None, + keyboard_modifiers: keyboard::Modifiers::default(), + last_notified: None, + last_scrolled: None, + last_id, + is_scrollbar_visible: true, + } } fn scroll(&mut self, delta: Vector, bounds: Rectangle, content_bounds: Rectangle) { From af86ea99a983dc4f74a788e93c7d929abbdbe20f Mon Sep 17 00:00:00 2001 From: edwloef Date: Sat, 30 May 2026 11:06:23 +0200 Subject: [PATCH 2/3] `diff` `text_input` state based on `id` --- widget/src/text_input.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index 942a1ccf13..69a8dad9a7 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -600,7 +600,7 @@ where } fn state(&self) -> tree::State { - tree::State::new(State::::new()) + tree::State::new(State::::new(self.id.clone())) } fn diff(&mut self, tree: &mut Tree) { @@ -610,6 +610,10 @@ where if self.on_input.is_none() { state.is_pasting = None; } + + if state.last_id != self.id { + tree.state = self.state(); + } } fn size(&self) -> Size { @@ -1371,6 +1375,7 @@ pub struct State { last_click: Option, cursor: Cursor, keyboard_modifiers: keyboard::Modifiers, + last_id: Option, // TODO: Add stateful horizontal scrolling offset } @@ -1399,8 +1404,11 @@ enum Paste { impl State

{ /// Creates a new [`State`], representing an unfocused [`TextInput`]. - pub fn new() -> Self { - Self::default() + pub fn new(last_id: Option) -> Self { + Self { + last_id, + ..Self::default() + } } /// Returns whether the [`TextInput`] is currently focused or not. From 30437822d8e551baccf782d85b26537699859a62 Mon Sep 17 00:00:00 2001 From: edwloef Date: Sat, 30 May 2026 11:08:14 +0200 Subject: [PATCH 3/3] `diff` `text_editor` state based on `id` --- widget/src/text_editor.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 344520c0a8..653bce3960 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -496,6 +496,7 @@ pub struct State { preedit: Option, last_click: Option, drag_click: Option, + last_id: Option, partial_scroll: f32, last_theme: RefCell>, highlighter: RefCell, @@ -568,6 +569,7 @@ where preedit: None, last_click: None, drag_click: None, + last_id: self.id.clone(), partial_scroll: 0.0, last_theme: RefCell::default(), highlighter: RefCell::new(Highlighter::new(&self.highlighter_settings)), @@ -576,6 +578,12 @@ where }) } + fn diff(&mut self, tree: &mut widget::Tree) { + if tree.state.downcast_mut::>().last_id != self.id { + tree.state = self.state(); + } + } + fn size(&self) -> Size { Size { width: self.width,