-
Notifications
You must be signed in to change notification settings - Fork 29.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't connect LocalTerminalBackend until LifecyclePhase.Restored #182631
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -35,40 +35,37 @@ import { Client as MessagePortClient } from 'vs/base/parts/ipc/common/ipc.mp'; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { acquirePort } from 'vs/base/parts/ipc/electron-sandbox/ipc.mp'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { mark } from 'vs/base/common/performance'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { DeferredPromise } from 'vs/base/common/async'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export class LocalTerminalBackendContribution implements IWorkbenchContribution { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
constructor( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@IInstantiationService instantiationService: IInstantiationService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ILogService logService: ILogService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ITerminalInstanceService terminalInstanceService: ITerminalInstanceService | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mark('code/willConnectPtyHost'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logService.trace('Renderer->PtyHost#connect: before acquirePort'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
acquirePort('vscode:createPtyHostMessageChannel', 'vscode:createPtyHostMessageChannelResult').then(port => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mark('code/didConnectPtyHost'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logService.trace('Renderer->PtyHost#connect: connection established'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const backend = instantiationService.createInstance(LocalTerminalBackend, port); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Registry.as<ITerminalBackendRegistry>(TerminalExtensions.Backend).registerTerminalBackend(backend); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
terminalInstanceService.didRegisterBackend(backend.remoteAuthority); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const backend = instantiationService.createInstance(LocalTerminalBackend); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Registry.as<ITerminalBackendRegistry>(TerminalExtensions.Backend).registerTerminalBackend(backend); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
terminalInstanceService.didRegisterBackend(backend.remoteAuthority); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBackend { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
readonly remoteAuthority = undefined; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly _ptys: Map<number, LocalPty> = new Map(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// HACK: ProxyChannels behave strangely when interacting with promises and seemingly never | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// resolve, so _proxyReady is awaited before every proxy use | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private _proxy?: IPtyService; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly _proxyReady: DeferredPromise<void>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could return the proxy so that you do not have to do all the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's what I did initially, the promise resolve function was definitely called, but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shared process is not using a deferred promise but just this if you want to copy: vscode/src/vs/workbench/services/sharedProcess/electron-sandbox/sharedProcessService.ts Lines 19 to 52 in 7a7d457
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh yeah the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yes! |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private _ptyHostDirectProxy: IPtyService; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly _ptys: Map<number, LocalPty> = new Map(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private readonly _onDidRequestDetach = this._register(new Emitter<{ requestId: number; workspaceId: string; instanceId: number }>()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
readonly onDidRequestDetach = this._onDidRequestDetach.event; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
constructor( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
port: MessagePort, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@IInstantiationService private readonly _instantiationService: IInstantiationService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@IWorkspaceContextService workspaceContextService: IWorkspaceContextService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ILifecycleService private readonly _lifecycleService: ILifecycleService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ILogService logService: ILogService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ILocalPtyService private readonly _localPtyService: ILocalPtyService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@ILabelService private readonly _labelService: ILabelService, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -86,81 +83,103 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
super(_localPtyService, logService, notificationService, historyService, _configurationResolverService, workspaceContextService); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// There are two connections to the pty host; one to the regular shared process | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// _localPtyService, and one directly via message port _ptyHostDirectProxy. The former is | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// used for pty host management messages, it would make sense in the future to use a | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// separate interface/service for this one. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const client = new MessagePortClient(port, `window:${this._environmentService.window.id}`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy = ProxyChannel.toService<IPtyService>(client.getChannel(TerminalIpcChannels.PtyHostWindow)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Attach process listeners | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.onProcessData(e => this._ptys.get(e.id)?.handleData(e.event)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.onDidChangeProperty(e => this._ptys.get(e.id)?.handleDidChangeProperty(e.property)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.onProcessExit(e => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const pty = this._ptys.get(e.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (pty) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pty.handleExit(e.event); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptys.delete(e.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.onProcessReady(e => this._ptys.get(e.id)?.handleReady(e.event)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.onProcessReplay(e => this._ptys.get(e.id)?.handleReplay(e.event)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.onProcessOrphanQuestion(e => this._ptys.get(e.id)?.handleOrphanQuestion()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.onDidRequestDetach(e => this._onDidRequestDetach.fire(e)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Listen for config changes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const initialConfig = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const match of Object.keys(initialConfig.autoReplies)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Ensure the reply is value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const reply = initialConfig.autoReplies[match] as string | null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (reply) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.installAutoReply(match, reply); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._proxyReady = new DeferredPromise<void>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._connectToDirectProxy(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
private async _connectToDirectProxy(): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// The pty host should not get launched until the first window restored phase | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._lifecycleService.when(LifecyclePhase.Restored); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mark('code/willConnectPtyHost'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._logService.trace('Renderer->PtyHost#connect: before acquirePort'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
acquirePort('vscode:createPtyHostMessageChannel', 'vscode:createPtyHostMessageChannelResult').then(port => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mark('code/didConnectPtyHost'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._logService.trace('Renderer->PtyHost#connect: connection established'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// There are two connections to the pty host; one to the regular shared process | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// _localPtyService, and one directly via message port _ptyHostDirectProxy. The former is | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// used for pty host management messages, it would make sense in the future to use a | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// separate interface/service for this one. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const client = new MessagePortClient(port, `window:${this._environmentService.window.id}`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const proxy = ProxyChannel.toService<IPtyService>(client.getChannel(TerminalIpcChannels.PtyHostWindow)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._proxy = proxy; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._proxyReady.complete(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Attach process listeners | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.onProcessData(e => this._ptys.get(e.id)?.handleData(e.event)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.onDidChangeProperty(e => this._ptys.get(e.id)?.handleDidChangeProperty(e.property)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.onProcessExit(e => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const pty = this._ptys.get(e.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (pty) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
pty.handleExit(e.event); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptys.delete(e.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.onProcessReady(e => this._ptys.get(e.id)?.handleReady(e.event)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.onProcessReplay(e => this._ptys.get(e.id)?.handleReplay(e.event)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.onProcessOrphanQuestion(e => this._ptys.get(e.id)?.handleOrphanQuestion()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.onDidRequestDetach(e => this._onDidRequestDetach.fire(e)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Listen for config changes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const initialConfig = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const match of Object.keys(initialConfig.autoReplies)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Ensure the reply is value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const reply = initialConfig.autoReplies[match] as string | null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (reply) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.installAutoReply(match, reply); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// TODO: Could simplify update to a single call | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._register(this._configurationService.onDidChangeConfiguration(async e => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (e.affectsConfiguration(TerminalSettingId.AutoReplies)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.uninstallAllAutoReplies(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const config = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const match of Object.keys(config.autoReplies)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Ensure the reply is value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const reply = config.autoReplies[match] as string | null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (reply) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._ptyHostDirectProxy.installAutoReply(match, reply); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// TODO: Could simplify update to a single call | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._register(this._configurationService.onDidChangeConfiguration(async e => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (e.affectsConfiguration(TerminalSettingId.AutoReplies)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.uninstallAllAutoReplies(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const config = this._configurationService.getValue<ITerminalConfiguration>(TERMINAL_CONFIG_SECTION); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (const match of Object.keys(config.autoReplies)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Ensure the reply is value | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const reply = config.autoReplies[match] as string | null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (reply) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
proxy.installAutoReply(match, reply); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
})); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
})); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async requestDetachInstance(workspaceId: string, instanceId: number): Promise<IProcessDetails | undefined> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._ptyHostDirectProxy.requestDetachInstance(workspaceId, instanceId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._proxy!.requestDetachInstance(workspaceId, instanceId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async acceptDetachInstanceReply(requestId: number, persistentProcessId?: number): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!persistentProcessId) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._logService.warn('Cannot attach to feature terminals, custom pty terminals, or those without a persistentProcessId'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._ptyHostDirectProxy.acceptDetachInstanceReply(requestId, persistentProcessId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._proxy!.acceptDetachInstanceReply(requestId, persistentProcessId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async persistTerminalState(): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const ids = Array.from(this._ptys.keys()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const serialized = await this._ptyHostDirectProxy.serializeTerminalState(ids); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const serialized = await this._proxy!.serializeTerminalState(ids); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._storageService.store(TerminalStorageKeys.TerminalBufferState, serialized, StorageScope.WORKSPACE, StorageTarget.MACHINE); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async updateTitle(id: number, title: string, titleSource: TitleEventSource): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._ptyHostDirectProxy.updateTitle(id, title, titleSource); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxy!.updateTitle(id, title, titleSource); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async updateIcon(id: number, userInitiated: boolean, icon: URI | { light: URI; dark: URI } | { id: string; color?: { id: string } }, color?: string): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._ptyHostDirectProxy.updateIcon(id, userInitiated, icon, color); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxy!.updateIcon(id, userInitiated, icon, color); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
updateProperty<T extends ProcessPropertyType>(id: number, property: ProcessPropertyType, value: IProcessPropertyMap[T]): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._ptyHostDirectProxy.updateProperty(id, property, value); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async updateProperty<T extends ProcessPropertyType>(id: number, property: ProcessPropertyType, value: IProcessPropertyMap[T]): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._proxy!.updateProperty(id, property, value); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async createProcess( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -174,15 +193,17 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
shouldPersist: boolean | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
): Promise<ITerminalChildProcess> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const executableEnv = await this._shellEnvironmentService.getShellEnv(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const id = await this._ptyHostDirectProxy.createProcess(shellLaunchConfig, cwd, cols, rows, unicodeVersion, env, executableEnv, options, shouldPersist, this._getWorkspaceId(), this._getWorkspaceName()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const id = await this._proxy!.createProcess(shellLaunchConfig, cwd, cols, rows, unicodeVersion, env, executableEnv, options, shouldPersist, this._getWorkspaceId(), this._getWorkspaceName()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const pty = this._instantiationService.createInstance(LocalPty, id, shouldPersist); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptys.set(id, pty); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return pty; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async attachToProcess(id: number): Promise<ITerminalChildProcess | undefined> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._ptyHostDirectProxy.attachToProcess(id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxy!.attachToProcess(id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const pty = this._instantiationService.createInstance(LocalPty, id, true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptys.set(id, pty); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return pty; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -194,7 +215,8 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async attachToRevivedProcess(id: number): Promise<ITerminalChildProcess | undefined> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const newId = await this._ptyHostDirectProxy.getRevivedPtyNewId(id) ?? id; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const newId = await this._proxy!.getRevivedPtyNewId(id) ?? id; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return await this.attachToProcess(newId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._logService.warn(`Couldn't attach to process ${e.message}`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -203,15 +225,18 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async listProcesses(): Promise<IProcessDetails[]> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._ptyHostDirectProxy.listProcesses(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._proxy!.listProcesses(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async reduceConnectionGraceTime(): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._ptyHostDirectProxy.reduceConnectionGraceTime(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._proxy!.reduceConnectionGraceTime(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getDefaultSystemShell(osOverride?: OperatingSystem): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._ptyHostDirectProxy.getDefaultSystemShell(osOverride); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._proxy!.getDefaultSystemShell(osOverride); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getProfiles(profiles: unknown, defaultProfile: unknown, includeDetectedProfiles?: boolean) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -220,23 +245,26 @@ class LocalTerminalBackend extends BaseTerminalBackend implements ITerminalBacke | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getEnvironment(): Promise<IProcessEnvironment> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._ptyHostDirectProxy.getEnvironment(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._proxy!.getEnvironment(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getShellEnvironment(): Promise<IProcessEnvironment> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._shellEnvironmentService.getShellEnv(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async getWslPath(original: string, direction: 'unix-to-win' | 'win-to-unix'): Promise<string> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._ptyHostDirectProxy.getWslPath(original, direction); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return this._proxy!.getWslPath(original, direction); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
async setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): Promise<void> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const args: ISetTerminalLayoutInfoArgs = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
workspaceId: this._getWorkspaceId(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
tabs: layoutInfo ? layoutInfo.tabs : [] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._ptyHostDirectProxy.setTerminalLayoutInfo(args); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxyReady.p; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await this._proxy!.setTerminalLayoutInfo(args); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Store in the storage service as well to be used when reviving processes as normally this | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// is stored in memory on the pty host | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
this._storageService.store(TerminalStorageKeys.TerminalLayoutInfo, JSON.stringify(args), StorageScope.WORKSPACE, StorageTarget.MACHINE); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably follow up on this, I am curious what the issue is.