mirror of
https://github.com/microsoft/vscode.git
synced 2025-12-26 13:19:42 +00:00
Wait to signal to the extHostTerminalService that the terminal is opened until the terminal has a name. (#58983)
Also added a change listener for title. Fixes #53057
This commit is contained in:
@@ -585,16 +585,6 @@ suite('window namespace tests', () => {
|
||||
});
|
||||
|
||||
suite('Terminal', () => {
|
||||
test('createTerminal, Terminal.name', () => {
|
||||
const terminal = window.createTerminal('foo');
|
||||
assert.equal(terminal.name, 'foo');
|
||||
|
||||
assert.throws(() => {
|
||||
(<any>terminal).name = 'bar';
|
||||
}, 'Terminal.name should be readonly');
|
||||
terminal.dispose();
|
||||
});
|
||||
|
||||
test('sendText immediately after createTerminal should not throw', () => {
|
||||
const terminal = window.createTerminal();
|
||||
assert.doesNotThrow(terminal.sendText.bind(terminal, 'echo "foo"'));
|
||||
@@ -708,10 +698,12 @@ suite('window namespace tests', () => {
|
||||
|
||||
test('onDidChangeActiveTerminal should fire when new terminals are created', (done) => {
|
||||
const reg1 = window.onDidChangeActiveTerminal((active: Terminal | undefined) => {
|
||||
console.log('!!!!!!!!!!!!!!!ONE');
|
||||
assert.equal(active, terminal);
|
||||
assert.equal(active, window.activeTerminal);
|
||||
reg1.dispose();
|
||||
const reg2 = window.onDidChangeActiveTerminal((active: Terminal | undefined) => {
|
||||
console.log('!!!!!!!!!!!!!!!TWO');
|
||||
assert.equal(active, undefined);
|
||||
assert.equal(active, window.activeTerminal);
|
||||
reg2.dispose();
|
||||
@@ -721,6 +713,8 @@ suite('window namespace tests', () => {
|
||||
});
|
||||
const terminal = window.createTerminal();
|
||||
terminal.show();
|
||||
console.log('!!!!!!!!!!!!!!!THREE');
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,6 +35,7 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
||||
this._toDispose.push(terminalService.onInstanceDimensionsChanged(instance => this._onInstanceDimensionsChanged(instance)));
|
||||
this._toDispose.push(terminalService.onInstanceRequestExtHostProcess(request => this._onTerminalRequestExtHostProcess(request)));
|
||||
this._toDispose.push(terminalService.onActiveInstanceChanged(instance => this._onActiveTerminalChanged(instance ? instance.id : undefined)));
|
||||
this._toDispose.push(terminalService.onInstanceTitleChanged(instance => this._onTitleChanged(instance.id, instance.title)));
|
||||
|
||||
// Set initial ext host state
|
||||
this.terminalService.terminalInstances.forEach(t => {
|
||||
@@ -163,6 +164,10 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
||||
this._proxy.$acceptTerminalProcessData(terminalId, data);
|
||||
}
|
||||
|
||||
private _onTitleChanged(terminalId: number, name: string): void {
|
||||
this._proxy.$acceptTerminalTitleChange(terminalId, name);
|
||||
}
|
||||
|
||||
private _onTerminalRendererInput(terminalId: number, data: string): void {
|
||||
this._proxy.$acceptTerminalRendererInput(terminalId, data);
|
||||
}
|
||||
@@ -172,7 +177,13 @@ export class MainThreadTerminalService implements MainThreadTerminalServiceShape
|
||||
}
|
||||
|
||||
private _onTerminalOpened(terminalInstance: ITerminalInstance): void {
|
||||
this._proxy.$acceptTerminalOpened(terminalInstance.id, terminalInstance.title);
|
||||
if (terminalInstance.title) {
|
||||
this._proxy.$acceptTerminalOpened(terminalInstance.id, terminalInstance.title);
|
||||
} else {
|
||||
terminalInstance.waitForTitle().then(title => {
|
||||
this._proxy.$acceptTerminalOpened(terminalInstance.id, title);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private _onTerminalProcessIdReady(terminalInstance: ITerminalInstance): void {
|
||||
|
||||
@@ -879,6 +879,7 @@ export interface ExtHostTerminalServiceShape {
|
||||
$acceptTerminalProcessId(id: number, processId: number): void;
|
||||
$acceptTerminalProcessData(id: number, data: string): void;
|
||||
$acceptTerminalRendererInput(id: number, data: string): void;
|
||||
$acceptTerminalTitleChange(id: number, name: string): void;
|
||||
$acceptTerminalRendererDimensions(id: number, cols: number, rows: number): void;
|
||||
$createProcess(id: number, shellLaunchConfig: ShellLaunchConfigDto, cols: number, rows: number): void;
|
||||
$acceptProcessInput(id: number, data: string): void;
|
||||
|
||||
@@ -115,6 +115,10 @@ export class ExtHostTerminal extends BaseExtHostTerminal implements vscode.Termi
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public set name(name: string) {
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
public get processId(): Thenable<number> {
|
||||
return this._pidPromise;
|
||||
}
|
||||
@@ -313,6 +317,13 @@ export class ExtHostTerminalService implements ExtHostTerminalServiceShape {
|
||||
}
|
||||
}
|
||||
|
||||
public $acceptTerminalTitleChange(id: number, name: string): void {
|
||||
const extHostTerminal = this._getTerminalObjectById(this.terminals, id);
|
||||
if (extHostTerminal) {
|
||||
extHostTerminal.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public $acceptTerminalClosed(id: number): void {
|
||||
const index = this._getTerminalObjectIndexById(this.terminals, id);
|
||||
if (index === null) {
|
||||
|
||||
@@ -189,7 +189,7 @@ export interface ITerminalService {
|
||||
onInstanceDimensionsChanged: Event<ITerminalInstance>;
|
||||
onInstanceRequestExtHostProcess: Event<ITerminalProcessExtHostRequest>;
|
||||
onInstancesChanged: Event<void>;
|
||||
onInstanceTitleChanged: Event<string>;
|
||||
onInstanceTitleChanged: Event<ITerminalInstance>;
|
||||
onActiveInstanceChanged: Event<ITerminalInstance>;
|
||||
terminalInstances: ITerminalInstance[];
|
||||
terminalTabs: ITerminalTab[];
|
||||
@@ -311,7 +311,7 @@ export interface ITerminalInstance {
|
||||
/**
|
||||
* An event that fires when the terminal instance's title changes.
|
||||
*/
|
||||
onTitleChanged: Event<string>;
|
||||
onTitleChanged: Event<ITerminalInstance>;
|
||||
|
||||
/**
|
||||
* An event that fires when the terminal instance is disposed.
|
||||
@@ -569,6 +569,8 @@ export interface ITerminalInstance {
|
||||
*/
|
||||
setTitle(title: string, eventFromProcess: boolean): void;
|
||||
|
||||
waitForTitle(): Promise<string>;
|
||||
|
||||
setDimensions(dimensions: ITerminalDimensions): void;
|
||||
|
||||
addDisposable(disposable: IDisposable): void;
|
||||
|
||||
@@ -44,8 +44,8 @@ export abstract class TerminalService implements ITerminalService {
|
||||
public get onInstanceDimensionsChanged(): Event<ITerminalInstance> { return this._onInstanceDimensionsChanged.event; }
|
||||
protected readonly _onInstancesChanged: Emitter<void> = new Emitter<void>();
|
||||
public get onInstancesChanged(): Event<void> { return this._onInstancesChanged.event; }
|
||||
protected readonly _onInstanceTitleChanged: Emitter<string> = new Emitter<string>();
|
||||
public get onInstanceTitleChanged(): Event<string> { return this._onInstanceTitleChanged.event; }
|
||||
protected readonly _onInstanceTitleChanged: Emitter<ITerminalInstance> = new Emitter<ITerminalInstance>();
|
||||
public get onInstanceTitleChanged(): Event<ITerminalInstance> { return this._onInstanceTitleChanged.event; }
|
||||
protected readonly _onActiveInstanceChanged: Emitter<ITerminalInstance> = new Emitter<ITerminalInstance>();
|
||||
public get onActiveInstanceChanged(): Event<ITerminalInstance> { return this._onActiveInstanceChanged.event; }
|
||||
protected readonly _onTabDisposed: Emitter<ITerminalTab> = new Emitter<ITerminalTab>();
|
||||
|
||||
@@ -66,6 +66,8 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
private _dimensionsOverride: ITerminalDimensions;
|
||||
private _windowsShellHelper: WindowsShellHelper;
|
||||
private _xtermReadyPromise: Promise<void>;
|
||||
private _titleReadyPromise: Promise<string>;
|
||||
private _titleReadyComplete: (title: string) => any;
|
||||
|
||||
private _disposables: lifecycle.IDisposable[];
|
||||
private _messageTitleDisposable: lifecycle.IDisposable;
|
||||
@@ -97,8 +99,8 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
public get onFocused(): Event<ITerminalInstance> { return this._onFocused.event; }
|
||||
private readonly _onProcessIdReady: Emitter<ITerminalInstance> = new Emitter<ITerminalInstance>();
|
||||
public get onProcessIdReady(): Event<ITerminalInstance> { return this._onProcessIdReady.event; }
|
||||
private readonly _onTitleChanged: Emitter<string> = new Emitter<string>();
|
||||
public get onTitleChanged(): Event<string> { return this._onTitleChanged.event; }
|
||||
private readonly _onTitleChanged: Emitter<ITerminalInstance> = new Emitter<ITerminalInstance>();
|
||||
public get onTitleChanged(): Event<ITerminalInstance> { return this._onTitleChanged.event; }
|
||||
private readonly _onData: Emitter<string> = new Emitter<string>();
|
||||
public get onData(): Event<string> { return this._onData.event; }
|
||||
private readonly _onLineData: Emitter<string> = new Emitter<string>();
|
||||
@@ -135,6 +137,11 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
this._isVisible = false;
|
||||
this._isDisposed = false;
|
||||
this._id = TerminalInstance._idCounter++;
|
||||
|
||||
this._titleReadyPromise = new Promise<string>(c => {
|
||||
this._titleReadyComplete = c;
|
||||
});
|
||||
|
||||
this._terminalHasTextContextKey = KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED.bindTo(this._contextKeyService);
|
||||
this.disableLayout = false;
|
||||
|
||||
@@ -1031,12 +1038,20 @@ export class TerminalInstance implements ITerminalInstance {
|
||||
}
|
||||
}
|
||||
const didTitleChange = title !== this._title;
|
||||
const oldTitle = this._title;
|
||||
this._title = title;
|
||||
if (didTitleChange) {
|
||||
this._onTitleChanged.fire(title);
|
||||
if (!oldTitle) {
|
||||
this._titleReadyComplete(title);
|
||||
}
|
||||
this._onTitleChanged.fire(this);
|
||||
}
|
||||
}
|
||||
|
||||
public waitForTitle(): Promise<string> {
|
||||
return this._titleReadyPromise;
|
||||
}
|
||||
|
||||
public setDimensions(dimensions: ITerminalDimensions): void {
|
||||
this._dimensionsOverride = dimensions;
|
||||
this._resize();
|
||||
|
||||
Reference in New Issue
Block a user