From 05247b090420a1cec0224c80a82f8d2cf87d5289 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 16 May 2026 01:11:19 +0530 Subject: [PATCH 1/3] fix: improved bottom panel architecture --- src/view/PanelView.js | 9 ++++++--- src/view/WorkspaceManager.js | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/view/PanelView.js b/src/view/PanelView.js index 0dac9f5aef..da5a750152 100644 --- a/src/view/PanelView.js +++ b/src/view/PanelView.js @@ -681,7 +681,7 @@ define(function (require, exports, module) { return false; } } - this.hide(); + this.hide({ preferFallback: true }); return true; }; @@ -747,8 +747,9 @@ define(function (require, exports, module) { /** * Hides the panel */ - Panel.prototype.hide = function () { + Panel.prototype.hide = function (options) { let panelId = this.panelID; + let preferFallback = !!(options && options.preferFallback); // Quick Access panel is pinned — it stays in _openIds and the tab bar. // Hiding it collapses the bottom panel container entirely. @@ -779,7 +780,9 @@ define(function (require, exports, module) { let wasActive = (_activeId === panelId); let activatedId = null; - if (wasActive && _openIds.length > 0) { + let onlyDefaultLeft = (_openIds.length === 1 && _openIds[0] === _defaultPanelId); + + if (wasActive && preferFallback && _openIds.length > 0 && !onlyDefaultLeft) { let nextIdx = Math.min(idx, _openIds.length - 1); activatedId = _openIds[nextIdx]; _activeId = null; diff --git a/src/view/WorkspaceManager.js b/src/view/WorkspaceManager.js index 72d8c217ea..acb33401f5 100644 --- a/src/view/WorkspaceManager.js +++ b/src/view/WorkspaceManager.js @@ -821,7 +821,7 @@ define(function (require, exports, module) { // buttons and menu items that mirror container visibility // (drawer, Git icon, etc.) need this signal to deselect. PanelView.collapseContainer(); - } else if (PanelView.getOpenBottomPanelIDs().length > 0) { + } else if (PanelView.getActiveBottomPanel()) { // Use the helper so SHOWN(_activeId) fires — same listeners // need this signal to re-select after a previous collapse. PanelView.restoreContainer(); From 584a10519fd39b837b1c72c5634eab00d4fe72f1 Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 16 May 2026 15:30:50 +0530 Subject: [PATCH 2/3] refactor: better api support for bottom panel architecture --- src/view/PanelView.js | 64 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/src/view/PanelView.js b/src/view/PanelView.js index da5a750152..02ca37c5d4 100644 --- a/src/view/PanelView.js +++ b/src/view/PanelView.js @@ -669,10 +669,10 @@ define(function (require, exports, module) { }; /** - * Requests the panel to hide, invoking the registered onCloseRequested handler first (if any). - * If the handler returns false, the panel stays open. If it returns true or no handler is - * registered, `hide()` is called. - * @return {Promise} Resolves to true if the panel was hidden, false if prevented. + * Requests this panel's tab to close, invoking the registered + * onCloseRequested handler first (if any). If the handler returns false, + * the tab stays open. Otherwise, `closeTab()` is called. + * @return {Promise} Resolves to true if the tab was closed, false if prevented. */ Panel.prototype.requestClose = async function () { if (this._onCloseRequestedHandler) { @@ -681,7 +681,7 @@ define(function (require, exports, module) { return false; } } - this.hide({ preferFallback: true }); + this.closeTab(); return true; }; @@ -745,14 +745,17 @@ define(function (require, exports, module) { }; /** - * Hides the panel + * Hides this panel: removes its tab from the tab bar, and if this was + * the active tab, collapses the bottom panel container. The panel stays + * registered — call show() to bring it back. + * + * For tab-bar UX where closing the active tab should switch to the next + * sibling tab (like clicking the X on a tab), use closeTab() instead. + * For permanent removal, use destroy(). */ - Panel.prototype.hide = function (options) { + Panel.prototype.hide = function () { let panelId = this.panelID; - let preferFallback = !!(options && options.preferFallback); - // Quick Access panel is pinned — it stays in _openIds and the tab bar. - // Hiding it collapses the bottom panel container entirely. if (panelId === _defaultPanelId) { if (_activeId !== panelId) { return; @@ -773,16 +776,51 @@ define(function (require, exports, module) { return; } - // Remove from open set + _openIds.splice(idx, 1); + this.$panel.removeClass("active-bottom-panel"); + + if (_activeId === panelId) { + _activeId = null; + if (_$container) { + restoreIfMaximized(); + Resizer.hide(_$container[0]); + } + } + + _removeTabFromBar(panelId); + + exports.trigger(EVENT_PANEL_HIDDEN, panelId); + }; + + /** + * Closes this tab: removes its tab from the tab bar. If this was the + * active tab, switches to the next sibling tab; if no other tab is open, + * collapses the bottom panel container instead. The panel stays + * registered — call show() to bring it back. + * + * For a programmatic hide that always collapses (no auto-switch to a + * sibling tab), use hide(). For permanent removal, use destroy(). + */ + Panel.prototype.closeTab = function () { + let panelId = this.panelID; + + if (panelId === _defaultPanelId) { + return; + } + + let idx = _openIds.indexOf(panelId); + if (idx === -1) { + return; + } + _openIds.splice(idx, 1); this.$panel.removeClass("active-bottom-panel"); let wasActive = (_activeId === panelId); let activatedId = null; - let onlyDefaultLeft = (_openIds.length === 1 && _openIds[0] === _defaultPanelId); - if (wasActive && preferFallback && _openIds.length > 0 && !onlyDefaultLeft) { + if (wasActive && _openIds.length > 0 && !onlyDefaultLeft) { let nextIdx = Math.min(idx, _openIds.length - 1); activatedId = _openIds[nextIdx]; _activeId = null; From 2b7c8b1ad96d8e90f7cbc6af9081f4957c794bff Mon Sep 17 00:00:00 2001 From: Pluto Date: Sat, 16 May 2026 15:32:40 +0530 Subject: [PATCH 3/3] chore: auto update api docs --- docs/API-Reference/view/PanelView.md | 29 +++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/docs/API-Reference/view/PanelView.md b/docs/API-Reference/view/PanelView.md index 78d9eee962..2d40f33c7b 100644 --- a/docs/API-Reference/view/PanelView.md +++ b/docs/API-Reference/view/PanelView.md @@ -143,6 +143,7 @@ Preference key for persisting the maximize state across reloads. * [.show()](#Panel+show) * [.addToTabBar()](#Panel+addToTabBar) * [.hide()](#Panel+hide) + * [.closeTab()](#Panel+closeTab) * [.focus()](#Panel+focus) ⇒ boolean * [.setVisible(visible)](#Panel+setVisible) * [.setTitle(newTitle)](#Panel+setTitle) @@ -196,12 +197,12 @@ tab close button). The handler should return `true` to allow the close, or `fals ### panel.requestClose() ⇒ Promise.<boolean> -Requests the panel to hide, invoking the registered onCloseRequested handler first (if any). -If the handler returns false, the panel stays open. If it returns true or no handler is -registered, `hide()` is called. +Requests this panel's tab to close, invoking the registered +onCloseRequested handler first (if any). If the handler returns false, +the tab stays open. Otherwise, `closeTab()` is called. **Kind**: instance method of [Panel](#Panel) -**Returns**: Promise.<boolean> - Resolves to true if the panel was hidden, false if prevented. +**Returns**: Promise.<boolean> - Resolves to true if the tab was closed, false if prevented. ### panel.show() @@ -219,7 +220,25 @@ was collapsed by the user — avoids forcing the bottom panel open. ### panel.hide() -Hides the panel +Hides this panel: removes its tab from the tab bar, and if this was +the active tab, collapses the bottom panel container. The panel stays +registered — call show() to bring it back. + +For tab-bar UX where closing the active tab should switch to the next +sibling tab (like clicking the X on a tab), use closeTab() instead. +For permanent removal, use destroy(). + +**Kind**: instance method of [Panel](#Panel) + + +### panel.closeTab() +Closes this tab: removes its tab from the tab bar. If this was the +active tab, switches to the next sibling tab; if no other tab is open, +collapses the bottom panel container instead. The panel stays +registered — call show() to bring it back. + +For a programmatic hide that always collapses (no auto-switch to a +sibling tab), use hide(). For permanent removal, use destroy(). **Kind**: instance method of [Panel](#Panel)