Fix terminal pane tabs arrangement and closing (#22013)

* Fixes the inability to drag and drop terminal tabs to reorder them;
fixed incorrect terminal tab move on drag and drop into existing pane
(follow-up of https://github.com/zed-industries/zed/pull/21238)
* Fixes save dialogue appearing when on closing terminal tabs with
running tasks (follow-up of
https://github.com/zed-industries/zed/pull/21374)

Release Notes:

- Fixed terminal pane tabs arrangement and closing
This commit is contained in:
Kirill Bulatov 2024-12-14 16:13:04 +02:00 committed by GitHub
parent 6e1cc5dad3
commit 9daa426e93
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 52 additions and 52 deletions

View file

@ -911,8 +911,7 @@ pub fn new_terminal_pane(
pane.set_custom_drop_handle(cx, move |pane, dropped_item, cx| { pane.set_custom_drop_handle(cx, move |pane, dropped_item, cx| {
if let Some(tab) = dropped_item.downcast_ref::<DraggedTab>() { if let Some(tab) = dropped_item.downcast_ref::<DraggedTab>() {
let this_pane = cx.view().clone(); let this_pane = cx.view().clone();
let belongs_to_this_pane = tab.pane == this_pane; let item = if tab.pane == this_pane {
let item = if belongs_to_this_pane {
pane.item_for_index(tab.ix) pane.item_for_index(tab.ix)
} else { } else {
tab.pane.read(cx).item_for_index(tab.ix) tab.pane.read(cx).item_for_index(tab.ix)
@ -922,7 +921,9 @@ pub fn new_terminal_pane(
let source = tab.pane.clone(); let source = tab.pane.clone();
let item_id_to_move = item.item_id(); let item_id_to_move = item.item_id();
let new_pane = pane.drag_split_direction().and_then(|split_direction| { let new_split_pane = pane
.drag_split_direction()
.map(|split_direction| {
terminal_panel.update(cx, |terminal_panel, cx| { terminal_panel.update(cx, |terminal_panel, cx| {
let is_zoomed = if terminal_panel.active_pane == this_pane { let is_zoomed = if terminal_panel.active_pane == this_pane {
pane.is_zoomed() pane.is_zoomed()
@ -936,39 +937,41 @@ pub fn new_terminal_pane(
cx, cx,
); );
terminal_panel.apply_tab_bar_buttons(&new_pane, cx); terminal_panel.apply_tab_bar_buttons(&new_pane, cx);
terminal_panel terminal_panel.center.split(
.center &this_pane,
.split(&this_pane, &new_pane, split_direction) &new_pane,
.log_err()?; split_direction,
Some(new_pane) )?;
anyhow::Ok(new_pane)
}) })
}); })
.transpose();
let destination; match new_split_pane {
let destination_index; // Source pane may be the one currently updated, so defer the move.
if let Some(new_pane) = new_pane { Ok(Some(new_pane)) => cx
destination_index = new_pane.read(cx).active_item_index(); .spawn(|_, mut cx| async move {
destination = new_pane;
} else if belongs_to_this_pane {
return ControlFlow::Break(());
} else {
destination = cx.view().clone();
destination_index = pane.active_item_index();
}
// Destination pane may be the one currently updated, so defer the move.
cx.spawn(|_, mut cx| async move {
cx.update(|cx| { cx.update(|cx| {
move_item( move_item(
&source, &source,
&destination, &new_pane,
item_id_to_move, item_id_to_move,
destination_index, new_pane.read(cx).active_item_index(),
cx, cx,
); );
}) })
.ok(); .ok();
}) })
.detach(); .detach(),
// 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(());
}
};
} else if let Some(project_path) = item.project_path(cx) { } else if let Some(project_path) = item.project_path(cx) {
if let Some(entry_path) = project.read(cx).absolute_path(&project_path, cx) if let Some(entry_path) = project.read(cx).absolute_path(&project_path, cx)
{ {

View file

@ -1468,7 +1468,7 @@ impl Pane {
// Always propose to save singleton files without any project paths: those cannot be saved via multibuffer, as require a file path selection modal. // Always propose to save singleton files without any project paths: those cannot be saved via multibuffer, as require a file path selection modal.
|| cx || cx
.update(|cx| { .update(|cx| {
item_to_close.is_dirty(cx) item_to_close.can_save(cx) && item_to_close.is_dirty(cx)
&& item_to_close.is_singleton(cx) && item_to_close.is_singleton(cx)
&& item_to_close.project_path(cx).is_none() && item_to_close.project_path(cx).is_none()
}) })
@ -4025,11 +4025,8 @@ mod tests {
cx.executor().run_until_parked(); cx.executor().run_until_parked();
cx.simulate_prompt_answer(2); cx.simulate_prompt_answer(2);
cx.executor().run_until_parked();
cx.simulate_prompt_answer(2);
cx.executor().run_until_parked();
save.await.unwrap(); save.await.unwrap();
assert_item_labels(&pane, ["A*^", "B^", "C^"], cx); assert_item_labels(&pane, [], cx);
} }
#[gpui::test] #[gpui::test]