Fix agent panel scroll while editing a past message (#30394)

Michael Sloan created

This is similar to the `block_mouse_down` method added in #20649 (which
has a very similar motivation), but is more comprehensive in stopping
mouse events. Since I want to cherry-pick this to the releases, keeping
this change just to the agent panel. In a follow-up will replace
existing use of `block_mouse_down` to instead use this.

Release Notes:

- N/A

Change summary

crates/agent/src/active_thread.rs |  2 +-
crates/gpui/src/elements/div.rs   | 21 ++++++++++++++++++---
2 files changed, 19 insertions(+), 4 deletions(-)

Detailed changes

crates/agent/src/active_thread.rs 🔗

@@ -2235,7 +2235,7 @@ impl ActiveThread {
                 // Backdrop to dim out the whole thread below the editing user message
                 parent.relative().child(
                     div()
-                        .occlude()
+                        .stop_mouse_events_except_scroll()
                         .absolute()
                         .inset_0()
                         .size_full()

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

@@ -490,7 +490,7 @@ impl Interactivity {
 
     /// Bind the given callback on the hover start and end events of this element. Note that the boolean
     /// passed to the callback is true when the hover starts and false when it ends.
-    /// The imperative API equivalent to [`StatefulInteractiveElement::on_drag`]
+    /// The imperative API equivalent to [`StatefulInteractiveElement::on_hover`]
     ///
     /// See [`Context::listener`](crate::Context::listener) to get access to a view's state from this callback.
     pub fn on_hover(&mut self, listener: impl Fn(&bool, &mut Window, &mut App) + 'static)
@@ -544,6 +544,15 @@ impl Interactivity {
     pub fn occlude_mouse(&mut self) {
         self.occlude_mouse = true;
     }
+
+    /// Registers event handles that stop propagation of mouse events for non-scroll events.
+    /// The imperative API equivalent to [`InteractiveElement::block_mouse_except_scroll`]
+    pub fn stop_mouse_events_except_scroll(&mut self) {
+        self.on_any_mouse_down(|_, _, cx| cx.stop_propagation());
+        self.on_any_mouse_up(|_, _, cx| cx.stop_propagation());
+        self.on_click(|_, _, cx| cx.stop_propagation());
+        self.on_hover(|_, _, cx| cx.stop_propagation());
+    }
 }
 
 /// A trait for elements that want to use the standard GPUI event handlers that don't
@@ -919,11 +928,17 @@ pub trait InteractiveElement: Sized {
         self
     }
 
-    /// Block the mouse from interacting with this element or any of its children
-    /// The fluent API equivalent to [`Interactivity::occlude_mouse`]
+    /// Stops propagation of left mouse down event.
     fn block_mouse_down(mut self) -> Self {
         self.on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation())
     }
+
+    /// Registers event handles that stop propagation of mouse events for non-scroll events.
+    /// The fluent API equivalent to [`Interactivity::block_mouse_except_scroll`]
+    fn stop_mouse_events_except_scroll(mut self) -> Self {
+        self.interactivity().stop_mouse_events_except_scroll();
+        self
+    }
 }
 
 /// A trait for elements that want to use the standard GPUI interactivity features