From b2d11880490552ab6eb36f540b8d2fab0116ce0b Mon Sep 17 00:00:00 2001 From: arookieofc <2128194521@qq.com> Date: Sat, 31 Oct 2026 21:43:20 +0800 Subject: [PATCH] fix(terminal): keep focus in the terminal after its context menu closes (#566) Right-clicking the terminal did not focus it, and closing any context menu sent focus to the editor. Popup recorded the element to restore in an effect, after Menu had already focused its first item, so it restored the menu item; focus then fell to the body and the workbench fallback focused the editor. Popup now records the focused element while rendering, and the terminal takes focus when its context menu opens. Enter after the menu closes goes to the shell. This covers every context menu: focus returns to what held it before the menu opened. Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com> --- src/features/terminal/TerminalView.tsx | 3 +++ src/ui/Popup.test.tsx | 17 ++++++++++++++++- src/ui/Popup.tsx | 14 ++++++++++++-- 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/features/terminal/TerminalView.tsx b/src/features/terminal/TerminalView.tsx index f805b310d..6b35883ab 100644 --- a/src/features/terminal/TerminalView.tsx +++ b/src/features/terminal/TerminalView.tsx @@ -86,6 +86,9 @@ function paneMenu(e: MouseEvent, key: string) { e.preventDefault(); const session = getSession(key); if (!session) return; + // Right-clicking focuses the terminal, like IDEA; otherwise the menu closing + // restores focus to whatever was focused before it, often the editor. + session.focus(); const exited = session.state.status === "exited" || session.state.status === "error"; const mac = usePlatform.getState().os === "macos"; const items: MenuItem[] = [ diff --git a/src/ui/Popup.test.tsx b/src/ui/Popup.test.tsx index b135322f8..ed98b0396 100644 --- a/src/ui/Popup.test.tsx +++ b/src/ui/Popup.test.tsx @@ -4,7 +4,7 @@ import { act, fireEvent, render, screen } from "@testing-library/react"; import { getContext, setContext } from "@/platform/context"; import { registerAction } from "@/platform/actions"; import { Popup } from "./Popup"; -import { Menu, MenuList } from "./Menu"; +import { ContextMenuHost, Menu, MenuList, hideContextMenu, showContextMenu } from "./Menu"; import { Dialog } from "./Dialog"; function Harness({ onClose }: { onClose?: (r: string) => void }) { @@ -177,6 +177,21 @@ describe("Dialog initial focus", () => { }); describe("Menu action enablement", () => { + it("returns focus to the element focused before a context menu opened", () => { + render( + <> +