Avoid panicking when closing a dragged tab

Antonio Scandurra , Max , and Nathan created

Co-Authored-By: Max <max@zed.dev>
Co-Authored-By: Nathan <nathan@zed.dev>

Change summary

crates/workspace/src/pane.rs      |  9 ++++-----
crates/workspace/src/workspace.rs | 13 ++++++-------
2 files changed, 10 insertions(+), 12 deletions(-)

Detailed changes

crates/workspace/src/pane.rs 🔗

@@ -219,8 +219,8 @@ pub struct NavigationEntry {
 #[derive(Clone)]
 pub struct DraggedTab {
     pub pane: View<Pane>,
+    pub item: Box<dyn ItemHandle>,
     pub ix: usize,
-    pub item_id: EntityId,
     pub detail: usize,
     pub is_active: bool,
 }
@@ -1310,9 +1310,9 @@ impl Pane {
             )
             .on_drag(
                 DraggedTab {
+                    item: item.boxed_clone(),
                     pane: cx.view().clone(),
                     detail,
-                    item_id,
                     is_active,
                     ix,
                 },
@@ -1603,7 +1603,7 @@ impl Pane {
         }
         let mut to_pane = cx.view().clone();
         let split_direction = self.drag_split_direction;
-        let item_id = dragged_tab.item_id;
+        let item_id = dragged_tab.item.item_id();
         let from_pane = dragged_tab.pane.clone();
         self.workspace
             .update(cx, |_, cx| {
@@ -2603,8 +2603,7 @@ mod tests {
 impl Render for DraggedTab {
     fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
         let ui_font = ThemeSettings::get_global(cx).ui_font.family.clone();
-        let item = &self.pane.read(cx).items[self.ix];
-        let label = item.tab_content(Some(self.detail), false, cx);
+        let label = self.item.tab_content(Some(self.detail), false, cx);
         Tab::new("")
             .selected(self.is_active)
             .child(label)

crates/workspace/src/workspace.rs 🔗

@@ -2250,17 +2250,16 @@ impl Workspace {
         destination_index: usize,
         cx: &mut ViewContext<Self>,
     ) {
-        let item_to_move = source
+        let Some((item_ix, item_handle)) = source
             .read(cx)
             .items()
             .enumerate()
-            .find(|(_, item_handle)| item_handle.item_id() == item_id_to_move);
-
-        if item_to_move.is_none() {
-            log::warn!("Tried to move item handle which was not in `from` pane. Maybe tab was closed during drop");
+            .find(|(_, item_handle)| item_handle.item_id() == item_id_to_move)
+        else {
+            // Tab was closed during drag
             return;
-        }
-        let (item_ix, item_handle) = item_to_move.unwrap();
+        };
+
         let item_handle = item_handle.clone();
 
         if source != destination {