From 8087d26f9e025e4c02248aab0fb16560768139a8 Mon Sep 17 00:00:00 2001 From: Marc Espin Date: Sun, 6 Oct 2024 10:08:23 +0200 Subject: [PATCH] fix: Avoid trigering side effects in orphan nodes updates (#959) --- crates/state/src/accessibility.rs | 4 +++- crates/state/src/cursor.rs | 6 +++++- crates/state/src/font_style.rs | 5 ++++- crates/state/src/layer.rs | 6 +++++- crates/state/src/layout.rs | 5 ++++- crates/state/src/transform.rs | 5 ++++- 6 files changed, 25 insertions(+), 6 deletions(-) diff --git a/crates/state/src/accessibility.rs b/crates/state/src/accessibility.rs index 2e7ecb261..bcbdb0221 100644 --- a/crates/state/src/accessibility.rs +++ b/crates/state/src/accessibility.rs @@ -459,7 +459,9 @@ impl State for AccessibilityNodeState { *self = accessibility; - if changed { + let is_orphan = node_view.height() == 0 && node_view.node_id() != *root_id; + + if changed && !is_orphan { // Assign an accessibility ID if none was passed but the node has a valid builder // // In our case, builder will be `None` if the node's tag cannot be added to accessibility diff --git a/crates/state/src/cursor.rs b/crates/state/src/cursor.rs index 6dcb5bbc2..f629507a0 100644 --- a/crates/state/src/cursor.rs +++ b/crates/state/src/cursor.rs @@ -21,6 +21,7 @@ use freya_native_core::{ State, }, tags::TagName, + NodeId, SendAnyMap, }; use freya_native_core_macro::partial_derive_state; @@ -151,6 +152,7 @@ impl State for CursorState { _children: Vec<::ElementBorrowed<'a>>, context: &SendAnyMap, ) -> bool { + let root_id = context.get::().unwrap(); let paragraphs = context.get::>>().unwrap(); let compositor_dirty_nodes = context.get::>>().unwrap(); let mut cursor = parent.map(|(p,)| p.clone()).unwrap_or_default(); @@ -162,7 +164,9 @@ impl State for CursorState { } let changed = &cursor != self; - if changed && CursorMode::Editable == cursor.mode { + let is_orphan = node_view.height() == 0 && node_view.node_id() != *root_id; + + if changed && CursorMode::Editable == cursor.mode && !is_orphan { if let Some((tag, cursor_ref)) = node_view.tag().zip(cursor.cursor_ref.as_ref()) { if *tag == TagName::Paragraph { paragraphs diff --git a/crates/state/src/font_style.rs b/crates/state/src/font_style.rs index 54f215a0a..81005d484 100644 --- a/crates/state/src/font_style.rs +++ b/crates/state/src/font_style.rs @@ -277,6 +277,7 @@ impl State for FontStyleState { _children: Vec<::ElementBorrowed<'a>>, context: &SendAnyMap, ) -> bool { + let root_id = context.get::().unwrap(); let torin_layout = context.get::>>>().unwrap(); let compositor_dirty_nodes = context.get::>>().unwrap(); @@ -290,7 +291,9 @@ impl State for FontStyleState { let changed = &font_style != self; - if changed { + let is_orphan = node_view.height() == 0 && node_view.node_id() != *root_id; + + if changed && !is_orphan { torin_layout.lock().unwrap().invalidate(node_view.node_id()); compositor_dirty_nodes .lock() diff --git a/crates/state/src/layer.rs b/crates/state/src/layer.rs index fc5d7c616..24bed3c99 100644 --- a/crates/state/src/layer.rs +++ b/crates/state/src/layer.rs @@ -14,6 +14,7 @@ use freya_native_core::{ NodeMaskBuilder, State, }, + NodeId, SendAnyMap, }; use freya_native_core_macro::partial_derive_state; @@ -75,6 +76,7 @@ impl State for LayerState { return false; } + let root_id = context.get::().unwrap(); let layers = context.get::>>().unwrap(); let inherited_layer = parent.map(|(p,)| p.layer_for_children).unwrap_or(0i16); @@ -91,7 +93,9 @@ impl State for LayerState { let changed = &layer_state != self; - if changed { + let is_orphan = node_view.height() == 0 && node_view.node_id() != *root_id; + + if changed && !is_orphan { layers .lock() .unwrap() diff --git a/crates/state/src/layout.rs b/crates/state/src/layout.rs index 939ebcd01..753123534 100644 --- a/crates/state/src/layout.rs +++ b/crates/state/src/layout.rs @@ -221,6 +221,7 @@ impl State for LayoutState { _children: Vec<::ElementBorrowed<'a>>, context: &SendAnyMap, ) -> bool { + let root_id = context.get::().unwrap(); let torin_layout = context.get::>>>().unwrap(); let compositor_dirty_nodes = context.get::>>().unwrap(); @@ -237,7 +238,9 @@ impl State for LayoutState { let changed = layout != *self; - if changed { + let is_orphan = node_view.height() == 0 && node_view.node_id() != *root_id; + + if changed && !is_orphan { torin_layout.lock().unwrap().invalidate(node_view.node_id()); compositor_dirty_nodes .lock() diff --git a/crates/state/src/transform.rs b/crates/state/src/transform.rs index d7dfc634d..2d0569722 100644 --- a/crates/state/src/transform.rs +++ b/crates/state/src/transform.rs @@ -85,6 +85,7 @@ impl State for TransformState { _children: Vec<::ElementBorrowed<'a>>, context: &SendAnyMap, ) -> bool { + let root_id = context.get::().unwrap(); let compositor_dirty_nodes = context.get::>>().unwrap(); let inherited_transform = parent.map(|(p,)| p.clone()).unwrap_or_default(); @@ -101,7 +102,9 @@ impl State for TransformState { let changed = transform_state != *self; - if changed { + let is_orphan = node_view.height() == 0 && node_view.node_id() != *root_id; + + if changed && !is_orphan { compositor_dirty_nodes .lock() .unwrap()