From f2b85eca4cc73a0768992fd205cf39ee15b1cccc Mon Sep 17 00:00:00 2001
From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
Date: Sat, 14 Nov 2026 15:46:03 +0800
Subject: [PATCH] fix(debugger): open the Debug window on Console, and on the
view last picked (#3316)
The Debug window switched to Console only when it was open while the session was starting; a window opened later mounted on Threads & Variables, and a remount forgot the user's choice. It now opens on Console until a view is picked, then on the view last picked; a breakpoint or exception still brings Threads & Variables forward.
---
.../debugger/__tests__/toolWindow.test.tsx | 14 ++++++++++++++
src/features/debugger/ui/DebugToolWindow.tsx | 10 ++++++++--
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/features/debugger/__tests__/toolWindow.test.tsx b/src/features/debugger/__tests__/toolWindow.test.tsx
index ead7668fd..52deb2527 100644
--- a/src/features/debugger/__tests__/toolWindow.test.tsx
+++ b/src/features/debugger/__tests__/toolWindow.test.tsx
@@ -228,6 +228,20 @@ describe("debug tool window", () => {
expect(console.getAttribute("aria-selected")).toBe("true");
});
+ it("opens on Console for a running session, and on the view last picked when shown again", () => {
+ useDebug.setState({ sessions: { 1: { ...session, status: "running" } }, active: 1 });
+ const first = render();
+ expect(screen.getByRole("tab", { name: "Console" }).getAttribute("aria-selected")).toBe("true");
+ fireEvent.click(screen.getByRole("tab", { name: "Threads & Variables" }));
+ first.unmount();
+ const again = render();
+ expect(screen.getByRole("tab", { name: "Threads & Variables" }).getAttribute("aria-selected")).toBe("true");
+ fireEvent.click(screen.getByRole("tab", { name: "Console" }));
+ again.unmount();
+ render();
+ expect(screen.getByRole("tab", { name: "Console" }).getAttribute("aria-selected")).toBe("true");
+ });
+
it("renders session tabs, views, frames and typed variables", async () => {
useDebug.setState({ sessions: { 1: session }, active: 1 });
render(
diff --git a/src/features/debugger/ui/DebugToolWindow.tsx b/src/features/debugger/ui/DebugToolWindow.tsx
index dcc5ccfc4..5ddc284a0 100644
--- a/src/features/debugger/ui/DebugToolWindow.tsx
+++ b/src/features/debugger/ui/DebugToolWindow.tsx
@@ -103,6 +103,9 @@ function MoreActions() {
type Tab = "variables" | "console" | "memory";
+/** The view the user last picked; the tool window opens on it again (Console until one is picked). */
+let chosenTab: Tab = "console";
+
function statusText(s: DebugSession): string {
if (s.status === "terminated") return s.exitCode != null ? `Finished · exit code ${s.exitCode}` : "Finished";
if (s.status === "starting") return "Starting…";
@@ -149,7 +152,7 @@ export function DebugToolWindow() {
session: number | undefined;
status: DebugSession["status"] | undefined;
tab: Tab;
- }>({ session: undefined, status: undefined, tab: "variables" });
+ }>({ session: undefined, status: undefined, tab: chosenTab });
if (active && (view.session !== active.startedAt || view.status !== active.status))
setView({
session: active.startedAt,
@@ -232,7 +235,10 @@ export function DebugToolWindow() {
aria-selected={tab === id}
aria-controls={`debug-panel-${id}`}
className={clsx(styles.tab, tab === id && styles.tabActive)}
- onClick={() => setView({ session: active.startedAt, status: active.status, tab: id })}
+ onClick={() => {
+ chosenTab = id;
+ setView({ session: active.startedAt, status: active.status, tab: id });
+ }}
>
{tx(label)}