chat panel: Fix tooltips not working for links (cherry-pick #9691) (#9699)

gcp-cherry-pick-bot[bot] and Bennet Bo Fenner created

Cherry-picked chat panel: Fix tooltips not working for links (#9691)

Closes #9418 

Noticed a difference in the `cx.set_tooltip(...)` calls between `div`
and `InteractiveText`. `div` calls `cx.set_tooltip(...)` inside
`after_layout`, but `InteractiveText` was calling this inside `paint`. I
believe as #9012 was merged, we need to call `cx.set_tooltip` inside
`after_layout`, as inserting inside `paint` does not seem to be
supported anymore.

I moved the code for setting the tooltip to `after_layout` and hovering
over links inside the chat seems to bring up the tooltips again.

Before:

See https://github.com/zed-industries/zed/issues/9418#issue-2189398784

After:



![image](https://github.com/zed-industries/zed/assets/53836821/a623164c-1ce0-40d7-bc53-020f176fba4a)


Release Notes:

- Fixed tooltip not showing up when hovering over links inside the chat
panel ([#9418](https://github.com/zed-industries/zed/issues/9418))

Co-authored-by: Bennet Bo Fenner <53836821+bennetbo@users.noreply.github.com>

Change summary

crates/gpui/src/elements/text.rs | 32 ++++++++++++++++++++------------
1 file changed, 20 insertions(+), 12 deletions(-)

Detailed changes

crates/gpui/src/elements/text.rs 🔗

@@ -415,8 +415,26 @@ impl Element for InteractiveText {
         state: &mut Self::BeforeLayout,
         cx: &mut ElementContext,
     ) -> Hitbox {
-        self.text.after_layout(bounds, state, cx);
-        cx.insert_hitbox(bounds, false)
+        cx.with_element_state::<InteractiveTextState, _>(
+            Some(self.element_id.clone()),
+            |interactive_state, cx| {
+                let interactive_state = interactive_state
+                    .map(|interactive_state| interactive_state.unwrap_or_default());
+
+                if let Some(interactive_state) = interactive_state.as_ref() {
+                    if let Some(active_tooltip) = interactive_state.active_tooltip.borrow().as_ref()
+                    {
+                        if let Some(tooltip) = active_tooltip.tooltip.clone() {
+                            cx.set_tooltip(tooltip);
+                        }
+                    }
+                }
+
+                self.text.after_layout(bounds, state, cx);
+                let hitbox = cx.insert_hitbox(bounds, false);
+                (hitbox, interactive_state)
+            },
+        )
     }
 
     fn paint(
@@ -557,16 +575,6 @@ impl Element for InteractiveText {
                     cx.on_mouse_event(move |_: &MouseDownEvent, _, _| {
                         active_tooltip.take();
                     });
-
-                    if let Some(tooltip) = interactive_state
-                        .active_tooltip
-                        .clone()
-                        .borrow()
-                        .as_ref()
-                        .and_then(|at| at.tooltip.clone())
-                    {
-                        cx.set_tooltip(tooltip);
-                    }
                 }
 
                 self.text.paint(bounds, text_state, &mut (), cx);