diff --git a/crates/gpui/Cargo.toml b/crates/gpui/Cargo.toml index d720dfb2a1..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 = "=0.9.0" +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 09afbff929..4ccdb5b205 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -23,6 +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, LOG_TAFFY}, }; use collections::HashMap; use refineable::Refineable; @@ -1316,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 ee21ecd8c4..b6ee841992 100644 --- a/crates/gpui/src/taffy.rs +++ b/crates/gpui/src/taffy.rs @@ -3,7 +3,7 @@ use crate::{ }; use collections::{FxHashMap, FxHashSet}; use smallvec::SmallVec; -use std::{fmt::Debug, ops::Range}; +use std::{cell::RefCell, fmt::Debug, ops::Range}; use taffy::{ TaffyTree, TraversePartialTree as _, geometry::{Point as TaffyPoint, Rect as TaffyRect, Size as TaffySize}, @@ -11,6 +11,18 @@ use taffy::{ tree::NodeId, }; +thread_local! { + pub static LAYOUT_ID_TO_DEBUG: RefCell> = const { RefCell::new(None) }; +} + +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, >; @@ -26,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(); @@ -49,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 @@ -64,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 @@ -73,7 +114,7 @@ impl TaffyLayoutEngine { &mut self, style: Style, rem_size: Pixels, - measure: impl FnMut( + mut measure: impl FnMut( Size>, Size, &mut Window, @@ -83,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 } @@ -198,6 +256,16 @@ impl TaffyLayoutEngine { ) .expect(EXPECT_MESSAGE); + /* + 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); + }); + */ + // println!("compute_layout took {:?}", started_at.elapsed()); } diff --git a/crates/language_models/src/provider/open_router.rs b/crates/language_models/src/provider/open_router.rs index 3a492086f1..aad113c565 100644 --- a/crates/language_models/src/provider/open_router.rs +++ b/crates/language_models/src/provider/open_router.rs @@ -853,25 +853,15 @@ impl Render for ConfigurationView { div().child(Label::new("Loading credentials...")).into_any() } else if self.should_render_editor(cx) { v_flex() + .id("open-router-container") .size_full() .on_action(cx.listener(Self::save_api_key)) - .child(Label::new("To use Zed's agent with OpenRouter, you need to add an API key. Follow these steps:")) + .child(Label::new( + "To use Zed's agent with OpenRouter, you need to add an API key.", + )) .child( - List::new() - .child(InstructionListItem::new( - "Create an API key by visiting", - Some("OpenRouter's console"), - Some("https://openrouter.ai/keys"), - )) - .child(InstructionListItem::text_only( - "Ensure your OpenRouter account has credits", - )) - .child(InstructionListItem::text_only( - "Paste your API key below and hit enter to start using the assistant", - )), - ) - .child( - h_flex() + div() + .id("api-key-editor") .w_full() .my_2() .px_2() @@ -882,12 +872,6 @@ impl Render for ConfigurationView { .rounded_sm() .child(self.render_api_key_editor(cx)), ) - .child( - Label::new( - format!("You can also assign the {OPENROUTER_API_KEY_VAR} environment variable and restart Zed."), - ) - .size(LabelSize::Small).color(Color::Muted), - ) .into_any() } else { h_flex()