From 040cc4d4c3eb9d968e5accbe4672a1120d67a737 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 3 May 2023 19:25:00 +0200 Subject: [PATCH] Allow notifying views when the ancestry of another view is outdated --- crates/gpui/src/app.rs | 5 +++-- crates/gpui/src/app/window.rs | 21 ++++++++++++++++++++- crates/gpui/src/elements.rs | 7 ++++--- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 355e8215e7..0b618d8e6d 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -25,6 +25,7 @@ use std::{ use anyhow::{anyhow, Context, Result}; use parking_lot::Mutex; use postage::oneshot; +use smallvec::SmallVec; use smol::prelude::*; use util::ResultExt; use uuid::Uuid; @@ -3198,7 +3199,7 @@ impl BorrowWindowContext for ViewContext<'_, '_, V> { pub struct LayoutContext<'a, 'b, 'c, V: View> { view_context: &'c mut ViewContext<'a, 'b, V>, new_parents: &'c mut HashMap, - views_to_notify_if_ancestors_change: &'c mut HashSet, + views_to_notify_if_ancestors_change: &'c mut HashMap>, pub refreshing: bool, } @@ -3206,7 +3207,7 @@ impl<'a, 'b, 'c, V: View> LayoutContext<'a, 'b, 'c, V> { pub fn new( view_context: &'c mut ViewContext<'a, 'b, V>, new_parents: &'c mut HashMap, - views_to_notify_if_ancestors_change: &'c mut HashSet, + views_to_notify_if_ancestors_change: &'c mut HashMap>, refreshing: bool, ) -> Self { Self { diff --git a/crates/gpui/src/app/window.rs b/crates/gpui/src/app/window.rs index 606cfc9a24..a96d937b1b 100644 --- a/crates/gpui/src/app/window.rs +++ b/crates/gpui/src/app/window.rs @@ -933,7 +933,7 @@ impl<'a> WindowContext<'a> { let root_view_id = self.window.root_view().id(); let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap(); let mut new_parents = HashMap::default(); - let mut views_to_notify_if_ancestors_change = HashSet::default(); + let mut views_to_notify_if_ancestors_change = HashMap::default(); rendered_root.layout( SizeConstraint::strict(window_size), &mut new_parents, @@ -942,6 +942,25 @@ impl<'a> WindowContext<'a> { self, )?; + for (view_id, view_ids_to_notify) in views_to_notify_if_ancestors_change { + let mut current_view_id = view_id; + loop { + let old_parent_id = self.window.parents.get(¤t_view_id); + let new_parent_id = new_parents.get(¤t_view_id); + if old_parent_id.is_none() && new_parent_id.is_none() { + break; + } else if old_parent_id == new_parent_id { + current_view_id = *old_parent_id.unwrap(); + } else { + let window_id = self.window_id; + for view_id_to_notify in view_ids_to_notify { + self.notify_view(window_id, view_id_to_notify); + } + break; + } + } + } + self.window.parents = new_parents; self.window .rendered_views diff --git a/crates/gpui/src/elements.rs b/crates/gpui/src/elements.rs index 073d12c329..e2c4af143c 100644 --- a/crates/gpui/src/elements.rs +++ b/crates/gpui/src/elements.rs @@ -37,9 +37,10 @@ use crate::{ WindowContext, }; use anyhow::{anyhow, Result}; -use collections::{HashMap, HashSet}; +use collections::HashMap; use core::panic; use json::ToJson; +use smallvec::SmallVec; use std::{ any::Any, borrow::Cow, @@ -648,7 +649,7 @@ pub trait AnyRootElement { &mut self, constraint: SizeConstraint, new_parents: &mut HashMap, - views_to_notify_if_ancestors_change: &mut HashSet, + views_to_notify_if_ancestors_change: &mut HashMap>, refreshing: bool, cx: &mut WindowContext, ) -> Result; @@ -673,7 +674,7 @@ impl AnyRootElement for RootElement { &mut self, constraint: SizeConstraint, new_parents: &mut HashMap, - views_to_notify_if_ancestors_change: &mut HashSet, + views_to_notify_if_ancestors_change: &mut HashMap>, refreshing: bool, cx: &mut WindowContext, ) -> Result {