Skip to content

Commit af0c034

Browse files
authored
fix extension pty terminal test failures (microsoft#135672)
1 parent 870aa86 commit af0c034

18 files changed

+248
-386
lines changed

src/vs/platform/terminal/common/terminal.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,13 @@ export const IPtyService = createDecorator<IPtyService>('ptyService');
181181
export const enum ProcessPropertyType {
182182
Cwd = 'cwd',
183183
InitialCwd = 'initialCwd',
184-
FixedDimensions = 'fixedDimensions'
184+
FixedDimensions = 'fixedDimensions',
185+
Title = 'title',
186+
ShellType = 'shellType',
187+
HasChildProcesses = 'hasChildProcesses',
188+
ResolvedShellLaunchConfig = 'resolvedShellLaunchConfig',
189+
OverrideDimensions = 'overrideDimensions',
190+
Exit = 'exit'
185191
}
186192

187193
export interface IProcessProperty<T extends ProcessPropertyType> {
@@ -192,7 +198,13 @@ export interface IProcessProperty<T extends ProcessPropertyType> {
192198
export interface IProcessPropertyMap {
193199
[ProcessPropertyType.Cwd]: string,
194200
[ProcessPropertyType.InitialCwd]: string,
195-
[ProcessPropertyType.FixedDimensions]: IFixedTerminalDimensions
201+
[ProcessPropertyType.FixedDimensions]: IFixedTerminalDimensions,
202+
[ProcessPropertyType.Title]: string
203+
[ProcessPropertyType.ShellType]: TerminalShellType | undefined,
204+
[ProcessPropertyType.HasChildProcesses]: boolean,
205+
[ProcessPropertyType.ResolvedShellLaunchConfig]: IShellLaunchConfig,
206+
[ProcessPropertyType.OverrideDimensions]: ITerminalDimensionsOverride | undefined,
207+
[ProcessPropertyType.Exit]: number | undefined
196208
}
197209

198210
export interface IFixedTerminalDimensions {
@@ -218,16 +230,10 @@ export interface IPtyService {
218230
readonly onPtyHostRequestResolveVariables?: Event<IRequestResolveVariablesEvent>;
219231

220232
readonly onProcessData: Event<{ id: number, event: IProcessDataEvent | string }>;
221-
readonly onProcessExit: Event<{ id: number, event: number | undefined }>;
222-
readonly onProcessReady: Event<{ id: number, event: { pid: number, cwd: string, capabilities: ProcessCapability[] } }>;
223-
readonly onProcessTitleChanged: Event<{ id: number, event: string }>;
224-
readonly onProcessShellTypeChanged: Event<{ id: number, event: TerminalShellType }>;
225-
readonly onProcessOverrideDimensions: Event<{ id: number, event: ITerminalDimensionsOverride | undefined }>;
226-
readonly onProcessResolvedShellLaunchConfig: Event<{ id: number, event: IShellLaunchConfig }>;
233+
readonly onProcessReady: Event<{ id: number, event: IProcessReadyEvent }>;
227234
readonly onProcessReplay: Event<{ id: number, event: IPtyHostProcessReplayEvent }>;
228235
readonly onProcessOrphanQuestion: Event<{ id: number }>;
229236
readonly onDidRequestDetach: Event<{ requestId: number, workspaceId: string, instanceId: number }>;
230-
readonly onProcessDidChangeHasChildProcesses: Event<{ id: number, event: boolean }>;
231237
readonly onDidChangeProperty: Event<{ id: number, property: IProcessProperty<any> }>
232238

233239
restartPtyHost?(): Promise<void>;
@@ -527,13 +533,7 @@ export interface ITerminalChildProcess {
527533
capabilities: ProcessCapability[];
528534

529535
onProcessData: Event<IProcessDataEvent | string>;
530-
onProcessExit: Event<number | undefined>;
531536
onProcessReady: Event<IProcessReadyEvent>;
532-
onProcessTitleChanged: Event<string>;
533-
onProcessShellTypeChanged: Event<TerminalShellType>;
534-
onProcessOverrideDimensions?: Event<ITerminalDimensionsOverride | undefined>;
535-
onProcessResolvedShellLaunchConfig?: Event<IShellLaunchConfig>;
536-
onDidChangeHasChildProcesses?: Event<boolean>;
537537
onDidChangeProperty: Event<IProcessProperty<any>>;
538538

539539
/**

src/vs/platform/terminal/node/ptyHostService.ts

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { ILogService } from 'vs/platform/log/common/log';
1717
import { LogLevelChannelClient } from 'vs/platform/log/common/logIpc';
1818
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
1919
import { RequestStore } from 'vs/platform/terminal/common/requestStore';
20-
import { HeartbeatConstants, IHeartbeatService, IProcessDataEvent, IPtyService, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, TerminalIcon, TerminalIpcChannels, IProcessProperty, TerminalShellType, TitleEventSource, ProcessPropertyType, ProcessCapability, IProcessPropertyMap, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
20+
import { HeartbeatConstants, IHeartbeatService, IProcessDataEvent, IPtyService, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalLaunchError, ITerminalProfile, ITerminalsLayoutInfo, TerminalIcon, TerminalIpcChannels, IProcessProperty, TitleEventSource, ProcessPropertyType, ProcessCapability, IProcessPropertyMap, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
2121
import { registerTerminalPlatformConfiguration } from 'vs/platform/terminal/common/terminalPlatformConfiguration';
2222
import { IGetTerminalLayoutInfoArgs, IProcessDetails, IPtyHostProcessReplayEvent, ISetTerminalLayoutInfoArgs } from 'vs/platform/terminal/common/terminalProcess';
2323
import { detectAvailableProfiles } from 'vs/platform/terminal/node/terminalProfiles';
@@ -64,26 +64,14 @@ export class PtyHostService extends Disposable implements IPtyService {
6464

6565
private readonly _onProcessData = this._register(new Emitter<{ id: number, event: IProcessDataEvent | string }>());
6666
readonly onProcessData = this._onProcessData.event;
67-
private readonly _onProcessExit = this._register(new Emitter<{ id: number, event: number | undefined }>());
68-
readonly onProcessExit = this._onProcessExit.event;
6967
private readonly _onProcessReady = this._register(new Emitter<{ id: number, event: { pid: number, cwd: string, capabilities: ProcessCapability[] } }>());
7068
readonly onProcessReady = this._onProcessReady.event;
7169
private readonly _onProcessReplay = this._register(new Emitter<{ id: number, event: IPtyHostProcessReplayEvent }>());
7270
readonly onProcessReplay = this._onProcessReplay.event;
73-
private readonly _onProcessTitleChanged = this._register(new Emitter<{ id: number, event: string }>());
74-
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
75-
private readonly _onProcessShellTypeChanged = this._register(new Emitter<{ id: number, event: TerminalShellType }>());
76-
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
77-
private readonly _onProcessOverrideDimensions = this._register(new Emitter<{ id: number, event: ITerminalDimensionsOverride | undefined }>());
78-
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
79-
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
80-
readonly onProcessResolvedShellLaunchConfig = this._onProcessResolvedShellLaunchConfig.event;
8171
private readonly _onProcessOrphanQuestion = this._register(new Emitter<{ id: number }>());
8272
readonly onProcessOrphanQuestion = this._onProcessOrphanQuestion.event;
8373
private readonly _onDidRequestDetach = this._register(new Emitter<{ requestId: number, workspaceId: string, instanceId: number }>());
8474
readonly onDidRequestDetach = this._onDidRequestDetach.event;
85-
private readonly _onProcessDidChangeHasChildProcesses = this._register(new Emitter<{ id: number, event: boolean }>());
86-
readonly onProcessDidChangeHasChildProcesses = this._onProcessDidChangeHasChildProcesses.event;
8775
private readonly _onDidChangeProperty = this._register(new Emitter<{ id: number, property: IProcessProperty<any> }>());
8876
readonly onDidChangeProperty = this._onDidChangeProperty.event;
8977

@@ -202,13 +190,7 @@ export class PtyHostService extends Disposable implements IPtyService {
202190
// Create proxy and forward events
203191
const proxy = ProxyChannel.toService<IPtyService>(client.getChannel(TerminalIpcChannels.PtyHost));
204192
this._register(proxy.onProcessData(e => this._onProcessData.fire(e)));
205-
this._register(proxy.onProcessExit(e => this._onProcessExit.fire(e)));
206193
this._register(proxy.onProcessReady(e => this._onProcessReady.fire(e)));
207-
this._register(proxy.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e)));
208-
this._register(proxy.onProcessShellTypeChanged(e => this._onProcessShellTypeChanged.fire(e)));
209-
this._register(proxy.onProcessOverrideDimensions(e => this._onProcessOverrideDimensions.fire(e)));
210-
this._register(proxy.onProcessResolvedShellLaunchConfig(e => this._onProcessResolvedShellLaunchConfig.fire(e)));
211-
this._register(proxy.onProcessDidChangeHasChildProcesses(e => this._onProcessDidChangeHasChildProcesses.fire(e)));
212194
this._register(proxy.onDidChangeProperty(e => this._onDidChangeProperty.fire(e)));
213195
this._register(proxy.onProcessReplay(e => this._onProcessReplay.fire(e)));
214196
this._register(proxy.onProcessOrphanQuestion(e => this._onProcessOrphanQuestion.fire(e)));

src/vs/platform/terminal/node/ptyService.ts

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri';
1212
import { getSystemShell } from 'vs/base/node/shell';
1313
import { ILogService } from 'vs/platform/log/common/log';
1414
import { RequestStore } from 'vs/platform/terminal/common/requestStore';
15-
import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalDimensionsOverride, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TerminalShellType, TitleEventSource, ProcessPropertyType, ProcessCapability, IProcessPropertyMap, IFixedTerminalDimensions } from 'vs/platform/terminal/common/terminal';
15+
import { IProcessDataEvent, IProcessReadyEvent, IPtyService, IRawTerminalInstanceLayoutInfo, IReconnectConstants, IRequestResolveVariablesEvent, IShellLaunchConfig, ITerminalInstanceLayoutInfoById, ITerminalLaunchError, ITerminalsLayoutInfo, ITerminalTabLayoutInfoById, TerminalIcon, IProcessProperty, TitleEventSource, ProcessPropertyType, IProcessPropertyMap, IFixedTerminalDimensions, ProcessCapability } from 'vs/platform/terminal/common/terminal';
1616
import { TerminalDataBufferer } from 'vs/platform/terminal/common/terminalDataBuffering';
1717
import { escapeNonWindowsPath } from 'vs/platform/terminal/common/terminalEnvironment';
1818
import { Terminal as XtermTerminal } from 'xterm-headless';
@@ -44,24 +44,12 @@ export class PtyService extends Disposable implements IPtyService {
4444
readonly onProcessData = this._onProcessData.event;
4545
private readonly _onProcessReplay = this._register(new Emitter<{ id: number, event: IPtyHostProcessReplayEvent }>());
4646
readonly onProcessReplay = this._onProcessReplay.event;
47-
private readonly _onProcessExit = this._register(new Emitter<{ id: number, event: number | undefined }>());
48-
readonly onProcessExit = this._onProcessExit.event;
4947
private readonly _onProcessReady = this._register(new Emitter<{ id: number, event: { pid: number, cwd: string, capabilities: ProcessCapability[] } }>());
5048
readonly onProcessReady = this._onProcessReady.event;
51-
private readonly _onProcessTitleChanged = this._register(new Emitter<{ id: number, event: string }>());
52-
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
53-
private readonly _onProcessShellTypeChanged = this._register(new Emitter<{ id: number, event: TerminalShellType }>());
54-
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
55-
private readonly _onProcessOverrideDimensions = this._register(new Emitter<{ id: number, event: ITerminalDimensionsOverride | undefined }>());
56-
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
57-
private readonly _onProcessResolvedShellLaunchConfig = this._register(new Emitter<{ id: number, event: IShellLaunchConfig }>());
58-
readonly onProcessResolvedShellLaunchConfig = this._onProcessResolvedShellLaunchConfig.event;
5949
private readonly _onProcessOrphanQuestion = this._register(new Emitter<{ id: number }>());
6050
readonly onProcessOrphanQuestion = this._onProcessOrphanQuestion.event;
6151
private readonly _onDidRequestDetach = this._register(new Emitter<{ requestId: number, workspaceId: string, instanceId: number }>());
6252
readonly onDidRequestDetach = this._onDidRequestDetach.event;
63-
private readonly _onProcessDidChangeHasChildProcesses = this._register(new Emitter<{ id: number, event: boolean }>());
64-
readonly onProcessDidChangeHasChildProcesses = this._onProcessDidChangeHasChildProcesses.event;
6553
private readonly _onDidChangeProperty = this._register(new Emitter<{ id: number, property: IProcessProperty<any> }>());
6654
readonly onDidChangeProperty = this._onDidChangeProperty.event;
6755

@@ -195,31 +183,21 @@ export class PtyService extends Disposable implements IPtyService {
195183
const id = ++this._lastPtyId;
196184
const process = new TerminalProcess(shellLaunchConfig, cwd, cols, rows, env, executableEnv, windowsEnableConpty, this._logService);
197185
process.onProcessData(event => this._onProcessData.fire({ id, event }));
198-
process.onProcessExit(event => this._onProcessExit.fire({ id, event }));
199-
if (process.onProcessOverrideDimensions) {
200-
process.onProcessOverrideDimensions(event => this._onProcessOverrideDimensions.fire({ id, event }));
201-
}
202-
if (process.onProcessResolvedShellLaunchConfig) {
203-
process.onProcessResolvedShellLaunchConfig(event => this._onProcessResolvedShellLaunchConfig.fire({ id, event }));
204-
}
205-
if (process.onDidChangeHasChildProcesses) {
206-
process.onDidChangeHasChildProcesses(event => this._onProcessDidChangeHasChildProcesses.fire({ id, event }));
207-
}
208186
const processLaunchOptions: IPersistentTerminalProcessLaunchOptions = {
209187
env,
210188
executableEnv,
211189
windowsEnableConpty
212190
};
213191
const persistentProcess = new PersistentTerminalProcess(id, process, workspaceId, workspaceName, shouldPersist, cols, rows, processLaunchOptions, unicodeVersion, this._reconnectConstants, this._logService, isReviving ? shellLaunchConfig.initialText : undefined, shellLaunchConfig.icon, shellLaunchConfig.color, shellLaunchConfig.fixedDimensions);
214-
process.onProcessExit(() => {
215-
persistentProcess.dispose();
216-
this._ptys.delete(id);
192+
process.onDidChangeProperty(property => {
193+
if (property.type === ProcessPropertyType.Exit) {
194+
persistentProcess.dispose();
195+
this._ptys.delete(id);
196+
}
197+
this._onDidChangeProperty.fire({ id, property });
217198
});
218-
process.onDidChangeProperty(property => this._onDidChangeProperty.fire({ id, property }));
219199
persistentProcess.onProcessReplay(event => this._onProcessReplay.fire({ id, event }));
220200
persistentProcess.onProcessReady(event => this._onProcessReady.fire({ id, event }));
221-
persistentProcess.onProcessTitleChanged(event => this._onProcessTitleChanged.fire({ id, event }));
222-
persistentProcess.onProcessShellTypeChanged(event => this._onProcessShellTypeChanged.fire({ id, event }));
223201
persistentProcess.onProcessOrphanQuestion(() => this._onProcessOrphanQuestion.fire({ id }));
224202
persistentProcess.onDidChangeProperty(property => this._onDidChangeProperty.fire({ id, property }));
225203
this._ptys.set(id, persistentProcess);
@@ -428,12 +406,6 @@ export class PersistentTerminalProcess extends Disposable {
428406
readonly onProcessReplay = this._onProcessReplay.event;
429407
private readonly _onProcessReady = this._register(new Emitter<IProcessReadyEvent>());
430408
readonly onProcessReady = this._onProcessReady.event;
431-
private readonly _onProcessTitleChanged = this._register(new Emitter<string>());
432-
readonly onProcessTitleChanged = this._onProcessTitleChanged.event;
433-
private readonly _onProcessShellTypeChanged = this._register(new Emitter<TerminalShellType>());
434-
readonly onProcessShellTypeChanged = this._onProcessShellTypeChanged.event;
435-
private readonly _onProcessOverrideDimensions = this._register(new Emitter<ITerminalDimensionsOverride | undefined>());
436-
readonly onProcessOverrideDimensions = this._onProcessOverrideDimensions.event;
437409
private readonly _onProcessData = this._register(new Emitter<string>());
438410
readonly onProcessData = this._onProcessData.event;
439411
private readonly _onProcessOrphanQuestion = this._register(new Emitter<void>());
@@ -511,20 +483,24 @@ export class PersistentTerminalProcess extends Disposable {
511483
this._logService.info(`Persistent process "${this._persistentProcessId}": The short reconnection grace time of ${printTime(reconnectConstants.shortGraceTime)} has expired, shutting down pid ${this._pid}`);
512484
this.shutdown(true);
513485
}, reconnectConstants.shortGraceTime));
514-
486+
this._register(this._terminalProcess.onDidChangeProperty(e => {
487+
if (e.type === ProcessPropertyType.Exit) {
488+
this._bufferer.stopBuffering(this._persistentProcessId);
489+
}
490+
this._onDidChangeProperty.fire(e);
491+
}));
515492
this._register(this._terminalProcess.onProcessReady(e => {
516493
this._pid = e.pid;
517494
this._cwd = e.cwd;
518495
this._onProcessReady.fire(e);
519496
}));
520-
this._register(this._terminalProcess.onProcessTitleChanged(e => this._onProcessTitleChanged.fire(e)));
521-
this._register(this._terminalProcess.onProcessShellTypeChanged(e => this._onProcessShellTypeChanged.fire(e)));
522-
this._register(this._terminalProcess.onDidChangeProperty(e => this._onDidChangeProperty.fire(e)));
497+
this._register(this._terminalProcess.onDidChangeProperty(e => {
498+
this._onDidChangeProperty.fire(e);
499+
}));
523500

524501
// Data buffering to reduce the amount of messages going to the renderer
525502
this._bufferer = new TerminalDataBufferer((_, data) => this._onProcessData.fire(data));
526503
this._register(this._bufferer.startBuffering(this._persistentProcessId, this._terminalProcess.onProcessData));
527-
this._register(this._terminalProcess.onProcessExit(() => this._bufferer.stopBuffering(this._persistentProcessId)));
528504

529505
// Data recording for reconnect
530506
this._register(this.onProcessData(e => this._serializer.handleData(e)));
@@ -579,8 +555,8 @@ export class PersistentTerminalProcess extends Disposable {
579555
}
580556
} else {
581557
this._onProcessReady.fire({ pid: this._pid, cwd: this._cwd, capabilities: this._terminalProcess.capabilities, requiresWindowsMode: isWindows && getWindowsBuildNumber() < 21376 });
582-
this._onProcessTitleChanged.fire(this._terminalProcess.currentTitle);
583-
this._onProcessShellTypeChanged.fire(this._terminalProcess.shellType);
558+
this._onDidChangeProperty.fire({ type: ProcessPropertyType.Title, value: this._terminalProcess.currentTitle });
559+
this._onDidChangeProperty.fire({ type: ProcessPropertyType.ShellType, value: this._terminalProcess.shellType });
584560
this.triggerReplay();
585561
}
586562
return undefined;

0 commit comments

Comments
 (0)