diff --git a/src/Terminal.ts b/src/Terminal.ts index 652e04cad6..cb2b322065 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -766,7 +766,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II this._colorManager.setTheme(this._theme); this._setupRenderer(); - this._renderCoordinator = new RenderCoordinator(this.renderer, this.rows); + this._renderCoordinator = new RenderCoordinator(this.renderer, this.rows, this.screenElement); this._renderCoordinator.onRender(e => this._onRender.fire(e)); this.onResize(e => this._renderCoordinator.resize(e.cols, e.rows)); diff --git a/src/renderer/RenderCoordinator.ts b/src/renderer/RenderCoordinator.ts index d8895bc423..a843c19dcf 100644 --- a/src/renderer/RenderCoordinator.ts +++ b/src/renderer/RenderCoordinator.ts @@ -14,17 +14,20 @@ export class RenderCoordinator extends Disposable { private _renderDebouncer: RenderDebouncer; private _screenDprMonitor: ScreenDprMonitor; + private _isPaused: boolean = false; + private _needsFullRefresh: boolean = false; + private _canvasWidth: number = 0; + private _canvasHeight: number = 0; + private _onCanvasResize = new EventEmitter2<{ width: number, height: number }>(); public get onCanvasResize(): IEvent<{ width: number, height: number }> { return this._onCanvasResize.event; } private _onRender = new EventEmitter2<{ start: number, end: number }>(); public get onRender(): IEvent<{ start: number, end: number }> { return this._onRender.event; } - private _canvasWidth: number = 0; - private _canvasHeight: number = 0; - constructor( private _renderer: IRenderer, - private _rowCount: number + private _rowCount: number, + screenElement: HTMLElement ) { super(); this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end)); @@ -37,9 +40,29 @@ export class RenderCoordinator extends Disposable { // dprchange should handle this case, we need this as well for browsers that don't support the // matchMedia query. this.register(addDisposableDomListener(window, 'resize', () => this._renderer.onDevicePixelRatioChange())); + + // Detect whether IntersectionObserver is detected and enable renderer pause + // and resume based on terminal visibility if so + if ('IntersectionObserver' in window) { + const observer = new IntersectionObserver(e => this._onIntersectionChange(e[e.length - 1]), { threshold: 0 }); + observer.observe(screenElement); + this.register({ dispose: () => observer.disconnect() }); + } + } + + private _onIntersectionChange(entry: IntersectionObserverEntry): void { + this._isPaused = entry.intersectionRatio === 0; + if (!this._isPaused && this._needsFullRefresh) { + this.refreshRows(0, this._rowCount - 1); + this._needsFullRefresh = false; + } } public refreshRows(start: number, end: number): void { + if (this._isPaused) { + this._needsFullRefresh = true; + return; + } this._renderDebouncer.refresh(start, end, this._rowCount); } diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index 50b41c46fe..08586b16c0 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -16,8 +16,6 @@ import { IColorSet } from '../ui/Types'; export class Renderer extends Disposable implements IRenderer { private _renderLayers: IRenderLayer[]; private _devicePixelRatio: number; - private _isPaused: boolean = false; - private _needsFullRefresh: boolean = false; private _characterJoinerRegistry: ICharacterJoinerRegistry; public dimensions: IRenderDimensions; @@ -53,14 +51,6 @@ export class Renderer extends Disposable implements IRenderer { this._devicePixelRatio = window.devicePixelRatio; this._updateDimensions(); this.onOptionsChanged(); - - // Detect whether IntersectionObserver is detected and enable renderer pause - // and resume based on terminal visibility if so - if ('IntersectionObserver' in window) { - const observer = new IntersectionObserver(e => this.onIntersectionChange(e[e.length - 1]), { threshold: 0 }); - observer.observe(this._terminal.element); - this.register({ dispose: () => observer.disconnect() }); - } } public dispose(): void { @@ -68,14 +58,6 @@ export class Renderer extends Disposable implements IRenderer { this._renderLayers.forEach(l => l.dispose()); } - public onIntersectionChange(entry: IntersectionObserverEntry): void { - this._isPaused = entry.intersectionRatio === 0; - if (!this._isPaused && this._needsFullRefresh) { - this._terminal.refresh(0, this._terminal.rows - 1); - this._needsFullRefresh = false; - } - } - public onDevicePixelRatioChange(): void { // If the device pixel ratio changed, the char atlas needs to be regenerated // and the terminal needs to refreshed @@ -94,11 +76,7 @@ export class Renderer extends Disposable implements IRenderer { l.reset(this._terminal); }); - if (this._isPaused) { - this._needsFullRefresh = true; - } else { - this._terminal.refresh(0, this._terminal.rows - 1); - } + this._terminal.refresh(0, this._terminal.rows - 1); } public onResize(cols: number, rows: number): void { @@ -109,11 +87,7 @@ export class Renderer extends Disposable implements IRenderer { this._renderLayers.forEach(l => l.resize(this._terminal, this.dimensions)); // Force a refresh - if (this._isPaused) { - this._needsFullRefresh = true; - } else { - this._terminal.refresh(0, this._terminal.rows - 1); - } + this._terminal.refresh(0, this._terminal.rows - 1); // Resize the screen this._terminal.screenElement.style.width = `${this.dimensions.canvasWidth}px`; @@ -149,11 +123,7 @@ export class Renderer extends Disposable implements IRenderer { } private _runOperation(operation: (layer: IRenderLayer) => void): void { - if (this._isPaused) { - this._needsFullRefresh = true; - } else { - this._renderLayers.forEach(l => operation(l)); - } + this._renderLayers.forEach(l => operation(l)); } /**