mirror of
https://github.com/zed-industries/zed.git
synced 2026-06-01 03:14:56 +07:00
debugger: Fix crash when dragging pane items to split view (#46806)
## Summary Fixes crash when dragging debugger panel items (terminal/console/variables/frames) to another pane as split view. **Root causes:** 1. Double borrow panic - `pane_group.split()` was called synchronously inside a `Context<Pane>` update, causing "cannot update Pane while it is already being updated" 2. `unwrap()` calls that panic when items are in transition during drag operations 3. `debug_assert!` in `pane_at_pixel_position` fails when `members` and `bounding_boxes` are temporarily out of sync after deferred split **Fixes:** - Defer entire split+move operation via `cx.spawn_in()` to avoid double borrow - Replace `unwrap()` with graceful early returns in `activate_item` and `run_in_terminal` - Handle `members.len() != bounding_boxes.len()` gracefully in `pane_at_pixel_position` Closes #46784 Closes #ISSUE Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: Anthony Eid <anthony@zed.dev>
This commit is contained in:
parent
9fce07599a
commit
a8bf82c469
1 changed files with 38 additions and 45 deletions
|
|
@ -335,56 +335,49 @@ pub(crate) fn new_debugger_pane(
|
|||
let source = tab.pane.clone();
|
||||
let item_id_to_move = item.item_id();
|
||||
|
||||
let Ok(new_split_pane) = pane
|
||||
.drag_split_direction()
|
||||
.map(|split_direction| {
|
||||
weak_running.update(cx, |running, cx| {
|
||||
let new_pane =
|
||||
new_debugger_pane(workspace.clone(), project.clone(), window, cx);
|
||||
let _previous_subscription = running.pane_close_subscriptions.insert(
|
||||
new_pane.entity_id(),
|
||||
cx.subscribe_in(&new_pane, window, RunningState::handle_pane_event),
|
||||
);
|
||||
debug_assert!(_previous_subscription.is_none());
|
||||
running
|
||||
.panes
|
||||
.split(&this_pane, &new_pane, split_direction, cx)?;
|
||||
anyhow::Ok(new_pane)
|
||||
})
|
||||
})
|
||||
.transpose()
|
||||
else {
|
||||
return ControlFlow::Break(());
|
||||
};
|
||||
|
||||
match new_split_pane.transpose() {
|
||||
// Source pane may be the one currently updated, so defer the move.
|
||||
Ok(Some(new_pane)) => cx
|
||||
.spawn_in(window, async move |_, cx| {
|
||||
cx.update(|window, cx| {
|
||||
move_item(
|
||||
&source,
|
||||
&new_pane,
|
||||
item_id_to_move,
|
||||
new_pane.read(cx).active_item_index(),
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.detach(),
|
||||
let Some(split_direction) = pane.drag_split_direction() else {
|
||||
// If we drop into existing pane or current pane,
|
||||
// regular pane drop handler will take care of it,
|
||||
// using the right tab index for the operation.
|
||||
Ok(None) => return ControlFlow::Continue(()),
|
||||
err @ Err(_) => {
|
||||
err.log_err();
|
||||
return ControlFlow::Break(());
|
||||
}
|
||||
return ControlFlow::Continue(());
|
||||
};
|
||||
|
||||
let workspace = workspace.clone();
|
||||
let weak_running = weak_running.clone();
|
||||
// Source pane may be the one currently updated, so defer the move.
|
||||
window.defer(cx, move |window, cx| {
|
||||
let new_pane = weak_running.update(cx, |running, cx| {
|
||||
let new_pane =
|
||||
new_debugger_pane(workspace.clone(), project.clone(), window, cx);
|
||||
let _previous_subscription = running.pane_close_subscriptions.insert(
|
||||
new_pane.entity_id(),
|
||||
cx.subscribe_in(&new_pane, window, RunningState::handle_pane_event),
|
||||
);
|
||||
debug_assert!(_previous_subscription.is_none());
|
||||
running
|
||||
.panes
|
||||
.split(&this_pane, &new_pane, split_direction, cx)?;
|
||||
anyhow::Ok(new_pane)
|
||||
});
|
||||
|
||||
match new_pane.and_then(|r| r) {
|
||||
Ok(new_pane) => {
|
||||
move_item(
|
||||
&source,
|
||||
&new_pane,
|
||||
item_id_to_move,
|
||||
new_pane.read(cx).active_item_index(),
|
||||
true,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("{err:?}");
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
ControlFlow::Break(())
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue