Skip to content

Commit

Permalink
set focus to terminal that the attached task is running from
Browse files Browse the repository at this point in the history
- 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 <lhuang4@ualberta.ca>
  • Loading branch information
elaihau committed Apr 1, 2020
1 parent 9391adb commit 98216b5
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 19 deletions.
51 changes: 32 additions & 19 deletions packages/task/src/browser/task-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { EditorManager } from '@theia/editor/lib/browser';
import { ProblemManager } from '@theia/markers/lib/browser/problem/problem-manager';
import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service';
import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
import { TerminalWidgetFactoryOptions, TERMINAL_WIDGET_FACTORY_ID } from '@theia/terminal/lib/browser/terminal-widget-impl';
import { TerminalWidgetFactoryOptions } from '@theia/terminal/lib/browser/terminal-widget-impl';
import { VariableResolverService } from '@theia/variable-resolver/lib/browser';
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
import { inject, injectable, named, postConstruct } from 'inversify';
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -700,12 +700,15 @@ export class TaskService implements TaskConfigurationClient {
const taskName = this.taskNameResolver.resolve(task);
const terminalId = matchedRunningTaskInfo.terminalId;
if (terminalId) {
const terminal = this.terminalService.getById(this.getTerminalWidgetId(terminalId));
if (terminal && task.presentation) {
if (task.presentation.focus) { // assign focus to the terminal if presentation.focus is true
this.terminalService.open(terminal, { mode: 'activate' });
} else if (task.presentation.reveal === RevealKind.Always) { // show the terminal but not assign focus
this.terminalService.open(terminal, { mode: 'reveal' });
const widgetId = this.getTerminalWidgetId(terminalId);
if (widgetId) {
const terminal = this.terminalService.getById(widgetId);
if (terminal && task.presentation) {
if (task.presentation.focus) { // assign focus to the terminal if presentation.focus is true
this.terminalService.open(terminal, { mode: 'activate' });
} else if (task.presentation.reveal === RevealKind.Always) { // show the terminal but not assign focus
this.terminalService.open(terminal, { mode: 'reveal' });
}
}
}
}
Expand Down Expand Up @@ -979,17 +982,24 @@ export class TaskService implements TaskConfigurationClient {
terminal.sendText(selectedText);
}

async attach(processId: number, taskId: number): Promise<void> {
async attach(terminalId: number, taskId: number): Promise<void> {
// 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';
}
}
}

Expand All @@ -998,7 +1008,7 @@ export class TaskService implements TaskConfigurationClient {
<TaskTerminalWidgetOpenerOptions>{
created: new Date().toString(),
taskId,
id: this.getTerminalWidgetId(processId),
id: this.getTerminalWidgetId(terminalId),
title: taskInfo
? `Task: ${taskInfo.config.label}`
: `Task: #${taskId}`,
Expand All @@ -1008,11 +1018,14 @@ export class TaskService implements TaskConfigurationClient {
taskConfig: taskInfo ? taskInfo.config : undefined
}
);
widget.start(processId);
widget.start(terminalId);
}

private getTerminalWidgetId(terminalId: number): string {
return `${TERMINAL_WIDGET_FACTORY_ID}-${terminalId}`;
protected getTerminalWidgetId(terminalId: number): string | undefined {
const terminalWidget = this.terminalService.getByTerminalId(terminalId);
if (terminalWidget) {
return terminalWidget.id;
}
}

async configure(task: TaskConfiguration): Promise<void> {
Expand Down
6 changes: 6 additions & 0 deletions packages/terminal/src/browser/base/terminal-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<string> {
return this.shellTerminalServer.getDefaultShell();
}
Expand Down

0 comments on commit 98216b5

Please sign in to comment.