From 91bac85a5b4707f1ddd728a8fb245eb9121c06f5 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Mon, 14 Sep 2020 10:33:55 -0700 Subject: [PATCH] Defer all resize events for git bash terminals This is a temporary workaround for #106668 before the proper fix #106672 can be done. Fixes #106668 --- .../contrib/terminal/node/terminalProcess.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts index f3a9e3da81c..7323c2e846c 100644 --- a/src/vs/workbench/contrib/terminal/node/terminalProcess.ts +++ b/src/vs/workbench/contrib/terminal/node/terminalProcess.ts @@ -36,6 +36,7 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess private _titleInterval: NodeJS.Timer | null = null; private _writeQueue: string[] = []; private _writeTimeout: NodeJS.Timeout | undefined; + private _delayedResizer: DelayedResizer | undefined; private readonly _initialCwd: string; private readonly _ptyOptions: pty.IPtyForkOptions | pty.IWindowsPtyForkOptions; @@ -80,6 +81,17 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess // This option will force conpty to not redraw the whole viewport on launch conptyInheritCursor: useConpty && !!_shellLaunchConfig.initialText }; + // Delay resizes to avoid conpty not respecting very early resize calls + if (platform.isWindows && useConpty && cols === 0 && rows === 0 && this._shellLaunchConfig.executable?.endsWith('Git\\bin\\bash.exe')) { + this._delayedResizer = new DelayedResizer(); + this._register(this._delayedResizer.onTrigger(dimensions => { + this._delayedResizer?.dispose(); + this._delayedResizer = undefined; + if (dimensions.cols && dimensions.rows) { + this.resize(dimensions.cols, dimensions.rows); + } + })); + } } public async start(): Promise { @@ -286,6 +298,14 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess if (this._ptyProcess) { cols = Math.max(cols, 1); rows = Math.max(rows, 1); + + // Delay resize if needed + if (this._delayedResizer) { + this._delayedResizer.cols = cols; + this._delayedResizer.rows = rows; + return; + } + this._logService.trace('IPty#resize', cols, rows); try { this._ptyProcess.resize(cols, rows); @@ -344,3 +364,32 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess return Promise.resolve(0); } } + +/** + * Tracks the latest resize event to be trigger at a later point. + */ +class DelayedResizer extends Disposable { + public rows: number | undefined; + public cols: number | undefined; + private _timeout: NodeJS.Timeout; + + private readonly _onTrigger = this._register(new Emitter<{ rows?: number, cols?: number }>()); + public get onTrigger(): Event<{ rows?: number, cols?: number }> { return this._onTrigger.event; } + + constructor() { + super(); + this._timeout = setTimeout(() => { + this._onTrigger.fire({ rows: this.rows, cols: this.cols }); + }, 1000); + this._register({ + dispose: () => { + clearTimeout(this._timeout); + } + }); + } + + dispose(): void { + super.dispose(); + clearTimeout(this._timeout); + } +} -- GitLab