From a19826af2bc435dd49589cc50b9445cfce4f5c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Gr=C3=BCndel?= Date: Thu, 13 Nov 2025 03:30:37 +0100 Subject: [PATCH] dock: Don't close tab via action when it can't be closed via context menu (#1581) Right now the last tab can be closed via the keyboard action, even though it's explicitly not allowed to be closed via the context menu. This can result in an invalid app state. This pull request takes the same check that's currently done to decide whether the close button should be drawn in the context menu, and adds it to the close action. --- crates/ui/src/dock/tab_panel.rs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/ui/src/dock/tab_panel.rs b/crates/ui/src/dock/tab_panel.rs index 752c113f..31e33d6b 100644 --- a/crates/ui/src/dock/tab_panel.rs +++ b/crates/ui/src/dock/tab_panel.rs @@ -101,6 +101,12 @@ impl Panel for TabPanel { return false; } + // 1. When is the final panel in the dock, it will not able to close. + // 2. When is in the Tiles, it will always able to close (by active panel state). + if !self.draggable(cx) && !self.in_tiles { + return false; + } + self.active_panel(cx) .map(|panel| panel.closable(cx)) .unwrap_or(false) @@ -1111,6 +1117,9 @@ impl TabPanel { window: &mut Window, cx: &mut Context, ) { + if !self.closable(cx) { + return; + } if let Some(panel) = self.active_panel(cx) { self.remove_panel(panel, window, cx); } @@ -1154,7 +1163,7 @@ impl Render for TabPanel { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl gpui::IntoElement { let focus_handle = self.focus_handle(cx); let active_panel = self.active_panel(cx); - let mut state = TabState { + let state = TabState { closable: self.closable(cx), draggable: self.draggable(cx), droppable: self.droppable(cx), @@ -1162,12 +1171,6 @@ impl Render for TabPanel { active_panel, }; - // 1. When is the final panel in the dock, it will not able to close. - // 2. When is in the Tiles, it will always able to close (by active panel state). - if !state.draggable && !self.in_tiles { - state.closable = false; - } - self.bind_actions(cx) .id("tab-panel") .track_focus(&focus_handle)