Add global event window.onDidWriteTerminalData

Fixes #78502
This commit is contained in:
Daniel Imms
2019-08-06 09:51:03 -07:00
parent 21a4e91688
commit dc6b475be7
7 changed files with 200 additions and 36 deletions

View File

@@ -11,6 +11,7 @@ import { URI } from 'vs/base/common/uri';
import { StopWatch } from 'vs/base/common/stopwatch';
import { ITerminalInstanceService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@extHostNamedCustomer(MainContext.MainThreadTerminalService)
export class MainThreadTerminalService implements MainThreadTerminalServiceShape {
@@ -22,12 +23,14 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
private readonly _terminalProcessesReady = new Map<number, (proxy: ITerminalProcessExtHostProxy) => void>();
private readonly _terminalOnDidWriteDataListeners = new Map<number, IDisposable>();
private readonly _terminalOnDidAcceptInputListeners = new Map<number, IDisposable>();
private _dataEventTracker: TerminalDataEventTracker | undefined;
constructor(
extHostContext: IExtHostContext,
@ITerminalService private readonly _terminalService: ITerminalService,
@ITerminalInstanceService readonly terminalInstanceService: ITerminalInstanceService,
@IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService
@IRemoteAgentService readonly _remoteAgentService: IRemoteAgentService,
@IInstantiationService private readonly _instantiationService: IInstantiationService,
) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTerminalService);
this._remoteAuthority = extHostContext.remoteAuthority;
@@ -172,6 +175,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
}
}
/** @deprecated */
public $registerOnDataListener(terminalId: number): void {
const terminalInstance = this._terminalService.getInstanceFromId(terminalId);
if (!terminalInstance) {
@@ -191,14 +195,34 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
terminalInstance.addDisposable(listener);
}
public $startSendingDataEvents(): void {
if (!this._dataEventTracker) {
this._dataEventTracker = this._instantiationService.createInstance(TerminalDataEventTracker, (id, data) => {
this._onTerminalData2(id, data);
});
}
}
public $stopSendingDataEvents(): void {
if (this._dataEventTracker) {
this._dataEventTracker.dispose();
this._dataEventTracker = undefined;
}
}
private _onActiveTerminalChanged(terminalId: number | null): void {
this._proxy.$acceptActiveTerminalChanged(terminalId);
}
/** @deprecated */
private _onTerminalData(terminalId: number, data: string): void {
this._proxy.$acceptTerminalProcessData(terminalId, data);
}
private _onTerminalData2(terminalId: number, data: string): void {
this._proxy.$acceptTerminalProcessData2(terminalId, data);
}
private _onTitleChanged(terminalId: number, name: string): void {
this._proxy.$acceptTerminalTitleChange(terminalId, name);
}
@@ -371,3 +395,22 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
return terminal;
}
}
/**
* Encapsulates temporary tracking of data events from terminal instances, once disposed all
* listeners are removed.
*/
class TerminalDataEventTracker extends DisposableStore {
constructor(
private readonly _callback: (id: number, data: string) => void,
@ITerminalService private readonly _terminalService: ITerminalService
) {
super();
this._terminalService.terminalInstances.forEach(instance => this._register(instance));
this.add(this._terminalService.onInstanceCreated(instance => this._register(instance)));
}
private _register(instance: ITerminalInstance): void {
this.add(instance.onData(e => this._callback(instance.id, e)));
}
}