diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts index b6c6ec8c4f9..b8d10e1ee5d 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/terminal.test.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { window, commands, Terminal, TerminalDimensionsChangeEvent } from 'vscode'; +import { window, commands, Terminal, TerminalDimensionsChangeEvent, TerminalVirtualProcess, EventEmitter } from 'vscode'; import { doesNotThrow, equal, ok } from 'assert'; suite('window namespace tests', () => { @@ -198,6 +198,67 @@ suite('window namespace tests', () => { done(); }); }); + + suite('Virtual process terminals', () => { + test('should fire onDidOpenTerminal and onDidCloseTerminal', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(term.name, 'c'); + reg1.dispose(); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + term.dispose(); + }); + const virtualProcess: TerminalVirtualProcess = { + write: new EventEmitter().event + }; + window.createTerminal({ name: 'c', virtualProcess }); + }); + + test('should get dimensions event when shown', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + reg1.dispose(); + equal(terminal, term); + term.show(); + }); + const virtualProcess: TerminalVirtualProcess = { + write: new EventEmitter().event, + onDidChangeDimensions: dimensions => { + ok(dimensions.columns > 0); + ok(dimensions.rows > 0); + const reg2 = window.onDidCloseTerminal(() => { + reg2.dispose(); + done(); + }); + terminal.dispose(); + } + }; + const terminal = window.createTerminal({ name: 'foo', virtualProcess }); + }); + + test('should fire Terminal.onData on write', (done) => { + const reg1 = window.onDidOpenTerminal(term => { + equal(terminal, term); + reg1.dispose(); + const reg2 = terminal.onDidWriteData(data => { + equal(data, 'bar'); + reg2.dispose(); + const reg3 = window.onDidCloseTerminal(() => { + reg3.dispose(); + done(); + }); + terminal.dispose(); + }); + writeEmitter.fire('bar'); + }); + const writeEmitter = new EventEmitter(); + const virtualProcess: TerminalVirtualProcess = { + write: writeEmitter.event + }; + const terminal = window.createTerminal({ name: 'foo', virtualProcess }); + }); + }); }); }); diff --git a/src/vs/workbench/api/browser/mainThreadTerminalService.ts b/src/vs/workbench/api/browser/mainThreadTerminalService.ts index a388f623d74..d340fd55ed6 100644 --- a/src/vs/workbench/api/browser/mainThreadTerminalService.ts +++ b/src/vs/workbench/api/browser/mainThreadTerminalService.ts @@ -264,8 +264,9 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape this._terminalProcessesReady[proxy.terminalId](proxy); delete this._terminalProcessesReady[proxy.terminalId]; + // Note that onReisze is not being listened to here as it needs to fire when max dimensions + // change, excluding the dimension override proxy.onInput(data => this._proxy.$acceptProcessInput(proxy.terminalId, data)); - proxy.onResize(dimensions => this._proxy.$acceptProcessResize(proxy.terminalId, dimensions.cols, dimensions.rows)); proxy.onShutdown(immediate => this._proxy.$acceptProcessShutdown(proxy.terminalId, immediate)); proxy.onRequestCwd(() => this._proxy.$acceptProcessRequestCwd(proxy.terminalId)); proxy.onRequestInitialCwd(() => this._proxy.$acceptProcessRequestInitialCwd(proxy.terminalId)); diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index 66b370a505e..0605a48b680 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -433,13 +433,20 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape { } public $acceptTerminalMaximumDimensions(id: number, cols: number, rows: number): void { - this._getTerminalByIdEventually(id).then(() => { - // When a terminal's dimensions change, a renderer's _maximum_ dimensions change - const renderer = this._getTerminalRendererById(id); - if (renderer) { - renderer._setMaximumDimensions(cols, rows); - } - }); + if (this._terminalProcesses[id]) { + // Virtual processes only - when virtual process resize fires it means that the + // terminal's maximum dimensions changed + this._terminalProcesses[id].resize(cols, rows); + } else { + // Terminal renderer + this._getTerminalByIdEventually(id).then(() => { + // When a terminal's dimensions change, a renderer's _maximum_ dimensions change + const renderer = this._getTerminalRendererById(id); + if (renderer) { + renderer._setMaximumDimensions(cols, rows); + } + }); + } } public $acceptTerminalRendererInput(id: number, data: string): void { diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index cfe096303a2..9cff1fd187d 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -363,14 +363,17 @@ export class TerminalInstance implements ITerminalInstance { if (this._cols !== newCols || this._rows !== newRows) { this._cols = newCols; this._rows = newRows; - if (this.shellLaunchConfig.isRendererOnly) { - this._onMaximumDimensionsChanged.fire(); - } + this._fireMaximumDimensionsChanged(); } return dimension.width; } + @debounce(50) + private _fireMaximumDimensionsChanged(): void { + this._onMaximumDimensionsChanged.fire(); + } + private _getDimension(width: number, height: number): dom.Dimension | null { // The font needs to have been initialized const font = this._configHelper.getFont(this._xterm);