Fix sluggish experience when dragging tabs (#3731)

Antonio Scandurra created

The problem was caused by a missing call to `WindowContext::notify` when
moving the mouse. Actually, we *did* notify as part of a
`MouseMoveEvent` listener registered in `Interactivity` but that code
path was never exercised because we were clearing the
`pending_mouse_down`.

This pull request fixes the issue by automatically redrawing the window
in gpui when there is an active drag and the mouse moves.

Release Notes:

- N/A

Change summary

crates/gpui2/src/elements/div.rs | 11 +++++------
crates/gpui2/src/window.rs       | 17 +++++++++++++----
2 files changed, 18 insertions(+), 10 deletions(-)

Detailed changes

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

@@ -1186,14 +1186,13 @@ impl Interactivity {
                 cx.on_mouse_event({
                     let pending_mouse_down = pending_mouse_down.clone();
                     move |event: &MouseMoveEvent, phase, cx| {
-                        let mut pending_mouse_down = pending_mouse_down.borrow_mut();
+                        if phase == DispatchPhase::Capture {
+                            return;
+                        }
 
+                        let mut pending_mouse_down = pending_mouse_down.borrow_mut();
                         if let Some(mouse_down) = pending_mouse_down.clone() {
-                            if cx.active_drag.is_some() {
-                                if phase == DispatchPhase::Capture {
-                                    cx.notify();
-                                }
-                            } else if phase == DispatchPhase::Bubble
+                            if !cx.has_active_drag()
                                 && (event.position - mouse_down.position).magnitude()
                                     > DRAG_THRESHOLD
                             {

crates/gpui2/src/window.rs 🔗

@@ -1516,15 +1516,24 @@ impl<'a> WindowContext<'a> {
                 }
             }
 
-            if self.app.propagate_event && event.downcast_ref::<MouseUpEvent>().is_some() {
-                self.active_drag = None;
-            }
-
             self.window
                 .rendered_frame
                 .mouse_listeners
                 .insert(event.type_id(), handlers);
         }
+
+        if self.app.propagate_event && self.has_active_drag() {
+            if event.is::<MouseMoveEvent>() {
+                // If this was a mouse move event, redraw the window so that the
+                // active drag can follow the mouse cursor.
+                self.notify();
+            } else if event.is::<MouseUpEvent>() {
+                // If this was a mouse up event, cancel the active drag and redraw
+                // the window.
+                self.active_drag = None;
+                self.notify();
+            }
+        }
     }
 
     fn dispatch_key_event(&mut self, event: &dyn Any) {