Fix remote terminal reconnect

Remote terminals were being saved on the server using the 'persistent
terminal ID' which is correct, but on the client side they were using
the 'terminal instance ID'. This works fine until a terminal gets relaunched
or a second window is opened, at which point the 2 IDs no longer align with
each other so restoring becomes flaky (some terminals may restore but it's
mostly broken).

This change uses the persistent terminal ID correctly in the remote's impl
of ITerminalChildProcess and falls back to 0 if it's not available (to be
filtered out all together in microsoft/vscode#117971). An extra event
listener for ready was also added to trigger the remote layout update since
that fires when persistentTerminalId is ready to go.

Fixes #117896
This commit is contained in:
Daniel Imms 2021-03-02 07:14:09 -08:00
parent 85cbc2bc7c
commit 9e4520310e
3 changed files with 7 additions and 3 deletions

View file

@ -104,11 +104,12 @@ export class RemoteTerminalProcess extends Disposable implements ITerminalChildP
private _startBarrier: Barrier;
private _persistentTerminalId: number;
public get id(): number { return this._persistentTerminalId; }
private _inReplay = false;
constructor(
readonly id: number,
private readonly _instanceId: number,
readonly shouldPersist: boolean,
private readonly _shellLaunchConfig: IShellLaunchConfig,
private readonly _activeWorkspaceRootUri: URI | undefined,
@ -151,7 +152,7 @@ export class RemoteTerminalProcess extends Disposable implements ITerminalChildP
env: this._shellLaunchConfig.env
};
this._logService.trace('Spawning remote agent process', { terminalId: this.id, shellLaunchConfigDto });
this._logService.trace('Spawning remote agent process', { terminalId: this._instanceId, shellLaunchConfigDto });
const result = await this._remoteTerminalChannel.createTerminalProcess(
shellLaunchConfigDto,

View file

@ -230,6 +230,9 @@ export class TerminalService implements ITerminalService {
this.onActiveTabChanged(() => isRemote ? this._updateRemoteState() : this._updateLocalState());
this.onActiveInstanceChanged(() => isRemote ? this._updateRemoteState() : this._updateLocalState());
this.onInstancesChanged(() => isRemote ? this._updateRemoteState() : this._updateLocalState());
// 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(() => isRemote ? this._updateRemoteState() : this._updateLocalState());
}
public setNativeWindowsDelegate(delegate: ITerminalNativeWindowsDelegate): void {

View file

@ -307,7 +307,7 @@ export class TerminalTab extends Disposable implements ITerminalTab {
terminals: instances.map(t => {
return {
relativeSize: isHorizontal ? t.cols / totalSize : t.rows / totalSize,
terminal: t.persistentTerminalId ? t.persistentTerminalId : t.id
terminal: t.persistentTerminalId || 0
};
})
};