Instead try to output something close to taffy api usage

Michael Sloan created

Change summary

crates/gpui/Cargo.toml          |  2 
crates/gpui/src/element.rs      | 26 ++++++++++++
crates/gpui/src/elements/div.rs | 31 ++++++--------
crates/gpui/src/taffy.rs        | 72 ++++++++++++++++++++++++++++++----
4 files changed, 101 insertions(+), 30 deletions(-)

Detailed changes

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

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<E: Element> Drawable<E> {
                     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<E: Element> Drawable<E> {
                     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();
                 }

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::<SmallVec<_>>();
-                        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<Hitbox> {
+        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()

crates/gpui/src/taffy.rs 🔗

@@ -19,6 +19,10 @@ thread_local! {
     pub static CONTAINER_LAYOUT_ID_TO_DEBUG: RefCell<Option<LayoutId>> = const { RefCell::new(None) };
 }
 
+thread_local! {
+    pub static LOG_TAFFY: RefCell<bool> = const { RefCell::new(false) };
+}
+
 type NodeMeasureFn = Box<
     dyn FnMut(Size<Option<Pixels>>, Size<AvailableSpace>, &mut Window, &mut App) -> Size<Pixels>,
 >;
@@ -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::<Vec<_>>()
+                        .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<Option<Pixels>>,
             Size<AvailableSpace>,
             &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());
     }