From 9025f522920a710f4f4e8dd98e8d09c2ffdc25ad Mon Sep 17 00:00:00 2001 From: shkumbinhasani Date: Sun, 1 Nov 2026 05:40:47 +0100 Subject: [PATCH] fix(web): clicking a file in the Files tree keeps focus on that row Opening a file from the tree switches the panel tab, which requested panel focus and restored the new tab's saved focus history. Skip the restore when focus is already inside the panel content. Fixes #28519 --- .../src/lib/workspaceFocus.browser.test.ts | 23 +++++++++++++++++++ apps/web/src/lib/workspaceFocus.ts | 1 + 2 files changed, 24 insertions(+) diff --git a/apps/web/src/lib/workspaceFocus.browser.test.ts b/apps/web/src/lib/workspaceFocus.browser.test.ts index f0064630f08c2..f97ac2e5408d3 100644 --- a/apps/web/src/lib/workspaceFocus.browser.test.ts +++ b/apps/web/src/lib/workspaceFocus.browser.test.ts @@ -226,6 +226,29 @@ describe("workspace area focus", () => { await vi.waitFor(() => expect(document.activeElement).toBe(composer.button)); }); + it("keeps focus on the control a panel tab switch came from", () => { + using fixture = setup(); + const panel = fixture.area("panel", 3); + const content = document.createElement("div"); + content.setAttribute("data-right-panel-surface-content", ""); + const row = (name: string) => { + const button = document.createElement("button"); + button.textContent = name; + content.append(button); + return button; + }; + const earlierRow = row("reference-analysis.md"); + const clickedRow = row("print-guide.md"); + panel.element.append(content); + panel.element.dataset.workspaceFocusKey = "panel:file:print-guide.md"; + earlierRow.focus(); + panel.element.dataset.workspaceFocusKey = "panel:file:reference-analysis.md"; + clickedRow.focus(); + panel.element.dataset.workspaceFocusKey = "panel:file:print-guide.md"; + expect(fixture.controller.focus("panel")).toBe(true); + expect(document.activeElement).toBe(clickedRow); + }); + it("waits for a requested area to mount", async () => { using fixture = setup(); fixture.area("composer", 2); diff --git a/apps/web/src/lib/workspaceFocus.ts b/apps/web/src/lib/workspaceFocus.ts index e612a8ff54974..dcdb8ffdabd89 100644 --- a/apps/web/src/lib/workspaceFocus.ts +++ b/apps/web/src/lib/workspaceFocus.ts @@ -186,6 +186,7 @@ export function createWorkspaceFocusController(doc: Document) { // A lazy surface's Suspense fallback is empty. Wait for its content instead // of claiming focus on the tab strip before the useful controls mount. if (surface && !surface.hasChildNodes()) return false; + if (!selector && surface?.contains(doc.activeElement)) return true; if (selector) { const target = area.querySelector(selector); if (!target || !isWorkspaceElementVisible(target)) return false;