clear terminal layout info on window close (#117496)
* fix #117372 * fix #117583 * restore any valid terminals
This commit is contained in:
parent
8de95c02db
commit
d83895acf7
6 changed files with 50 additions and 28 deletions
|
@ -95,8 +95,12 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
}
|
||||
|
||||
async attachToProcess(id: number): Promise<void> {
|
||||
this._throwIfNoPty(id).attach();
|
||||
this._logService.trace(`Persistent terminal "${id}": Attach`);
|
||||
try {
|
||||
this._throwIfNoPty(id);
|
||||
this._logService.trace(`Persistent terminal reconnection "${id}"`);
|
||||
} catch (e) {
|
||||
this._logService.trace(`Persistent terminal reconnection "${id}" failed`, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
async detachFromProcess(id: number): Promise<void> {
|
||||
|
@ -136,16 +140,13 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
}
|
||||
|
||||
async getTerminalLayoutInfo(args: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined> {
|
||||
if (args) {
|
||||
const layout = this._workspaceLayoutInfos.get(args.workspaceId);
|
||||
if (layout) {
|
||||
const expandedTabs = await Promise.all(layout.tabs.map(async tab => this._expandTerminalTab(tab)));
|
||||
const filtered = expandedTabs.filter(t => t.terminals.length > 0);
|
||||
return {
|
||||
tabs: filtered
|
||||
};
|
||||
}
|
||||
|
||||
const layout = this._workspaceLayoutInfos.get(args.workspaceId);
|
||||
if (layout) {
|
||||
const expandedTabs = await Promise.all(layout.tabs.map(async tab => this._expandTerminalTab(tab)));
|
||||
const filtered = expandedTabs.filter(t => t.terminals.length > 0);
|
||||
return {
|
||||
tabs: filtered
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
@ -161,12 +162,21 @@ export class PtyService extends Disposable implements IPtyService {
|
|||
}
|
||||
|
||||
private async _expandTerminalInstance(t: ITerminalInstanceLayoutInfoById): Promise<IRawTerminalInstanceLayoutInfo<IPtyHostDescriptionDto | null>> {
|
||||
const persistentTerminalProcess = this._throwIfNoPty(t.terminal);
|
||||
const termDto = persistentTerminalProcess && await this._terminalToDto(t.terminal, persistentTerminalProcess);
|
||||
return {
|
||||
terminal: termDto ?? null,
|
||||
relativeSize: t.relativeSize
|
||||
};
|
||||
try {
|
||||
const persistentTerminalProcess = this._throwIfNoPty(t.terminal);
|
||||
const termDto = persistentTerminalProcess && await this._terminalToDto(t.terminal, persistentTerminalProcess);
|
||||
return {
|
||||
terminal: termDto ?? null,
|
||||
relativeSize: t.relativeSize
|
||||
};
|
||||
} catch (e) {
|
||||
this._logService.trace(`Couldn't get layout info, a terminal was probably disconnected`, e.message);
|
||||
// this will be filtered out and not reconnected
|
||||
return {
|
||||
terminal: null,
|
||||
relativeSize: t.relativeSize
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private async _terminalToDto(id: number, persistentTerminalProcess: PersistentTerminalProcess): Promise<IPtyHostDescriptionDto> {
|
||||
|
|
|
@ -46,10 +46,10 @@ export interface ITerminalInstanceService {
|
|||
getXtermWebglConstructor(): Promise<typeof XTermWebglAddon>;
|
||||
createWindowsShellHelper(shellProcessId: number, xterm: XTermTerminal): IWindowsShellHelper;
|
||||
createTerminalProcess(shellLaunchConfig: IShellLaunchConfig, cwd: string, cols: number, rows: number, env: IProcessEnvironment, windowsEnableConpty: boolean, shouldPersist: boolean): Promise<ITerminalChildProcess>;
|
||||
attachToProcess(id: number): Promise<ITerminalChildProcess>;
|
||||
attachToProcess(id: number): Promise<ITerminalChildProcess | undefined>;
|
||||
getDefaultShellAndArgs(useAutomationShell: boolean, platformOverride?: Platform): Promise<{ shell: string, args: string[] | string | undefined }>;
|
||||
getMainProcessParentEnv(): Promise<IProcessEnvironment>;
|
||||
setTerminalLayoutInfo(args: ISetTerminalLayoutInfoArgs): void;
|
||||
setTerminalLayoutInfo(args?: ISetTerminalLayoutInfoArgs): void;
|
||||
setTerminalLayoutInfo(layout: ITerminalsLayoutInfoById): void;
|
||||
getTerminalLayoutInfo(): Promise<ITerminalsLayoutInfo | undefined>;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst
|
|||
getWorkspaceId(): string {
|
||||
return '';
|
||||
}
|
||||
setTerminalLayoutInfo(layout: ITerminalsLayoutInfoById, id?: string): Promise<void> {
|
||||
setTerminalLayoutInfo(layout?: ITerminalsLayoutInfoById, id?: string): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getTerminalLayoutInfo(args?: IGetTerminalLayoutInfoArgs): Promise<ITerminalsLayoutInfo | undefined> {
|
||||
|
|
|
@ -195,7 +195,13 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
|||
// Flow control is not needed for ptys hosted in the same process (ie. the electron
|
||||
// renderer).
|
||||
if (shellLaunchConfig.attachPersistentTerminal) {
|
||||
this._process = await this._terminalInstanceService.attachToProcess(shellLaunchConfig.attachPersistentTerminal.id);
|
||||
const result = await this._terminalInstanceService.attachToProcess(shellLaunchConfig.attachPersistentTerminal.id);
|
||||
if (result) {
|
||||
this._process = result;
|
||||
} else {
|
||||
this._logService.trace(`Attach to process failed for terminal ${shellLaunchConfig.attachPersistentTerminal}`);
|
||||
return undefined;
|
||||
}
|
||||
} else {
|
||||
this._process = await this._launchLocalProcess(shellLaunchConfig, cols, rows, this.userHome, isScreenReaderModeEnabled);
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ export class TerminalService implements ITerminalService {
|
|||
private async _reconnectToLocalTerminals(): Promise<void> {
|
||||
// Reattach to all local terminals
|
||||
const layoutInfo = await this._terminalInstanceService.getTerminalLayoutInfo();
|
||||
if (layoutInfo) {
|
||||
if (layoutInfo && layoutInfo.tabs.length > 0) {
|
||||
this._recreateTerminalTabs(layoutInfo);
|
||||
// now that terminals have been restored,
|
||||
// attach listeners to update local state when terminals are changed
|
||||
|
@ -335,6 +335,7 @@ export class TerminalService implements ITerminalService {
|
|||
|
||||
// Force dispose of all terminal instances
|
||||
this.terminalInstances.forEach(instance => instance.dispose(true));
|
||||
this._terminalInstanceService.setTerminalLayoutInfo(undefined);
|
||||
}
|
||||
|
||||
public getTabLabels(): string[] {
|
||||
|
|
|
@ -117,9 +117,14 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst
|
|||
return this._instantiationService.createInstance(LocalPty, id, shouldPersist);
|
||||
}
|
||||
|
||||
public async attachToProcess(id: number): Promise<ITerminalChildProcess> {
|
||||
await this._localPtyService.attachToProcess(id);
|
||||
return this._instantiationService.createInstance(LocalPty, id, true);
|
||||
public async attachToProcess(id: number): Promise<ITerminalChildProcess | undefined> {
|
||||
try {
|
||||
await this._localPtyService.attachToProcess(id);
|
||||
return this._instantiationService.createInstance(LocalPty, id, true);
|
||||
} catch (e) {
|
||||
this._logService.trace(`Couldn't attach to process ${e.message}`);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private _isWorkspaceShellAllowed(): boolean {
|
||||
|
@ -157,10 +162,10 @@ export class TerminalInstanceService extends Disposable implements ITerminalInst
|
|||
return getMainProcessParentEnv();
|
||||
}
|
||||
|
||||
public setTerminalLayoutInfo(layoutInfo: ITerminalsLayoutInfoById): void {
|
||||
public setTerminalLayoutInfo(layoutInfo?: ITerminalsLayoutInfoById): void {
|
||||
const args: ISetTerminalLayoutInfoArgs = {
|
||||
workspaceId: this._getWorkspaceId(),
|
||||
tabs: layoutInfo.tabs
|
||||
tabs: layoutInfo ? layoutInfo.tabs : []
|
||||
};
|
||||
this._localPtyService.setTerminalLayoutInfo(args);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue