diff --git a/src/Terminal.ts b/src/Terminal.ts index 3a2a1eb36b..852d424d28 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -1469,6 +1469,10 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp this._charSizeService.measure(); } + // Sync the scroll area to make sure scroll events don't fire and scroll the viewport to an + // invalid location + this.viewport.syncScrollArea(true); + this.refresh(0, this.rows - 1); this._onResize.fire({ cols: x, rows: y }); } diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index 894beb36c7..692d6b0346 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -35,7 +35,7 @@ export interface IPartialColorSet { export interface IViewport extends IDisposable { scrollBarWidth: number; - syncScrollArea(): void; + syncScrollArea(immediate?: boolean): void; getLinesScrolled(ev: WheelEvent): number; onWheel(ev: WheelEvent): boolean; onTouchStart(ev: TouchEvent): void; diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index d200ef8c86..4817ab3b6e 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -61,7 +61,14 @@ export class Viewport extends Disposable implements IViewport { * Refreshes row height, setting line-height, viewport height and scroll area height if * necessary. */ - private _refresh(): void { + private _refresh(immediate: boolean): void { + if (immediate) { + this._innerRefresh(); + if (this._refreshAnimationFrame !== null) { + cancelAnimationFrame(this._refreshAnimationFrame); + } + return; + } if (this._refreshAnimationFrame === null) { this._refreshAnimationFrame = requestAnimationFrame(() => this._innerRefresh()); } @@ -89,40 +96,39 @@ export class Viewport extends Disposable implements IViewport { this._refreshAnimationFrame = null; } - /** * Updates dimensions and synchronizes the scroll area if necessary. */ - public syncScrollArea(): void { + public syncScrollArea(immediate: boolean = false): void { // If buffer height changed if (this._lastRecordedBufferLength !== this._bufferService.buffer.lines.length) { this._lastRecordedBufferLength = this._bufferService.buffer.lines.length; - this._refresh(); + this._refresh(immediate); return; } // If viewport height changed if (this._lastRecordedViewportHeight !== this._renderService.dimensions.canvasHeight) { - this._refresh(); + this._refresh(immediate); return; } // If the buffer position doesn't match last scroll top const newScrollTop = this._bufferService.buffer.ydisp * this._currentRowHeight; if (this._lastScrollTop !== newScrollTop) { - this._refresh(); + this._refresh(immediate); return; } // If element's scroll top changed, this can happen when hiding the element if (this._lastScrollTop !== this._viewportElement.scrollTop) { - this._refresh(); + this._refresh(immediate); return; } // If row height changed if (this._renderService.dimensions.scaledCellHeight / window.devicePixelRatio !== this._currentRowHeight) { - this._refresh(); + this._refresh(immediate); return; } } diff --git a/src/common/buffer/Buffer.ts b/src/common/buffer/Buffer.ts index 1b3e5d8617..152bab7a3c 100644 --- a/src/common/buffer/Buffer.ts +++ b/src/common/buffer/Buffer.ts @@ -167,19 +167,25 @@ export class Buffer implements IBuffer { if (this._rows < newRows) { for (let y = this._rows; y < newRows; y++) { if (this.lines.length < newRows + this.ybase) { - if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) { - // There is room above the buffer and there are no empty elements below the line, - // scroll up - this.ybase--; - addToY++; - if (this.ydisp > 0) { - // Viewport is at the top of the buffer, must increase downwards - this.ydisp--; - } - } else { - // Add a blank line if there is no buffer left at the top to scroll to, or if there - // are blank lines after the cursor + if (this._optionsService.options.windowsMode) { + // Just add the new missing rows on Windows as conpty reprints the screen with it's + // view of the world. Once a line enters scrollback for conpty it remains there this.lines.push(new BufferLine(newCols, nullCell)); + } else { + if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) { + // There is room above the buffer and there are no empty elements below the line, + // scroll up + this.ybase--; + addToY++; + if (this.ydisp > 0) { + // Viewport is at the top of the buffer, must increase downwards + this.ydisp--; + } + } else { + // Add a blank line if there is no buffer left at the top to scroll to, or if there + // are blank lines after the cursor + this.lines.push(new BufferLine(newCols, nullCell)); + } } } }