diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index 0bf0cd8c0f..72758a9dca 100644 --- a/crates/gpui/Cargo.toml +++ b/crates/gpui/Cargo.toml @@ -121,7 +121,7 @@ smallvec.workspace = true smol.workspace = true strum.workspace = true sum_tree.workspace = true -taffy = { version = "=0.9.0", features = ["debug"] } +taffy = { version = "=0.9.0", features = ["serde"] } thiserror.workspace = true util.workspace = true uuid.workspace = true diff --git a/crates/gpui/src/element.rs b/crates/gpui/src/element.rs index e5f49c7be1..31177d666b 100644 --- a/crates/gpui/src/element.rs +++ b/crates/gpui/src/element.rs @@ -34,7 +34,7 @@ use crate::{ App, ArenaBox, AvailableSpace, Bounds, Context, DispatchNodeId, ELEMENT_ARENA, ElementId, FocusHandle, InspectorElementId, LayoutId, Pixels, Point, Size, Style, Window, - util::FluentBuilder, + taffy::LOG_TAFFY, util::FluentBuilder, }; use derive_more::{Deref, DerefMut}; pub(crate) use smallvec::SmallVec; @@ -372,6 +372,22 @@ impl Drawable { inspector_id = None; } + let should_start_logging = global_id + .as_ref() + .map(|id| { + id.0.last() + .map(|last| last == &"open-router-container".into()) + .unwrap_or(false) + }) + .unwrap_or(false); + + if should_start_logging { + println!("Starting taffy logging for element"); + LOG_TAFFY.with_borrow_mut(|log_taffy| { + *log_taffy = true; + }); + } + let (layout_id, request_layout) = self.element.request_layout( global_id.as_ref(), inspector_id.as_ref(), @@ -379,6 +395,14 @@ impl Drawable { cx, ); + // Only turn off logging if this element started it + if should_start_logging { + println!("Stopping taffy logging for element"); + LOG_TAFFY.with_borrow_mut(|log_taffy| { + *log_taffy = false; + }); + } + if global_id.is_some() { window.element_id_stack.pop(); } diff --git a/crates/gpui/src/elements/div.rs b/crates/gpui/src/elements/div.rs index 0669d36b2c..4ccdb5b205 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -23,7 +23,7 @@ use crate::{ MouseClickEvent, MouseDownEvent, MouseMoveEvent, MouseUpEvent, Overflow, ParentElement, Pixels, Point, Render, ScrollWheelEvent, SharedString, Size, Style, StyleRefinement, Styled, Task, TooltipId, Visibility, Window, WindowControlArea, point, px, size, - taffy::{CONTAINER_LAYOUT_ID_TO_DEBUG, LAYOUT_ID_TO_DEBUG}, + taffy::{CONTAINER_LAYOUT_ID_TO_DEBUG, LAYOUT_ID_TO_DEBUG, LOG_TAFFY}, }; use collections::HashMap; use refineable::Refineable; @@ -1299,23 +1299,7 @@ impl Element for Div { .iter_mut() .map(|child| child.request_layout(window, cx)) .collect::>(); - let layout_id = - window.request_layout(style, child_layout_ids.iter().copied(), cx); - if let Some(global_id) = global_id.as_ref() - && global_id.0.ends_with(&["api-key-editor".into()]) - { - LAYOUT_ID_TO_DEBUG.with_borrow_mut(|layout_id_to_debug| { - *layout_id_to_debug = Some(layout_id) - }); - } - if let Some(global_id) = global_id.as_ref() - && global_id.0.ends_with(&["open-router-container".into()]) - { - CONTAINER_LAYOUT_ID_TO_DEBUG.with_borrow_mut(|layout_id_to_debug| { - *layout_id_to_debug = Some(layout_id) - }); - } - layout_id + window.request_layout(style, child_layout_ids.iter().copied(), cx) }) }, ) @@ -1333,6 +1317,17 @@ impl Element for Div { window: &mut Window, cx: &mut App, ) -> Option { + if let Some(global_id) = global_id + && global_id.0.ends_with(&["open-router-container".into()]) + { + println!("open-router-container bounds = {:?}", bounds) + } + if let Some(global_id) = global_id + && global_id.0.ends_with(&["api-key-editor".into()]) + { + println!("api-key-editor bounds = {:?}", bounds) + } + let has_prepaint_listener = self.prepaint_listener.is_some(); let mut children_bounds = Vec::with_capacity(if has_prepaint_listener { request_layout.child_layout_ids.len() diff --git a/crates/gpui/src/taffy.rs b/crates/gpui/src/taffy.rs index 61736e456c..b6ee841992 100644 --- a/crates/gpui/src/taffy.rs +++ b/crates/gpui/src/taffy.rs @@ -19,6 +19,10 @@ thread_local! { pub static CONTAINER_LAYOUT_ID_TO_DEBUG: RefCell> = const { RefCell::new(None) }; } +thread_local! { + pub static LOG_TAFFY: RefCell = const { RefCell::new(false) }; +} + type NodeMeasureFn = Box< dyn FnMut(Size>, Size, &mut Window, &mut App) -> Size, >; @@ -34,6 +38,11 @@ pub struct TaffyLayoutEngine { const EXPECT_MESSAGE: &str = "we should avoid taffy layout errors by construction if possible"; +fn layout_id_to_var_name(layout_id: LayoutId) -> String { + let node_id: u64 = layout_id.clone().0.into(); + format!("node_{}", node_id) +} + impl TaffyLayoutEngine { pub fn new() -> Self { let mut taffy = TaffyTree::new(); @@ -57,12 +66,23 @@ impl TaffyLayoutEngine { rem_size: Pixels, children: &[LayoutId], ) -> LayoutId { + let should_log = LOG_TAFFY.with_borrow(|log_taffy| *log_taffy); let taffy_style = style.to_taffy(rem_size); let layout_id = if children.is_empty() { - self.taffy + let layout_id = self + .taffy .new_leaf(taffy_style) .expect(EXPECT_MESSAGE) - .into() + .into(); + if should_log { + let var_name = layout_id_to_var_name(layout_id); + println!( + "let {} = taffy.new_leaf({:?}).unwrap();", + var_name, + serde_json::to_string(&style.to_taffy(rem_size)).unwrap(), + ); + } + layout_id } else { let parent_id = self .taffy @@ -72,6 +92,19 @@ impl TaffyLayoutEngine { }) .expect(EXPECT_MESSAGE) .into(); + if should_log { + let var_name = layout_id_to_var_name(parent_id); + println!( + "let {} = taffy.new_with_children({:?}, &[{:?}]).unwrap();", + var_name, + serde_json::to_string(&style.to_taffy(rem_size)).unwrap(), + children + .iter() + .map(|id| layout_id_to_var_name(*id)) + .collect::>() + .join(", ") + ); + } parent_id }; layout_id @@ -81,7 +114,7 @@ impl TaffyLayoutEngine { &mut self, style: Style, rem_size: Pixels, - measure: impl FnMut( + mut measure: impl FnMut( Size>, Size, &mut Window, @@ -91,16 +124,33 @@ impl TaffyLayoutEngine { ) -> LayoutId { let taffy_style = style.to_taffy(rem_size); + let should_log = LOG_TAFFY.with_borrow(|log_taffy| *log_taffy); + let layout_id = self .taffy .new_leaf_with_context( taffy_style, NodeContext { - measure: Box::new(measure), + measure: Box::new(move |size, available_space, window, app| { + let result = measure(size, available_space, window, app); + if should_log { + println!("measure({:?}, {:?}) == {:?}", size, available_space, result); + } + result + }), }, ) .expect(EXPECT_MESSAGE) .into(); + + if should_log { + println!( + "let {} = taffy.new_leaf_with_context({:?}, MEASURE_CONTEXT).unwrap()", + layout_id_to_var_name(layout_id), + serde_json::to_string(&style.to_taffy(rem_size)).unwrap(), + ); + } + layout_id } @@ -206,13 +256,15 @@ impl TaffyLayoutEngine { ) .expect(EXPECT_MESSAGE); - LAYOUT_ID_TO_DEBUG.with_borrow(|layout_id_to_debug| { - println!("Layout ID Debug: {:?}", layout_id_to_debug); - }); + /* + LAYOUT_ID_TO_DEBUG.with_borrow(|layout_id_to_debug| { + println!("Layout ID Debug: {:?}", layout_id_to_debug); + }); - CONTAINER_LAYOUT_ID_TO_DEBUG.with_borrow(|layout_id| { - println!("Container Layout ID Debug: {:?}\n", layout_id); - }); + CONTAINER_LAYOUT_ID_TO_DEBUG.with_borrow(|layout_id| { + println!("Container Layout ID Debug: {:?}\n", layout_id); + }); + */ // println!("compute_layout took {:?}", started_at.elapsed()); }