From 2ec2b76d7ac5dc4c92e315d344a45b97b9114f36 Mon Sep 17 00:00:00 2001 From: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com> Date: Wed, 4 Nov 2026 09:58:51 +0800 Subject: [PATCH] fix(remote): keep the host in a remote window's title (#1146) Connecting a remote window titles it ` []`, but the frontend rewrote the title from the project and active file whenever either changed (and after a reload), dropping the host. The title now includes the remote session's host. --- src/features/app/__tests__/shell.test.tsx | 4 ++++ src/features/app/title.ts | 18 ++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/features/app/__tests__/shell.test.tsx b/src/features/app/__tests__/shell.test.tsx index f1c217439..b458bb598 100644 --- a/src/features/app/__tests__/shell.test.tsx +++ b/src/features/app/__tests__/shell.test.tsx @@ -14,6 +14,10 @@ describe("window title", () => { expect(windowTitle("openidea", null)).toBe("openidea"); expect(windowTitle(null, null)).toBe("OpenIDEA"); }); + it("names the host of a remote project", () => { + expect(windowTitle("rproj", "/home/me/rproj/a.ts", false, "me@server")).toBe("rproj [me@server] – a.ts"); + expect(windowTitle("rproj", null, false, "me@server")).toBe("rproj [me@server]"); + }); }); describe("keymap reference", () => { diff --git a/src/features/app/title.ts b/src/features/app/title.ts index 1a178ff94..2f586cc5e 100644 --- a/src/features/app/title.ts +++ b/src/features/app/title.ts @@ -1,20 +1,24 @@ /** * Window title, IDEA style: ` – `; with Settings › Appearance › - * "Always show full path in window header" the file's full path. + * "Always show full path in window header" the file's full path. A remote + * project names its host: ` [] – `. */ import { useEditorRegistry } from "@/editor/api"; import { t, useI18n } from "@/platform/i18n"; import { isTauri } from "@/platform/ipc"; import { basename, useProject } from "@/platform/project"; +import { useRemote } from "@/platform/remote"; export function windowTitle( project: string | null | undefined, file: string | null | undefined, fullPath = false, + host: string | null = null, ): string { const name = file ? (fullPath ? file : basename(file)) : null; if (!project) return name ?? t("app.title.default"); - return name ? `${project} – ${name}` : project; + const where = host ? `${project} [${host}]` : project; + return name ? `${where} – ${name}` : where; } export function installWindowTitle(): () => void { @@ -30,13 +34,19 @@ export function installWindowTitle(): () => void { const update = () => { const { project, settings } = useProject.getState(); const fullPath = settings?.appearance?.fullPathInTitle === true; - const title = windowTitle(project?.name, useEditorRegistry.getState().active?.ctx.path, fullPath); + const host = useRemote.getState().session?.host ?? null; + const title = windowTitle(project?.name, useEditorRegistry.getState().active?.ctx.path, fullPath, host); if (title === last) return; last = title; if (typeof document !== "undefined") document.title = title; setNative?.(title); }; update(); - const unsubs = [useProject.subscribe(update), useEditorRegistry.subscribe(update), useI18n.subscribe(update)]; + const unsubs = [ + useProject.subscribe(update), + useEditorRegistry.subscribe(update), + useI18n.subscribe(update), + useRemote.subscribe(update), + ]; return () => unsubs.forEach((u) => u()); }