From 74f973872765db430d27a7821c8342e1fe4e3db8 Mon Sep 17 00:00:00 2001 From: Liang Huang Date: Mon, 30 Mar 2020 15:08:20 -0400 Subject: [PATCH] set focus to terminal that the attached task is running from - Same task can be attached over and over again, producing multiple terminal widgets. With this change, Theia sets focus to the teminal widget that the to-be-attached task is running from. If such terminal widget is not found, Theia creates a new terminal widget for the attached task. - fixes #7407 Signed-off-by: Liang Huang --- packages/task/src/browser/task-service.ts | 31 +++++++++++++------ .../src/browser/base/terminal-service.ts | 6 ++++ .../browser/terminal-frontend-contribution.ts | 4 +++ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/packages/task/src/browser/task-service.ts b/packages/task/src/browser/task-service.ts index 5cca84ec7f6ec..fbc5939f18aec 100644 --- a/packages/task/src/browser/task-service.ts +++ b/packages/task/src/browser/task-service.ts @@ -228,7 +228,7 @@ export class TaskService implements TaskConfigurationClient { if (isTaskActiveAndOutputSilent && problem.marker.severity === DiagnosticSeverity.Error) { const terminalId = matchedRunningTaskInfo!.terminalId; if (terminalId) { - const terminal = this.terminalService.getById(this.getTerminalWidgetId(terminalId)); + const terminal = this.terminalService.getByTerminalId(terminalId); if (terminal) { const focus = !!matchedRunningTaskInfo!.config.presentation!.focus; if (focus) { // assign focus to the terminal if presentation.focus is true @@ -304,7 +304,7 @@ export class TaskService implements TaskConfigurationClient { } else { const eventTaskConfig = event.config; if (eventTaskConfig && eventTaskConfig.presentation && eventTaskConfig.presentation.reveal === RevealKind.Silent && event.terminalId) { - const terminal = this.terminalService.getById(this.getTerminalWidgetId(event.terminalId)); + const terminal = this.terminalService.getByTerminalId(event.terminalId); const focus = !!eventTaskConfig.presentation.focus; if (terminal) { if (focus) { // assign focus to the terminal if presentation.focus is true @@ -979,17 +979,24 @@ export class TaskService implements TaskConfigurationClient { terminal.sendText(selectedText); } - async attach(processId: number, taskId: number): Promise { + async attach(terminalId: number, taskId: number): Promise { // Get the list of all available running tasks. const runningTasks: TaskInfo[] = await this.getRunningTasks(); // Get the corresponding task information based on task id if available. const taskInfo: TaskInfo | undefined = runningTasks.find((t: TaskInfo) => t.taskId === taskId); let widgetOpenMode: WidgetOpenMode = 'open'; - if (taskInfo && taskInfo.config.presentation && taskInfo.config.presentation.reveal === RevealKind.Always) { - if (taskInfo.config.presentation.focus) { // assign focus to the terminal if presentation.focus is true - widgetOpenMode = 'activate'; - } else { // show the terminal but not assign focus - widgetOpenMode = 'reveal'; + if (taskInfo) { + const terminalWidget = this.terminalService.getByTerminalId(terminalId); + if (terminalWidget) { + this.messageService.error('Task is already running in terminal'); + return this.terminalService.open(terminalWidget, { mode: 'activate' }); + } + if (taskInfo.config.presentation && taskInfo.config.presentation.reveal === RevealKind.Always) { + if (taskInfo.config.presentation.focus) { // assign focus to the terminal if presentation.focus is true + widgetOpenMode = 'activate'; + } else { // show the terminal but not assign focus + widgetOpenMode = 'reveal'; + } } } @@ -998,7 +1005,7 @@ export class TaskService implements TaskConfigurationClient { { created: new Date().toString(), taskId, - id: this.getTerminalWidgetId(processId), + id: this.getTerminalWidgetId(terminalId), title: taskInfo ? `Task: ${taskInfo.config.label}` : `Task: #${taskId}`, @@ -1008,10 +1015,14 @@ export class TaskService implements TaskConfigurationClient { taskConfig: taskInfo ? taskInfo.config : undefined } ); - widget.start(processId); + widget.start(terminalId); } private getTerminalWidgetId(terminalId: number): string { + const terminalWidget = this.terminalService.getByTerminalId(terminalId); + if (terminalWidget) { + return terminalWidget.id; + } return `${TERMINAL_WIDGET_FACTORY_ID}-${terminalId}`; } diff --git a/packages/terminal/src/browser/base/terminal-service.ts b/packages/terminal/src/browser/base/terminal-service.ts index a3ce7453b9a1f..0570cf80b74c5 100644 --- a/packages/terminal/src/browser/base/terminal-service.ts +++ b/packages/terminal/src/browser/base/terminal-service.ts @@ -46,6 +46,12 @@ export interface TerminalService { */ getById(id: string): TerminalWidget | undefined; + /** + * @param id - the terminal id (NOT the terminal widget id!) + * @return the widget + */ + getByTerminalId(terminalId: number): TerminalWidget | undefined; + /** * Returns detected default shell. */ diff --git a/packages/terminal/src/browser/terminal-frontend-contribution.ts b/packages/terminal/src/browser/terminal-frontend-contribution.ts index b7150a3fb3b7b..739e037fadb3f 100644 --- a/packages/terminal/src/browser/terminal-frontend-contribution.ts +++ b/packages/terminal/src/browser/terminal-frontend-contribution.ts @@ -257,6 +257,10 @@ export class TerminalFrontendContribution implements TerminalService, CommandCon return this.all.find(terminal => terminal.id === id); } + getByTerminalId(terminalId: number): TerminalWidget | undefined { + return this.all.find(terminal => terminal.terminalId === terminalId); + } + getDefaultShell(): Promise { return this.shellTerminalServer.getDefaultShell(); }