Fix dock resizing (#3663)

Mikayla Maki created

This fixes some bugs in the display and tracking of dock resizes

Release Notes:

-

Change summary

crates/gpui2/src/elements/canvas.rs |  8 +++---
crates/gpui2/src/elements/div.rs    |  4 +-
crates/workspace2/src/dock.rs       | 39 +++++++++++++++++++-----------
3 files changed, 31 insertions(+), 20 deletions(-)

Detailed changes

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

@@ -27,7 +27,7 @@ impl IntoElement for Canvas {
 }
 
 impl Element for Canvas {
-    type State = ();
+    type State = Style;
 
     fn layout(
         &mut self,
@@ -37,11 +37,11 @@ impl Element for Canvas {
         let mut style = Style::default();
         style.refine(&self.style);
         let layout_id = cx.request_layout(&style, []);
-        (layout_id, ())
+        (layout_id, style)
     }
 
-    fn paint(self, bounds: Bounds<Pixels>, _: &mut (), cx: &mut WindowContext) {
-        (self.paint_callback)(&bounds, cx)
+    fn paint(self, bounds: Bounds<Pixels>, style: &mut Style, cx: &mut WindowContext) {
+        style.paint(bounds, cx, |cx| (self.paint_callback)(&bounds, cx));
     }
 }
 

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

@@ -213,7 +213,7 @@ pub trait InteractiveElement: Sized {
         listener: impl Fn(&DragMoveEvent<T>, &mut WindowContext) + 'static,
     ) -> Self
     where
-        T: Render,
+        T: 'static,
     {
         self.interactivity().mouse_move_listeners.push(Box::new(
             move |event, bounds, phase, cx| {
@@ -223,7 +223,7 @@ pub trait InteractiveElement: Sized {
                     if cx
                         .active_drag
                         .as_ref()
-                        .is_some_and(|drag| drag.value.type_id() == TypeId::of::<T>())
+                        .is_some_and(|drag| (*drag.value).type_id() == TypeId::of::<T>())
                     {
                         (listener)(
                             &DragMoveEvent {

crates/workspace2/src/dock.rs 🔗

@@ -486,12 +486,9 @@ impl Render for Dock {
         if let Some(entry) = self.visible_entry() {
             let size = entry.panel.size(cx);
 
-            let mut pre_resize_handle = None;
-            let mut post_resize_handle = None;
             let position = self.position;
-            let handler = div()
+            let mut handle = div()
                 .id("resize-handle")
-                .bg(cx.theme().colors().border)
                 .on_drag(DraggedDock(position), |dock, cx| {
                     cx.build_view(|_| dock.clone())
                 })
@@ -506,16 +503,31 @@ impl Render for Dock {
 
             match self.position() {
                 DockPosition::Left => {
-                    post_resize_handle =
-                        Some(handler.min_w(HANDLE_SIZE).h_full().cursor_col_resize())
+                    handle = handle
+                        .absolute()
+                        .right(px(0.))
+                        .top(px(0.))
+                        .h_full()
+                        .w(HANDLE_SIZE)
+                        .cursor_col_resize();
                 }
                 DockPosition::Bottom => {
-                    pre_resize_handle =
-                        Some(handler.w_full().min_h(HANDLE_SIZE).cursor_row_resize())
+                    handle = handle
+                        .absolute()
+                        .top(px(0.))
+                        .left(px(0.))
+                        .w_full()
+                        .h(HANDLE_SIZE)
+                        .cursor_row_resize();
                 }
                 DockPosition::Right => {
-                    pre_resize_handle =
-                        Some(handler.min_w(HANDLE_SIZE).h_full().cursor_col_resize())
+                    handle = handle
+                        .absolute()
+                        .top(px(0.))
+                        .left(px(0.))
+                        .w_full()
+                        .h(HANDLE_SIZE)
+                        .cursor_col_resize();
                 }
             }
 
@@ -531,16 +543,15 @@ impl Render for Dock {
                     DockPosition::Right => this.border_l(),
                     DockPosition::Bottom => this.border_t(),
                 })
-                .children(pre_resize_handle)
                 .child(
                     div()
                         .map(|this| match self.position().axis() {
-                            Axis::Horizontal => this.min_w(px(size) - HANDLE_SIZE).h_full(),
-                            Axis::Vertical => this.min_h(px(size) - HANDLE_SIZE).w_full(),
+                            Axis::Horizontal => this.min_w(px(size)).h_full(),
+                            Axis::Vertical => this.min_h(px(size)).w_full(),
                         })
                         .child(entry.panel.to_any()),
                 )
-                .children(post_resize_handle)
+                .child(handle)
         } else {
             div()
         }