diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index 9a9702cdadae36440f540cebd7ff2b780de8e92d..dbad8f8a333c746ec4707a067d5d1bd69c3bd13f 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -53,11 +53,13 @@ export abstract class TerminalService extends CommonTerminalService implements I if (shell.runInBackground) { // TODO: When show is triggered, create a TerminalTab for this instance // TODO: How do backgrounded terminals interact with extensions listening for them, just ignore? - return this.createInstance(this._terminalFocusContextKey, + const instance = this.createInstance(this._terminalFocusContextKey, this.configHelper, undefined, shell, true); + this._backgroundedTerminalInstances.push(instance); + return instance; } const terminalTab = this._instantiationService.createInstance(TerminalTab, this._terminalFocusContextKey, @@ -77,6 +79,28 @@ export abstract class TerminalService extends CommonTerminalService implements I return instance; } + protected _showBackgroundTerminal(instance: ITerminalInstance): void { + // TODO: Remove from _backgroundedTerminalInstances + this._backgroundedTerminalInstances = this._backgroundedTerminalInstances.splice(this._backgroundedTerminalInstances.indexOf(instance), 1); + instance.shellLaunchConfig.runInBackground = false; + console.log('show backgrounded terminal', instance); + + const terminalTab = this._instantiationService.createInstance(TerminalTab, + this._terminalFocusContextKey, + this.configHelper, + this._terminalContainer, + instance); + this._terminalTabs.push(terminalTab); + terminalTab.addDisposable(terminalTab.onDisposed(this._onTabDisposed.fire, this._onTabDisposed)); + terminalTab.addDisposable(terminalTab.onInstancesChanged(this._onInstancesChanged.fire, this._onInstancesChanged)); + this._initInstanceListeners(instance); + if (this.terminalInstances.length === 1) { + // It's the first instance so it should be made active automatically + this.setActiveInstanceByIndex(0); + } + this._onInstancesChanged.fire(); + } + public focusFindWidget(): Promise { return this.showPanel(false).then(() => { const panel = this._panelService.getActivePanel() as TerminalPanel; diff --git a/src/vs/workbench/contrib/terminal/browser/terminalTab.ts b/src/vs/workbench/contrib/terminal/browser/terminalTab.ts index a1feac0545c7a264314c2a5facbc191a2bbb5ad9..87c5e41a396d3621caf14cef14612d5d007e46d8 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalTab.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalTab.ts @@ -225,7 +225,7 @@ export class TerminalTab extends Disposable implements ITerminalTab { terminalFocusContextKey: IContextKey, configHelper: ITerminalConfigHelper, private _container: HTMLElement, - shellLaunchConfig: IShellLaunchConfig, + shellLaunchConfigOrInstance: IShellLaunchConfig | ITerminalInstance, @ITerminalService private readonly _terminalService: ITerminalService, @IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService ) { @@ -233,12 +233,17 @@ export class TerminalTab extends Disposable implements ITerminalTab { this._onDisposed = new Emitter(); this._onInstancesChanged = new Emitter(); - const instance = this._terminalService.createInstance( - terminalFocusContextKey, - configHelper, - undefined, - shellLaunchConfig, - true); + let instance: ITerminalInstance; + if ('id' in shellLaunchConfigOrInstance) { + instance = shellLaunchConfigOrInstance; + } else { + instance = this._terminalService.createInstance( + terminalFocusContextKey, + configHelper, + undefined, + shellLaunchConfigOrInstance, + true); + } this._terminalInstances.push(instance); this._initInstanceListeners(instance); this._activeInstanceIndex = 0; diff --git a/src/vs/workbench/contrib/terminal/common/terminalService.ts b/src/vs/workbench/contrib/terminal/common/terminalService.ts index 74d076206c95ae52f957095cabcfb1ae23d14f10..de60157babed43136b68fc417248a77c2bcae585 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalService.ts @@ -30,6 +30,7 @@ export abstract class TerminalService implements ITerminalService { protected _findWidgetVisible: IContextKey; protected _terminalContainer: HTMLElement; protected _terminalTabs: ITerminalTab[] = []; + protected _backgroundedTerminalInstances: ITerminalInstance[] = []; protected get _terminalInstances(): ITerminalInstance[] { return this._terminalTabs.reduce((p, c) => p.concat(c.terminalInstances), []); } @@ -103,6 +104,7 @@ export abstract class TerminalService implements ITerminalService { protected abstract _getWslPath(path: string): Promise; protected abstract _getWindowsBuildNumber(): number; + protected abstract _showBackgroundTerminal(instance: ITerminalInstance): void; public abstract refreshActiveTab(): void; public abstract createTerminal(shell?: IShellLaunchConfig, wasNewTerminalAction?: boolean): ITerminalInstance; @@ -222,6 +224,15 @@ export abstract class TerminalService implements ITerminalService { } public getInstanceFromId(terminalId: number): ITerminalInstance { + let bgIndex = -1; + this._backgroundedTerminalInstances.forEach((terminalInstance, i) => { + if (terminalInstance.id === terminalId) { + bgIndex = i; + } + }); + if (bgIndex !== -1) { + return this._backgroundedTerminalInstances[bgIndex]; + } return this.terminalInstances[this._getIndexFromId(terminalId)]; } @@ -230,6 +241,11 @@ export abstract class TerminalService implements ITerminalService { } public setActiveInstance(terminalInstance: ITerminalInstance): void { + // If this was a runInBackground terminal created by the API this was triggered by show, + // in which case we need to create the terminal tab + if (terminalInstance.shellLaunchConfig.runInBackground) { + this._showBackgroundTerminal(terminalInstance); + } this.setActiveInstanceByIndex(this._getIndexFromId(terminalInstance.id)); }