diff --git a/src/vs/platform/terminal/common/terminal.ts b/src/vs/platform/terminal/common/terminal.ts index 3c9c10db0d3..82b064a99af 100644 --- a/src/vs/platform/terminal/common/terminal.ts +++ b/src/vs/platform/terminal/common/terminal.ts @@ -103,7 +103,6 @@ export interface IRawTerminalTabLayoutInfo { } export type ITerminalTabLayoutInfoById = IRawTerminalTabLayoutInfo; -export type ITerminalTabLayoutInfo = IRawTerminalTabLayoutInfo; export interface IRawTerminalsLayoutInfo { tabs: IRawTerminalTabLayoutInfo[]; @@ -113,6 +112,7 @@ export interface IPtyHostAttachTarget { id: number; pid: number; title: string; + titleSource: TitleEventSource; cwd: string; workspaceId: string; workspaceName: string; @@ -120,6 +120,15 @@ export interface IPtyHostAttachTarget { icon: TerminalIcon | undefined; } +export enum TitleEventSource { + /** From the API or the rename command that overrides any other type */ + Api, + /** From the process name property*/ + Process, + /** From the VT sequence */ + Sequence +} + export type ITerminalsLayoutInfo = IRawTerminalsLayoutInfo; export type ITerminalsLayoutInfoById = IRawTerminalsLayoutInfo; @@ -174,7 +183,7 @@ export interface IOffProcessTerminalService { getEnvironment(): Promise; getShellEnvironment(): Promise; setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise; - updateTitle(id: number, title: string): Promise; + updateTitle(id: number, title: string, titleSource: TitleEventSource): Promise; updateIcon(id: number, icon: TerminalIcon, color?: string): Promise; getTerminalLayoutInfo(): Promise; reduceConnectionGraceTime(): Promise; @@ -240,7 +249,7 @@ export interface IPtyService { processBinary(id: number, data: string): Promise; /** Confirm the process is _not_ an orphan. */ orphanQuestionReply(id: number): Promise; - updateTitle(id: number, title: string): Promise; + updateTitle(id: number, title: string, titleSource: TitleEventSource): Promise; updateIcon(id: number, icon: TerminalIcon, color?: string): Promise; getDefaultSystemShell(osOverride?: OperatingSystem): Promise; getProfiles?(includeDetectedProfiles?: boolean): Promise; @@ -349,7 +358,7 @@ export interface IShellLaunchConfig { /** * This is a terminal that attaches to an already running terminal. */ - attachPersistentProcess?: { id: number; pid: number; title: string; cwd: string; icon?: TerminalIcon; color?: string }; + attachPersistentProcess?: { id: number; pid: number; title: string; titleSource: TitleEventSource; cwd: string; icon?: TerminalIcon; color?: string }; /** * Whether the terminal process environment should be exactly as provided in diff --git a/src/vs/platform/terminal/common/terminalProcess.ts b/src/vs/platform/terminal/common/terminalProcess.ts index 914e85c8a94..bc51bd66e7d 100644 --- a/src/vs/platform/terminal/common/terminalProcess.ts +++ b/src/vs/platform/terminal/common/terminalProcess.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { UriComponents } from 'vs/base/common/uri'; -import { IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon } from 'vs/platform/terminal/common/terminal'; +import { IRawTerminalTabLayoutInfo, ITerminalEnvironment, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { ISerializableEnvironmentVariableCollection } from 'vs/platform/terminal/common/environmentVariable'; export interface ISingleTerminalConfiguration { @@ -51,6 +51,7 @@ export interface IProcessDetails { id: number; pid: number; title: string; + titleSource: TitleEventSource; cwd: string; workspaceId: string; workspaceName: string; diff --git a/src/vs/platform/terminal/node/ptyHostService.ts b/src/vs/platform/terminal/node/ptyHostService.ts index b9ad90e8602..27eb9176773 100644 --- a/src/vs/platform/terminal/node/ptyHostService.ts +++ b/src/vs/platform/terminal/node/ptyHostService.ts @@ -5,7 +5,7 @@ import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { ILogService } from 'vs/platform/log/common/log'; -import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalsLayoutInfo, TerminalIpcChannels, IHeartbeatService, HeartbeatConstants, TerminalShellType, ITerminalProfile, IRequestResolveVariablesEvent, SafeConfigProvider, TerminalSettingId, TerminalIcon } from 'vs/platform/terminal/common/terminal'; +import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalsLayoutInfo, TerminalIpcChannels, IHeartbeatService, HeartbeatConstants, TerminalShellType, ITerminalProfile, IRequestResolveVariablesEvent, SafeConfigProvider, TerminalSettingId, TitleEventSource, TerminalIcon } from 'vs/platform/terminal/common/terminal'; import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { FileAccess } from 'vs/base/common/network'; import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; @@ -167,8 +167,8 @@ export class PtyHostService extends Disposable implements IPtyService { lastPtyId = Math.max(lastPtyId, id); return id; } - updateTitle(id: number, title: string): Promise { - return this._proxy.updateTitle(id, title); + updateTitle(id: number, title: string, titleSource: TitleEventSource): Promise { + return this._proxy.updateTitle(id, title, titleSource); } updateIcon(id: number, icon: TerminalIcon, color?: string): Promise { return this._proxy.updateIcon(id, icon, color); diff --git a/src/vs/platform/terminal/node/ptyService.ts b/src/vs/platform/terminal/node/ptyService.ts index 950d09a069a..f10f2af6d6f 100644 --- a/src/vs/platform/terminal/node/ptyService.ts +++ b/src/vs/platform/terminal/node/ptyService.ts @@ -5,7 +5,7 @@ import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; import { IProcessEnvironment, isWindows, OperatingSystem, OS } from 'vs/base/common/platform'; -import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, LocalReconnectConstants, ITerminalsLayoutInfo, IRawTerminalInstanceLayoutInfo, ITerminalTabLayoutInfoById, ITerminalInstanceLayoutInfoById, TerminalShellType, IProcessReadyEvent, TerminalIcon } from 'vs/platform/terminal/common/terminal'; +import { IPtyService, IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, LocalReconnectConstants, ITerminalsLayoutInfo, IRawTerminalInstanceLayoutInfo, ITerminalTabLayoutInfoById, ITerminalInstanceLayoutInfoById, TerminalShellType, IProcessReadyEvent, TitleEventSource, TerminalIcon } from 'vs/platform/terminal/common/terminal'; import { AutoOpenBarrier, Queue, RunOnceScheduler } from 'vs/base/common/async'; import { Emitter } from 'vs/base/common/event'; import { TerminalRecorder } from 'vs/platform/terminal/common/terminalRecorder'; @@ -115,8 +115,8 @@ export class PtyService extends Disposable implements IPtyService { } } - async updateTitle(id: number, title: string): Promise { - this._throwIfNoPty(id).setTitle(title); + async updateTitle(id: number, title: string, titleSource: TitleEventSource): Promise { + this._throwIfNoPty(id).setTitle(title, titleSource); } async updateIcon(id: number, icon: URI | { light: URI; dark: URI } | { id: string, color?: { id: string } }, color?: string): Promise { @@ -205,10 +205,8 @@ export class PtyService extends Disposable implements IPtyService { const layout = this._workspaceLayoutInfos.get(args.workspaceId); if (layout) { const expandedTabs = await Promise.all(layout.tabs.map(async tab => this._expandTerminalTab(tab))); - const filtered = expandedTabs.filter(t => t.terminals.length > 0); - return { - tabs: filtered - }; + const tabs = expandedTabs.filter(t => t.terminals.length > 0); + return { tabs }; } return undefined; } @@ -246,6 +244,7 @@ export class PtyService extends Disposable implements IPtyService { return { id, title: persistentProcess.title, + titleSource: persistentProcess.titleSource, pid: persistentProcess.pid, workspaceId: persistentProcess.workspaceId, workspaceName: persistentProcess.workspaceName, @@ -300,15 +299,17 @@ export class PersistentTerminalProcess extends Disposable { private _pid = -1; private _cwd = ''; private _title: string | undefined; - + private _titleSource: TitleEventSource = TitleEventSource.Process; get pid(): number { return this._pid; } get title(): string { return this._title || this._terminalProcess.currentTitle; } + get titleSource(): TitleEventSource { return this._titleSource; } get icon(): TerminalIcon | undefined { return this._icon; } get color(): string | undefined { return this._color; } - setTitle(title: string): void { + setTitle(title: string, titleSource: TitleEventSource): void { this._title = title; + this._titleSource = titleSource; } setIcon(icon: TerminalIcon, color?: string): void { diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index 7c81d6928d0..56d4075670c 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -10,13 +10,13 @@ import { URI } from 'vs/base/common/uri'; import { StopWatch } from 'vs/base/common/stopwatch'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; -import { IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensions } from 'vs/platform/terminal/common/terminal'; +import { IShellLaunchConfig, IShellLaunchConfigDto, ITerminalDimensions, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering'; import { ITerminalExternalLinkProvider, ITerminalInstance, ITerminalInstanceService, ITerminalLink, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/browser/terminalProcessExtHostProxy'; import { IEnvironmentVariableService, ISerializableEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { deserializeEnvironmentVariableCollection, serializeEnvironmentVariableCollection } from 'vs/workbench/contrib/terminal/common/environmentVariableShared'; -import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminalProfileResolverService, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IStartExtensionTerminalRequest, ITerminalProcessExtHostProxy, ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; import { withNullAsUndefined } from 'vs/base/common/types'; import { OperatingSystem, OS } from 'vs/base/common/platform'; diff --git a/src/vs/workbench/contrib/terminal/browser/remoteTerminalService.ts b/src/vs/workbench/contrib/terminal/browser/remoteTerminalService.ts index 3ed3747df3d..619b98e9212 100644 --- a/src/vs/workbench/contrib/terminal/browser/remoteTerminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/remoteTerminalService.ts @@ -17,11 +17,12 @@ import { ILogService } from 'vs/platform/log/common/log'; import { INotificationHandle, INotificationService, IPromptChoice, Severity } from 'vs/platform/notification/common/notification'; import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver'; import { IRequestResolveVariablesEvent, IShellLaunchConfig, IShellLaunchConfigDto, ITerminalChildProcess, ITerminalProfile, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TerminalIcon } from 'vs/platform/terminal/common/terminal'; +import { IProcessDetails } from 'vs/platform/terminal/common/terminalProcess'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; import { RemotePty } from 'vs/workbench/contrib/terminal/browser/remotePty'; import { IRemoteTerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { ICompleteTerminalConfiguration, RemoteTerminalChannelClient, REMOTE_TERMINAL_CHANNEL_NAME } from 'vs/workbench/contrib/terminal/common/remoteTerminalChannel'; -import { IRemoteTerminalAttachTarget, ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalConfigHelper } from 'vs/workbench/contrib/terminal/common/terminal'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; @@ -195,18 +196,20 @@ export class RemoteTerminalService extends Disposable implements IRemoteTerminal return undefined; } - async listProcesses(): Promise { + async listProcesses(): Promise { const terms = this._remoteTerminalChannel ? await this._remoteTerminalChannel.listProcesses() : []; return terms.map(termDto => { - return { + return { id: termDto.id, pid: termDto.pid, title: termDto.title, + titleSource: termDto.titleSource, cwd: termDto.cwd, workspaceId: termDto.workspaceId, workspaceName: termDto.workspaceName, icon: termDto.icon, - color: termDto.color + color: termDto.color, + isOrphan: termDto.isOrphan }; }); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts index 6c2315fc798..0268f12c9bc 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts @@ -8,8 +8,8 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { FindReplaceState } from 'vs/editor/contrib/find/findState'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; -import { IOffProcessTerminalService, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalIcon, TerminalShellType } from 'vs/platform/terminal/common/terminal'; -import { ICommandTracker, INavigationMode, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalProcessExtHostProxy, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IOffProcessTerminalService, IShellLaunchConfig, ITerminalChildProcess, ITerminalDimensions, ITerminalLaunchError, ITerminalProfile, ITerminalTabLayoutInfoById, TerminalIcon, TitleEventSource, TerminalShellType } from 'vs/platform/terminal/common/terminal'; +import { ICommandTracker, INavigationMode, IRemoteTerminalAttachTarget, IStartExtensionTerminalRequest, ITerminalConfigHelper, ITerminalProcessExtHostProxy } from 'vs/workbench/contrib/terminal/common/terminal'; import type { Terminal as XTermTerminal } from 'xterm'; import type { SearchAddon as XTermSearchAddon } from 'xterm-addon-search'; import type { Unicode11Addon as XTermUnicode11Addon } from 'xterm-addon-unicode11'; @@ -378,6 +378,11 @@ export interface ITerminalInstance { */ readonly title: string; + /** + * How the current title was set. + */ + readonly titleSource: TitleEventSource; + /** * The shell type of the terminal. */ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts index c0a7b7ae945..a3def71891b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalActions.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalActions.ts @@ -26,13 +26,13 @@ import { IListService } from 'vs/platform/list/browser/listService'; import { INotificationService } from 'vs/platform/notification/common/notification'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { IPickOptions, IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput'; -import { ILocalTerminalService, ITerminalProfile, TerminalSettingId } from 'vs/platform/terminal/common/terminal'; +import { ILocalTerminalService, ITerminalProfile, TerminalSettingId, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands'; import { FindInFilesCommand, IFindInFilesArgs } from 'vs/workbench/contrib/search/browser/searchActions'; import { Direction, IRemoteTerminalService, ITerminalInstance, ITerminalInstanceService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal'; import { TerminalQuickAccessProvider } from 'vs/workbench/contrib/terminal/browser/terminalQuickAccess'; -import { IRemoteTerminalAttachTarget, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, KEYBINDING_CONTEXT_TERMINAL_FIND_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_TABS_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TABS_SINGULAR_SELECTION, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_ACTION_CATEGORY, TerminalCommandId, TERMINAL_VIEW_ID, TitleEventSource } from 'vs/workbench/contrib/terminal/common/terminal'; +import { IRemoteTerminalAttachTarget, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, KEYBINDING_CONTEXT_TERMINAL_FIND_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_TABS_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TABS_SINGULAR_SELECTION, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_ACTION_CATEGORY, TerminalCommandId, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal'; import { ITerminalContributionService } from 'vs/workbench/contrib/terminal/common/terminalExtensionPoints'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import { IHistoryService } from 'vs/workbench/services/history/common/history'; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index fb2acc2531f..f715d7b2029 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -24,7 +24,7 @@ import { activeContrastBorder, scrollbarSliderActiveBackground, scrollbarSliderB import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { PANEL_BACKGROUND, SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme'; import { TerminalWidgetManager } from 'vs/workbench/contrib/terminal/browser/widgets/widgetManager'; -import { ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_VIEW_ID, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, TitleEventSource, DEFAULT_COMMANDS_TO_SKIP_SHELL, TERMINAL_CREATION_COMMANDS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, SUGGESTED_RENDERER_TYPE, ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; +import { ITerminalProcessManager, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, NEVER_MEASURE_RENDER_TIME_STORAGE_KEY, ProcessState, TERMINAL_VIEW_ID, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, INavigationMode, DEFAULT_COMMANDS_TO_SKIP_SHELL, TERMINAL_CREATION_COMMANDS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, SUGGESTED_RENDERER_TYPE, ITerminalProfileResolverService } from 'vs/workbench/contrib/terminal/common/terminal'; import { ansiColorIdentifiers, ansiColorMap, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR } from 'vs/workbench/contrib/terminal/common/terminalColorRegistry'; import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper'; import { TerminalLinkManager } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager'; @@ -46,7 +46,7 @@ import { TypeAheadAddon } from 'vs/workbench/contrib/terminal/browser/terminalTy import { BrowserFeatures } from 'vs/base/browser/canIUse'; import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences'; import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; -import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType, TerminalSettingId, TerminalIcon } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, TerminalShellType, TerminalSettingId, TitleEventSource, TerminalIcon } from 'vs/platform/terminal/common/terminal'; import { IProductService } from 'vs/platform/product/common/productService'; import { formatMessageForTerminal } from 'vs/workbench/contrib/terminal/common/terminalStrings'; import { AutoOpenBarrier } from 'vs/base/common/async'; @@ -105,6 +105,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { private _skipTerminalCommands: string[]; private _shellType: TerminalShellType; private _title: string = ''; + private _titleSource: TitleEventSource = TitleEventSource.Process; private _container: HTMLElement | undefined; private _wrapperElement: (HTMLElement & { xterm?: XTermTerminal }) | undefined; private _xterm: XTermTerminal | undefined; @@ -187,6 +188,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { get isDisconnected(): boolean { return this._processManager.isDisconnected; } get isRemote(): boolean { return this._processManager.remoteAuthority !== undefined; } get title(): string { return this._title; } + get titleSource(): TitleEventSource { return this._titleSource; } get icon(): TerminalIcon | undefined { return this._getIcon(); } get color(): string | undefined { return this._getColor(); } @@ -286,6 +288,11 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { // Wait for a period to allow a container to be ready await this._containerReadyBarrier.wait(); await this._createProcess(); + + // Re-establish the title after reconnect + if (this.shellLaunchConfig.attachPersistentProcess) { + this.setTitle(this.shellLaunchConfig.attachPersistentProcess.title, this.shellLaunchConfig.attachPersistentProcess.titleSource); + } }); this.addDisposable(this._configurationService.onDidChangeConfiguration(e => { @@ -1623,6 +1630,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { } const didTitleChange = title !== this._title; this._title = title; + this._titleSource = eventSource; if (didTitleChange) { this._setAriaLabel(this._xterm, this._instanceId, this._title); diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 269bf44f401..e2e19ad7fbb 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -294,12 +294,8 @@ export class TerminalService implements ITerminalService { // The state must be updated when the terminal is relaunched, otherwise the persistent // terminal ID will be stale and the process will be leaked. this.onInstanceProcessIdReady(() => this._saveState()); - this.onInstanceTitleChanged(instance => { - this._updateTitle(instance); - }); - this.onInstanceIconChanged(instance => { - this._updateIcon(instance); - }); + this.onInstanceTitleChanged(instance => this._updateTitle(instance)); + this.onInstanceIconChanged(instance => this._updateIcon(instance)); } private _handleInstanceContextKeys(): void { @@ -410,7 +406,7 @@ export class TerminalService implements ITerminalService { if (!this.configHelper.config.enablePersistentSessions || !instance || !instance.persistentProcessId || !instance.title) { return; } - this._offProcessTerminalService?.updateTitle(instance.persistentProcessId, instance.title); + this._offProcessTerminalService?.updateTitle(instance.persistentProcessId, instance.title, instance.titleSource); } @debounce(500) diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index 4788b47c4f1..14571020725 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -9,7 +9,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IProcessEnvironment, OperatingSystem } from 'vs/base/common/platform'; import { IExtensionPointDescriptor } from 'vs/workbench/services/extensions/common/extensionsRegistry'; -import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, TerminalShellType } from 'vs/platform/terminal/common/terminal'; +import { IProcessDataEvent, IProcessReadyEvent, IShellLaunchConfig, ITerminalDimensions, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalProfileObject, TerminalShellType, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IEnvironmentVariableInfo } from 'vs/workbench/contrib/terminal/common/environmentVariable'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { URI } from 'vs/base/common/uri'; @@ -231,6 +231,7 @@ export interface IRemoteTerminalAttachTarget { id: number; pid: number; title: string; + titleSource: TitleEventSource; cwd: string; workspaceId: string; workspaceName: string; @@ -364,15 +365,6 @@ export interface IDefaultShellAndArgsRequest { callback: (shell: string, args: string[] | string | undefined) => void; } -export enum TitleEventSource { - /** From the API or the rename command that overrides any other type */ - Api, - /** From the process name property*/ - Process, - /** From the VT sequence */ - Sequence -} - export const QUICK_LAUNCH_PROFILE_CHOICE = 'workbench.action.terminal.profile.choice'; export const enum TerminalCommandId { diff --git a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalService.ts b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalService.ts index ed79d042d24..18feaabdacd 100644 --- a/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalService.ts +++ b/src/vs/workbench/contrib/terminal/electron-sandbox/localTerminalService.ts @@ -14,7 +14,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { ILabelService } from 'vs/platform/label/common/label'; import { ILogService } from 'vs/platform/log/common/log'; import { INotificationHandle, INotificationService, IPromptChoice, Severity } from 'vs/platform/notification/common/notification'; -import { ILocalTerminalService, IShellLaunchConfig, ITerminalChildProcess, ITerminalsLayoutInfo, ITerminalsLayoutInfoById } from 'vs/platform/terminal/common/terminal'; +import { ILocalTerminalService, IShellLaunchConfig, ITerminalChildProcess, ITerminalsLayoutInfo, ITerminalsLayoutInfoById, TitleEventSource } from 'vs/platform/terminal/common/terminal'; import { IGetTerminalLayoutInfoArgs, IProcessDetails, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess'; import { ILocalPtyService } from 'vs/platform/terminal/electron-sandbox/terminal'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -115,8 +115,8 @@ export class LocalTerminalService extends Disposable implements ILocalTerminalSe })); } } - async updateTitle(id: number, title: string): Promise { - await this._localPtyService.updateTitle(id, title); + async updateTitle(id: number, title: string, titleSource: TitleEventSource): Promise { + await this._localPtyService.updateTitle(id, title, titleSource); } async updateIcon(id: number, icon: URI | { light: URI; dark: URI } | { id: string, color?: { id: string } }, color?: string): Promise {