From 58dbc983615f358d69ae44ae0f031de2129c262c Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 14 Jul 2019 09:26:09 -0700 Subject: [PATCH 01/56] Move BaseCharAtlas to browser --- src/{ => browser}/renderer/atlas/BaseCharAtlas.ts | 4 ++-- src/browser/renderer/atlas/Types.d.ts | 14 ++++++++++++++ src/renderer/BaseRenderLayer.ts | 4 ++-- src/renderer/atlas/CharAtlasCache.ts | 2 +- src/renderer/atlas/DynamicCharAtlas.ts | 5 +++-- src/renderer/atlas/Types.d.ts | 10 ---------- 6 files changed, 22 insertions(+), 17 deletions(-) rename src/{ => browser}/renderer/atlas/BaseCharAtlas.ts (93%) create mode 100644 src/browser/renderer/atlas/Types.d.ts diff --git a/src/renderer/atlas/BaseCharAtlas.ts b/src/browser/renderer/atlas/BaseCharAtlas.ts similarity index 93% rename from src/renderer/atlas/BaseCharAtlas.ts rename to src/browser/renderer/atlas/BaseCharAtlas.ts index 470736f1..dc114601 100644 --- a/src/renderer/atlas/BaseCharAtlas.ts +++ b/src/browser/renderer/atlas/BaseCharAtlas.ts @@ -3,8 +3,8 @@ * @license MIT */ -import { IGlyphIdentifier } from './Types'; -import { IDisposable } from 'xterm'; +import { IGlyphIdentifier } from 'browser/renderer/atlas/Types'; +import { IDisposable } from 'common/Types'; export abstract class BaseCharAtlas implements IDisposable { private _didWarmUp: boolean = false; diff --git a/src/browser/renderer/atlas/Types.d.ts b/src/browser/renderer/atlas/Types.d.ts new file mode 100644 index 00000000..fd5b596c --- /dev/null +++ b/src/browser/renderer/atlas/Types.d.ts @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2017 The xterm.js authors. All rights reserved. + * @license MIT + */ + +export interface IGlyphIdentifier { + chars: string; + code: number; + bg: number; + fg: number; + bold: boolean; + dim: boolean; + italic: boolean; +} diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index 767ef08c..e704375c 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -8,9 +8,9 @@ import { IRenderDimensions } from 'browser/renderer/Types'; import { ITerminal } from '../Types'; import { ICellData } from 'common/Types'; import { DEFAULT_COLOR, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from 'common/buffer/Constants'; -import { IGlyphIdentifier } from './atlas/Types'; +import { IGlyphIdentifier } from 'browser/renderer/atlas/Types'; import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; -import { BaseCharAtlas } from './atlas/BaseCharAtlas'; +import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; import { acquireCharAtlas } from './atlas/CharAtlasCache'; import { AttributeData } from 'common/buffer/AttributeData'; import { IColorSet } from 'browser/Types'; diff --git a/src/renderer/atlas/CharAtlasCache.ts b/src/renderer/atlas/CharAtlasCache.ts index 43b5eb83..f9bd68a1 100644 --- a/src/renderer/atlas/CharAtlasCache.ts +++ b/src/renderer/atlas/CharAtlasCache.ts @@ -5,7 +5,7 @@ import { ITerminal } from '../../Types'; import { generateConfig, configEquals } from './CharAtlasUtils'; -import { BaseCharAtlas } from './BaseCharAtlas'; +import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; import { DynamicCharAtlas } from './DynamicCharAtlas'; import { ICharAtlasConfig } from './Types'; import { IColorSet } from 'browser/Types'; diff --git a/src/renderer/atlas/DynamicCharAtlas.ts b/src/renderer/atlas/DynamicCharAtlas.ts index 6e669d91..9af79e01 100644 --- a/src/renderer/atlas/DynamicCharAtlas.ts +++ b/src/renderer/atlas/DynamicCharAtlas.ts @@ -3,9 +3,10 @@ * @license MIT */ -import { IGlyphIdentifier, ICharAtlasConfig } from './Types'; +import { ICharAtlasConfig } from './Types'; import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; -import { BaseCharAtlas } from './BaseCharAtlas'; +import { IGlyphIdentifier } from 'browser/renderer/atlas/Types'; +import { BaseCharAtlas } from '../../browser/renderer/atlas/BaseCharAtlas'; import { DEFAULT_ANSI_COLORS } from 'browser/ColorManager'; import { LRUMap } from 'browser/renderer/atlas/LRUMap'; import { isFirefox, isSafari } from 'common/Platform'; diff --git a/src/renderer/atlas/Types.d.ts b/src/renderer/atlas/Types.d.ts index 1de843e0..f717381c 100644 --- a/src/renderer/atlas/Types.d.ts +++ b/src/renderer/atlas/Types.d.ts @@ -6,16 +6,6 @@ import { FontWeight } from 'xterm'; import { IColorSet } from 'browser/Types'; -export interface IGlyphIdentifier { - chars: string; - code: number; - bg: number; - fg: number; - bold: boolean; - dim: boolean; - italic: boolean; -} - export interface ICharAtlasConfig { devicePixelRatio: number; fontSize: number; From c0253c10935cd0329f3f02cda07fa55fd0b004c2 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 14 Jul 2019 09:31:04 -0700 Subject: [PATCH 02/56] Move DynamicCharAtlas to browser --- .../renderer/atlas/DynamicCharAtlas.ts | 20 ++++++++++++------- src/browser/renderer/atlas/Types.d.ts | 15 ++++++++++++++ src/renderer/atlas/CharAtlasCache.ts | 4 ++-- src/renderer/atlas/CharAtlasUtils.ts | 2 +- src/renderer/atlas/Types.d.ts | 19 ------------------ 5 files changed, 31 insertions(+), 29 deletions(-) rename src/{ => browser}/renderer/atlas/DynamicCharAtlas.ts (95%) delete mode 100644 src/renderer/atlas/Types.d.ts diff --git a/src/renderer/atlas/DynamicCharAtlas.ts b/src/browser/renderer/atlas/DynamicCharAtlas.ts similarity index 95% rename from src/renderer/atlas/DynamicCharAtlas.ts rename to src/browser/renderer/atlas/DynamicCharAtlas.ts index 9af79e01..d591c173 100644 --- a/src/renderer/atlas/DynamicCharAtlas.ts +++ b/src/browser/renderer/atlas/DynamicCharAtlas.ts @@ -3,10 +3,9 @@ * @license MIT */ -import { ICharAtlasConfig } from './Types'; import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; -import { IGlyphIdentifier } from 'browser/renderer/atlas/Types'; -import { BaseCharAtlas } from '../../browser/renderer/atlas/BaseCharAtlas'; +import { IGlyphIdentifier, ICharAtlasConfig } from 'browser/renderer/atlas/Types'; +import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; import { DEFAULT_ANSI_COLORS } from 'browser/ColorManager'; import { LRUMap } from 'browser/renderer/atlas/LRUMap'; import { isFirefox, isSafari } from 'common/Platform'; @@ -90,12 +89,12 @@ export class DynamicCharAtlas extends BaseCharAtlas { // The canvas needs alpha because we use clearColor to convert the background color to alpha. // It might also contain some characters with transparent backgrounds if allowTransparency is // set. - this._cacheCtx = this._cacheCanvas.getContext('2d', {alpha: true}); + this._cacheCtx = throwIfFalsy(this._cacheCanvas.getContext('2d', {alpha: true})); const tmpCanvas = document.createElement('canvas'); tmpCanvas.width = this._config.scaledCharWidth; tmpCanvas.height = this._config.scaledCharHeight; - this._tmpCtx = tmpCanvas.getContext('2d', {alpha: this._config.allowTransparency}); + this._tmpCtx = throwIfFalsy(tmpCanvas.getContext('2d', {alpha: this._config.allowTransparency})); this._width = Math.floor(TEXTURE_WIDTH / this._config.scaledCharWidth); this._height = Math.floor(TEXTURE_HEIGHT / this._config.scaledCharHeight); @@ -145,7 +144,7 @@ export class DynamicCharAtlas extends BaseCharAtlas { index = this._cacheMap.size; } else { // we're out of space, so our call to set will delete this item - index = this._cacheMap.peek().index; + index = this._cacheMap.peek()!.index; } const cacheValue = this._drawToCache(glyph, index); this._cacheMap.set(glyphKey, cacheValue); @@ -187,7 +186,7 @@ export class DynamicCharAtlas extends BaseCharAtlas { const cacheX = this._toCoordinateX(cacheValue.index); const cacheY = this._toCoordinateY(cacheValue.index); ctx.drawImage( - cacheValue.inBitmap ? this._bitmap : this._cacheCanvas, + cacheValue.inBitmap ? this._bitmap! : this._cacheCanvas, cacheX, cacheY, this._config.scaledCharWidth, @@ -367,3 +366,10 @@ function clearColor(imageData: ImageData, color: IColor): boolean { } return isEmpty; } + +export function throwIfFalsy(value: T | undefined | null): T { + if (!value) { + throw new Error('value must not be falsy'); + } + return value; +} diff --git a/src/browser/renderer/atlas/Types.d.ts b/src/browser/renderer/atlas/Types.d.ts index fd5b596c..0724b163 100644 --- a/src/browser/renderer/atlas/Types.d.ts +++ b/src/browser/renderer/atlas/Types.d.ts @@ -3,6 +3,9 @@ * @license MIT */ +import { FontWeight } from 'common/services/Services'; +import { IColorSet } from 'browser/Types'; + export interface IGlyphIdentifier { chars: string; code: number; @@ -12,3 +15,15 @@ export interface IGlyphIdentifier { dim: boolean; italic: boolean; } + +export interface ICharAtlasConfig { + devicePixelRatio: number; + fontSize: number; + fontFamily: string; + fontWeight: FontWeight; + fontWeightBold: FontWeight; + scaledCharWidth: number; + scaledCharHeight: number; + allowTransparency: boolean; + colors: IColorSet; +} diff --git a/src/renderer/atlas/CharAtlasCache.ts b/src/renderer/atlas/CharAtlasCache.ts index f9bd68a1..ec66b67a 100644 --- a/src/renderer/atlas/CharAtlasCache.ts +++ b/src/renderer/atlas/CharAtlasCache.ts @@ -6,8 +6,8 @@ import { ITerminal } from '../../Types'; import { generateConfig, configEquals } from './CharAtlasUtils'; import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; -import { DynamicCharAtlas } from './DynamicCharAtlas'; -import { ICharAtlasConfig } from './Types'; +import { DynamicCharAtlas } from '../../browser/renderer/atlas/DynamicCharAtlas'; +import { ICharAtlasConfig } from 'browser/renderer/atlas/Types'; import { IColorSet } from 'browser/Types'; interface ICharAtlasCacheEntry { diff --git a/src/renderer/atlas/CharAtlasUtils.ts b/src/renderer/atlas/CharAtlasUtils.ts index ee787a7b..da067f52 100644 --- a/src/renderer/atlas/CharAtlasUtils.ts +++ b/src/renderer/atlas/CharAtlasUtils.ts @@ -4,7 +4,7 @@ */ import { ITerminal } from '../../Types'; -import { ICharAtlasConfig } from './Types'; +import { ICharAtlasConfig } from 'browser/renderer/atlas/Types'; import { DEFAULT_COLOR } from 'common/buffer/Constants'; import { IColorSet } from 'browser/Types'; diff --git a/src/renderer/atlas/Types.d.ts b/src/renderer/atlas/Types.d.ts deleted file mode 100644 index f717381c..00000000 --- a/src/renderer/atlas/Types.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2017 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { FontWeight } from 'xterm'; -import { IColorSet } from 'browser/Types'; - -export interface ICharAtlasConfig { - devicePixelRatio: number; - fontSize: number; - fontFamily: string; - fontWeight: FontWeight; - fontWeightBold: FontWeight; - scaledCharWidth: number; - scaledCharHeight: number; - allowTransparency: boolean; - colors: IColorSet; -} From 64062d1a25d7c0c4b252a928370b3230ed74f6d4 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 14 Jul 2019 09:38:49 -0700 Subject: [PATCH 03/56] Move CharAtlasUtils into browser --- src/browser/Types.d.ts | 9 +++++++ .../renderer/atlas/CharAtlasUtils.ts | 24 +++++++++---------- src/browser/renderer/atlas/Types.d.ts | 4 ++-- src/renderer/LinkRenderLayer.ts | 2 +- src/renderer/atlas/CharAtlasCache.ts | 6 ++--- 5 files changed, 27 insertions(+), 18 deletions(-) rename src/{ => browser}/renderer/atlas/CharAtlasUtils.ts (73%) diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index c9167316..3f3a7637 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -24,6 +24,15 @@ export interface IColorSet { ansi: IColor[]; } +export interface IPartialColorSet { + foreground: IColor; + background: IColor; + cursor?: IColor; + cursorAccent?: IColor; + selection?: IColor; + ansi: IColor[]; +} + export interface IViewport extends IDisposable { scrollBarWidth: number; syncScrollArea(): void; diff --git a/src/renderer/atlas/CharAtlasUtils.ts b/src/browser/renderer/atlas/CharAtlasUtils.ts similarity index 73% rename from src/renderer/atlas/CharAtlasUtils.ts rename to src/browser/renderer/atlas/CharAtlasUtils.ts index da067f52..346b35f8 100644 --- a/src/renderer/atlas/CharAtlasUtils.ts +++ b/src/browser/renderer/atlas/CharAtlasUtils.ts @@ -3,19 +3,19 @@ * @license MIT */ -import { ITerminal } from '../../Types'; import { ICharAtlasConfig } from 'browser/renderer/atlas/Types'; import { DEFAULT_COLOR } from 'common/buffer/Constants'; -import { IColorSet } from 'browser/Types'; +import { IColorSet, IPartialColorSet } from 'browser/Types'; +import { ITerminalOptions } from 'common/services/Services'; -export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, terminal: ITerminal, colors: IColorSet): ICharAtlasConfig { +export function generateConfig(scaledCharWidth: number, scaledCharHeight: number, options: ITerminalOptions, colors: IColorSet): ICharAtlasConfig { // null out some fields that don't matter - const clonedColors = { + const clonedColors = { foreground: colors.foreground, background: colors.background, - cursor: null, - cursorAccent: null, - selection: null, + cursor: undefined, + cursorAccent: undefined, + selection: undefined, // For the static char atlas, we only use the first 16 colors, but we need all 256 for the // dynamic character atlas. ansi: colors.ansi.slice(0, 16) @@ -24,11 +24,11 @@ export function generateConfig(scaledCharWidth: number, scaledCharHeight: number devicePixelRatio: window.devicePixelRatio, scaledCharWidth, scaledCharHeight, - fontFamily: terminal.options.fontFamily, - fontSize: terminal.options.fontSize, - fontWeight: terminal.options.fontWeight, - fontWeightBold: terminal.options.fontWeightBold, - allowTransparency: terminal.options.allowTransparency, + fontFamily: options.fontFamily, + fontSize: options.fontSize, + fontWeight: options.fontWeight, + fontWeightBold: options.fontWeightBold, + allowTransparency: options.allowTransparency, colors: clonedColors }; } diff --git a/src/browser/renderer/atlas/Types.d.ts b/src/browser/renderer/atlas/Types.d.ts index 0724b163..d8bc54c1 100644 --- a/src/browser/renderer/atlas/Types.d.ts +++ b/src/browser/renderer/atlas/Types.d.ts @@ -4,7 +4,7 @@ */ import { FontWeight } from 'common/services/Services'; -import { IColorSet } from 'browser/Types'; +import { IPartialColorSet } from 'browser/Types'; export interface IGlyphIdentifier { chars: string; @@ -25,5 +25,5 @@ export interface ICharAtlasConfig { scaledCharWidth: number; scaledCharHeight: number; allowTransparency: boolean; - colors: IColorSet; + colors: IPartialColorSet; } diff --git a/src/renderer/LinkRenderLayer.ts b/src/renderer/LinkRenderLayer.ts index 6e6ba2e4..f4fb966a 100644 --- a/src/renderer/LinkRenderLayer.ts +++ b/src/renderer/LinkRenderLayer.ts @@ -7,7 +7,7 @@ import { ITerminal, ILinkifierAccessor } from '../Types'; import { IRenderDimensions } from 'browser/renderer/Types'; import { BaseRenderLayer } from './BaseRenderLayer'; import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; -import { is256Color } from './atlas/CharAtlasUtils'; +import { is256Color } from 'browser/renderer/atlas/CharAtlasUtils'; import { IColorSet, ILinkifierEvent } from 'browser/Types'; export class LinkRenderLayer extends BaseRenderLayer { diff --git a/src/renderer/atlas/CharAtlasCache.ts b/src/renderer/atlas/CharAtlasCache.ts index ec66b67a..ccc4437c 100644 --- a/src/renderer/atlas/CharAtlasCache.ts +++ b/src/renderer/atlas/CharAtlasCache.ts @@ -4,9 +4,9 @@ */ import { ITerminal } from '../../Types'; -import { generateConfig, configEquals } from './CharAtlasUtils'; +import { generateConfig, configEquals } from 'browser/renderer/atlas/CharAtlasUtils'; import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; -import { DynamicCharAtlas } from '../../browser/renderer/atlas/DynamicCharAtlas'; +import { DynamicCharAtlas } from 'browser/renderer/atlas/DynamicCharAtlas'; import { ICharAtlasConfig } from 'browser/renderer/atlas/Types'; import { IColorSet } from 'browser/Types'; @@ -32,7 +32,7 @@ export function acquireCharAtlas( scaledCharWidth: number, scaledCharHeight: number ): BaseCharAtlas { - const newConfig = generateConfig(scaledCharWidth, scaledCharHeight, terminal, colors); + const newConfig = generateConfig(scaledCharWidth, scaledCharHeight, terminal.optionsService.options, colors); // Check to see if the terminal already owns this config for (let i = 0; i < charAtlasCache.length; i++) { From 60194179f800569c6b1231a87023e0663ba98eb1 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 14 Jul 2019 09:43:54 -0700 Subject: [PATCH 04/56] Move CharAtlasCache to browser --- addons/xterm-addon-webgl/src/WebglRenderer.ts | 2 +- .../xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts | 4 ---- src/Terminal.ts | 2 +- src/{ => browser}/renderer/atlas/CharAtlasCache.ts | 7 +++---- src/renderer/BaseRenderLayer.ts | 2 +- 5 files changed, 6 insertions(+), 11 deletions(-) rename src/{ => browser}/renderer/atlas/CharAtlasCache.ts (94%) diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index 3d41e1b5..41973138 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -7,7 +7,7 @@ import { ITerminal } from '../../../src/Types'; import { GlyphRenderer } from './GlyphRenderer'; import { LinkRenderLayer } from './renderLayer/LinkRenderLayer'; import { CursorRenderLayer } from './renderLayer/CursorRenderLayer'; -import { acquireCharAtlas } from './atlas/CharAtlasCache'; +import { acquireCharAtlas } from 'browser/renderer/atlas/CharAtlasCache'; import { WebglCharAtlas } from './atlas/WebglCharAtlas'; import { RectangleRenderer } from './RectangleRenderer'; import { IWebGL2RenderingContext } from './Types'; diff --git a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts index df0cdbab..0e2d645e 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts @@ -4,16 +4,12 @@ */ import { IRenderLayer } from './Types'; -import { ICellData } from 'common/Types'; -import { DEFAULT_COLOR, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from 'common/buffer/Constants'; import { IGlyphIdentifier } from '../atlas/Types'; -import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; import { acquireCharAtlas } from '../atlas/CharAtlasCache'; import { Terminal } from 'xterm'; import { IColorSet } from 'browser/Types'; import { IRenderDimensions } from 'browser/renderer/Types'; import { CellData } from 'common/buffer/CellData'; -import { AttributeData } from 'common/buffer/AttributeData'; import { WebglCharAtlas } from 'atlas/WebglCharAtlas'; import { throwIfFalsy } from '../WebglUtils'; diff --git a/src/Terminal.ts b/src/Terminal.ts index 7a068c84..0d8bf834 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -38,7 +38,7 @@ import { SoundService } from 'browser/services/SoundService'; import { MouseZoneManager } from 'browser/MouseZoneManager'; import { AccessibilityManager } from './AccessibilityManager'; import { ITheme, IMarker, IDisposable, ISelectionPosition } from 'xterm'; -import { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache'; +import { removeTerminalFromCache } from 'browser/renderer/atlas/CharAtlasCache'; import { DomRenderer } from './renderer/dom/DomRenderer'; import { IKeyboardEvent, KeyboardResultType, ICharset, IBufferLine, IAttributeData } from 'common/Types'; import { evaluateKeyboardEvent } from 'common/input/Keyboard'; diff --git a/src/renderer/atlas/CharAtlasCache.ts b/src/browser/renderer/atlas/CharAtlasCache.ts similarity index 94% rename from src/renderer/atlas/CharAtlasCache.ts rename to src/browser/renderer/atlas/CharAtlasCache.ts index ccc4437c..92c970f2 100644 --- a/src/renderer/atlas/CharAtlasCache.ts +++ b/src/browser/renderer/atlas/CharAtlasCache.ts @@ -3,7 +3,6 @@ * @license MIT */ -import { ITerminal } from '../../Types'; import { generateConfig, configEquals } from 'browser/renderer/atlas/CharAtlasUtils'; import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; import { DynamicCharAtlas } from 'browser/renderer/atlas/DynamicCharAtlas'; @@ -15,7 +14,7 @@ interface ICharAtlasCacheEntry { config: ICharAtlasConfig; // N.B. This implementation potentially holds onto copies of the terminal forever, so // this may cause memory leaks. - ownedBy: ITerminal[]; + ownedBy: any[]; } const charAtlasCache: ICharAtlasCacheEntry[] = []; @@ -27,7 +26,7 @@ const charAtlasCache: ICharAtlasCacheEntry[] = []; * @param colors The colors to use. */ export function acquireCharAtlas( - terminal: ITerminal, + terminal: any, colors: IColorSet, scaledCharWidth: number, scaledCharHeight: number @@ -79,7 +78,7 @@ export function acquireCharAtlas( * Removes a terminal reference from the cache, allowing its memory to be freed. * @param terminal The terminal to remove. */ -export function removeTerminalFromCache(terminal: ITerminal): void { +export function removeTerminalFromCache(terminal: any): void { for (let i = 0; i < charAtlasCache.length; i++) { const index = charAtlasCache[i].ownedBy.indexOf(terminal); if (index !== -1) { diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index e704375c..f2eae23d 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -11,7 +11,7 @@ import { DEFAULT_COLOR, WHITESPACE_CELL_CHAR, WHITESPACE_CELL_CODE } from 'commo import { IGlyphIdentifier } from 'browser/renderer/atlas/Types'; import { DIM_OPACITY, INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; import { BaseCharAtlas } from 'browser/renderer/atlas/BaseCharAtlas'; -import { acquireCharAtlas } from './atlas/CharAtlasCache'; +import { acquireCharAtlas } from 'browser/renderer/atlas/CharAtlasCache'; import { AttributeData } from 'common/buffer/AttributeData'; import { IColorSet } from 'browser/Types'; import { CellData } from 'common/buffer/CellData'; From 868125f2585b86e78761253013b28ac0b2487108 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 14 Jul 2019 10:04:51 -0700 Subject: [PATCH 05/56] Don't pass terminal around within render layers Will ease migration to services --- src/renderer/BaseRenderLayer.ts | 73 +++++++++++------------ src/renderer/CursorRenderLayer.ts | 86 ++++++++++++++-------------- src/renderer/LinkRenderLayer.ts | 12 ++-- src/renderer/Renderer.ts | 26 ++++----- src/renderer/SelectionRenderLayer.ts | 30 +++++----- src/renderer/TextRenderLayer.ts | 47 ++++++++------- src/renderer/Types.d.ts | 18 +++--- 7 files changed, 143 insertions(+), 149 deletions(-) diff --git a/src/renderer/BaseRenderLayer.ts b/src/renderer/BaseRenderLayer.ts index f2eae23d..c0df47dc 100644 --- a/src/renderer/BaseRenderLayer.ts +++ b/src/renderer/BaseRenderLayer.ts @@ -46,7 +46,8 @@ export abstract class BaseRenderLayer implements IRenderLayer { id: string, zIndex: number, private _alpha: boolean, - protected _colors: IColorSet + protected _colors: IColorSet, + protected _terminal: ITerminal ) { this._canvas = document.createElement('canvas'); this._canvas.classList.add(`xterm-${id}-layer`); @@ -70,18 +71,18 @@ export abstract class BaseRenderLayer implements IRenderLayer { } } - public onOptionsChanged(terminal: ITerminal): void {} - public onBlur(terminal: ITerminal): void {} - public onFocus(terminal: ITerminal): void {} - public onCursorMove(terminal: ITerminal): void {} - public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void {} - public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number], columnSelectMode: boolean = false): void {} + public onOptionsChanged(): void {} + public onBlur(): void {} + public onFocus(): void {} + public onCursorMove(): void {} + public onGridChanged(startRow: number, endRow: number): void {} + public onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean = false): void {} - public setColors(terminal: ITerminal, colorSet: IColorSet): void { - this._refreshCharAtlas(terminal, colorSet); + public setColors(colorSet: IColorSet): void { + this._refreshCharAtlas(colorSet); } - protected _setTransparency(terminal: ITerminal, alpha: boolean): void { + protected _setTransparency(alpha: boolean): void { // Do nothing when alpha doesn't change if (alpha === this._alpha) { return; @@ -96,24 +97,23 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._container.replaceChild(this._canvas, oldCanvas); // Regenerate char atlas and force a full redraw - this._refreshCharAtlas(terminal, this._colors); - this.onGridChanged(terminal, 0, terminal.rows - 1); + this._refreshCharAtlas(this._colors); + this.onGridChanged(0, this._terminal.rows - 1); } /** * Refreshes the char atlas, aquiring a new one if necessary. - * @param terminal The terminal. * @param colorSet The color set to use for the char atlas. */ - private _refreshCharAtlas(terminal: ITerminal, colorSet: IColorSet): void { + private _refreshCharAtlas(colorSet: IColorSet): void { if (this._scaledCharWidth <= 0 && this._scaledCharHeight <= 0) { return; } - this._charAtlas = acquireCharAtlas(terminal, colorSet, this._scaledCharWidth, this._scaledCharHeight); + this._charAtlas = acquireCharAtlas(this._terminal, colorSet, this._scaledCharWidth, this._scaledCharHeight); this._charAtlas.warmUp(); } - public resize(terminal: ITerminal, dim: IRenderDimensions): void { + public resize(dim: IRenderDimensions): void { this._scaledCellWidth = dim.scaledCellWidth; this._scaledCellHeight = dim.scaledCellHeight; this._scaledCharWidth = dim.scaledCharWidth; @@ -130,10 +130,10 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._clearAll(); } - this._refreshCharAtlas(terminal, this._colors); + this._refreshCharAtlas(this._colors); } - public abstract reset(terminal: ITerminal): void; + public abstract reset(): void; /** * Fills 1+ cells completely. This uses the existing fillStyle on the context. @@ -233,16 +233,15 @@ export abstract class BaseRenderLayer implements IRenderLayer { * Draws a truecolor character at the cell. The character will be clipped to * ensure that it fits with the cell, including the cell to the right if it's * a wide character. This uses the existing fillStyle on the context. - * @param terminal The terminal. * @param cell The cell data for the character to draw. * @param x The column to draw at. * @param y The row to draw at. * @param color The color of the character. */ - protected _fillCharTrueColor(terminal: ITerminal, cell: CellData, x: number, y: number): void { - this._ctx.font = this._getFont(terminal, false, false); + protected _fillCharTrueColor(cell: CellData, x: number, y: number): void { + this._ctx.font = this._getFont(false, false); this._ctx.textBaseline = 'middle'; - this._clipRow(terminal, y); + this._clipRow(y); this._ctx.fillText( cell.getChars(), x * this._scaledCellWidth + this._scaledCharLeft, @@ -252,7 +251,6 @@ export abstract class BaseRenderLayer implements IRenderLayer { /** * Draws one or more characters at a cell. If possible this will draw using * the character atlas to reduce draw time. - * @param terminal The terminal. * @param chars The character or characters. * @param code The character code. * @param width The width of the characters. @@ -263,14 +261,14 @@ export abstract class BaseRenderLayer implements IRenderLayer { * This is used to validate whether a cached image can be used. * @param bold Whether the text is bold. */ - protected _drawChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void { + protected _drawChars(cell: ICellData, x: number, y: number): void { // skip cache right away if we draw in RGB // Note: to avoid bad runtime JoinedCellData will be skipped // in the cache handler itself (atlasDidDraw == false) and // fall through to uncached later down below if (cell.isFgRGB() || cell.isBgRGB()) { - this._drawUncachedChars(terminal, cell, x, y); + this._drawUncachedChars(cell, x, y); return; } @@ -284,7 +282,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { fg = (cell.isFgDefault()) ? DEFAULT_COLOR : cell.getFgColor(); } - const drawInBrightColor = terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8 && fg !== INVERTED_DEFAULT_COLOR; + const drawInBrightColor = this._terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8 && fg !== INVERTED_DEFAULT_COLOR; fg += drawInBrightColor ? 8 : 0; this._currentGlyphIdentifier.chars = cell.getChars() || WHITESPACE_CELL_CHAR; @@ -302,7 +300,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { ); if (!atlasDidDraw) { - this._drawUncachedChars(terminal, cell, x, y); + this._drawUncachedChars(cell, x, y); } } @@ -310,16 +308,15 @@ export abstract class BaseRenderLayer implements IRenderLayer { * Draws one or more characters at one or more cells. The character(s) will be * clipped to ensure that they fit with the cell(s), including the cell to the * right if the last character is a wide character. - * @param terminal The terminal. * @param chars The character. * @param width The width of the character. * @param fg The foreground color, in the format stored within the attributes. * @param x The column to draw at. * @param y The row to draw at. */ - private _drawUncachedChars(terminal: ITerminal, cell: ICellData, x: number, y: number): void { + private _drawUncachedChars(cell: ICellData, x: number, y: number): void { this._ctx.save(); - this._ctx.font = this._getFont(terminal, !!cell.isBold(), !!cell.isItalic()); + this._ctx.font = this._getFont(!!cell.isBold(), !!cell.isItalic()); this._ctx.textBaseline = 'middle'; if (cell.isInverse()) { @@ -337,14 +334,14 @@ export abstract class BaseRenderLayer implements IRenderLayer { this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`; } else { let fg = cell.getFgColor(); - if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) { + if (this._terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) { fg += 8; } this._ctx.fillStyle = this._colors.ansi[fg].css; } } - this._clipRow(terminal, y); + this._clipRow(y); // Apply alpha to dim the character if (cell.isDim()) { @@ -360,29 +357,27 @@ export abstract class BaseRenderLayer implements IRenderLayer { /** * Clips a row to ensure no pixels will be drawn outside the cells in the row. - * @param terminal The terminal. * @param y The row to clip. */ - private _clipRow(terminal: ITerminal, y: number): void { + private _clipRow(y: number): void { this._ctx.beginPath(); this._ctx.rect( 0, y * this._scaledCellHeight, - terminal.cols * this._scaledCellWidth, + this._terminal.cols * this._scaledCellWidth, this._scaledCellHeight); this._ctx.clip(); } /** * Gets the current font. - * @param terminal The terminal. * @param isBold If we should use the bold fontWeight. */ - protected _getFont(terminal: ITerminal, isBold: boolean, isItalic: boolean): string { - const fontWeight = isBold ? terminal.options.fontWeightBold : terminal.options.fontWeight; + protected _getFont(isBold: boolean, isItalic: boolean): string { + const fontWeight = isBold ? this._terminal.options.fontWeightBold : this._terminal.options.fontWeight; const fontStyle = isItalic ? 'italic' : ''; - return `${fontStyle} ${fontWeight} ${terminal.options.fontSize * window.devicePixelRatio}px ${terminal.options.fontFamily}`; + return `${fontStyle} ${fontWeight} ${this._terminal.options.fontSize * window.devicePixelRatio}px ${this._terminal.options.fontFamily}`; } } diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index b0e43fdc..33674bb7 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -25,12 +25,12 @@ const BLINK_INTERVAL = 600; export class CursorRenderLayer extends BaseRenderLayer { private _state: ICursorState; - private _cursorRenderers: {[key: string]: (terminal: ITerminal, x: number, y: number, cell: ICellData) => void}; + private _cursorRenderers: {[key: string]: (x: number, y: number, cell: ICellData) => void}; private _cursorBlinkStateManager: CursorBlinkStateManager; private _cell: ICellData = new CellData(); - constructor(container: HTMLElement, zIndex: number, colors: IColorSet) { - super(container, 'cursor', zIndex, true, colors); + constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ITerminal) { + super(container, 'cursor', zIndex, true, colors, terminal); this._state = { x: null, y: null, @@ -46,8 +46,8 @@ export class CursorRenderLayer extends BaseRenderLayer { // TODO: Consider initial options? Maybe onOptionsChanged should be called at the end of open? } - public resize(terminal: ITerminal, dim: IRenderDimensions): void { - super.resize(terminal, dim); + public resize(dim: IRenderDimensions): void { + super.resize(dim); // Resizing the canvas discards the contents of the canvas so clear state this._state = { x: null, @@ -58,35 +58,35 @@ export class CursorRenderLayer extends BaseRenderLayer { }; } - public reset(terminal: ITerminal): void { + public reset(): void { this._clearCursor(); if (this._cursorBlinkStateManager) { this._cursorBlinkStateManager.dispose(); this._cursorBlinkStateManager = null; - this.onOptionsChanged(terminal); + this.onOptionsChanged(); } } - public onBlur(terminal: ITerminal): void { + public onBlur(): void { if (this._cursorBlinkStateManager) { this._cursorBlinkStateManager.pause(); } - terminal.refresh(terminal.buffer.y, terminal.buffer.y); + this._terminal.refresh(this._terminal.buffer.y, this._terminal.buffer.y); } - public onFocus(terminal: ITerminal): void { + public onFocus(): void { if (this._cursorBlinkStateManager) { - this._cursorBlinkStateManager.resume(terminal); + this._cursorBlinkStateManager.resume(this._terminal); } else { - terminal.refresh(terminal.buffer.y, terminal.buffer.y); + this._terminal.refresh(this._terminal.buffer.y, this._terminal.buffer.y); } } - public onOptionsChanged(terminal: ITerminal): void { - if (terminal.options.cursorBlink) { + public onOptionsChanged(): void { + if (this._terminal.options.cursorBlink) { if (!this._cursorBlinkStateManager) { - this._cursorBlinkStateManager = new CursorBlinkStateManager(terminal, () => { - this._render(terminal, true); + this._cursorBlinkStateManager = new CursorBlinkStateManager(this._terminal, () => { + this._render(true); }); } } else { @@ -96,55 +96,55 @@ export class CursorRenderLayer extends BaseRenderLayer { } // Request a refresh from the terminal as management of rendering is being // moved back to the terminal - terminal.refresh(terminal.buffer.y, terminal.buffer.y); + this._terminal.refresh(this._terminal.buffer.y, this._terminal.buffer.y); } } - public onCursorMove(terminal: ITerminal): void { + public onCursorMove(): void { if (this._cursorBlinkStateManager) { - this._cursorBlinkStateManager.restartBlinkAnimation(terminal); + this._cursorBlinkStateManager.restartBlinkAnimation(this._terminal); } } - public onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void { + public onGridChanged(startRow: number, endRow: number): void { if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) { - this._render(terminal, false); + this._render(false); } else { - this._cursorBlinkStateManager.restartBlinkAnimation(terminal); + this._cursorBlinkStateManager.restartBlinkAnimation(this._terminal); } } - private _render(terminal: ITerminal, triggeredByAnimationFrame: boolean): void { + private _render(triggeredByAnimationFrame: boolean): void { // Don't draw the cursor if it's hidden - if (!terminal.cursorState || terminal.cursorHidden) { + if (!this._terminal.cursorState || this._terminal.cursorHidden) { this._clearCursor(); return; } - const cursorY = terminal.buffer.ybase + terminal.buffer.y; - const viewportRelativeCursorY = cursorY - terminal.buffer.ydisp; + const cursorY = this._terminal.buffer.ybase + this._terminal.buffer.y; + const viewportRelativeCursorY = cursorY - this._terminal.buffer.ydisp; // Don't draw the cursor if it's off-screen - if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= terminal.rows) { + if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= this._terminal.rows) { this._clearCursor(); return; } - terminal.buffer.lines.get(cursorY).loadCell(terminal.buffer.x, this._cell); + this._terminal.buffer.lines.get(cursorY).loadCell(this._terminal.buffer.x, this._cell); if (this._cell.content === undefined) { return; } - if (!terminal.isFocused) { + if (!this._terminal.isFocused) { this._clearCursor(); this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; - this._renderBlurCursor(terminal, terminal.buffer.x, viewportRelativeCursorY, this._cell); + this._renderBlurCursor(this._terminal.buffer.x, viewportRelativeCursorY, this._cell); this._ctx.restore(); - this._state.x = terminal.buffer.x; + this._state.x = this._terminal.buffer.x; this._state.y = viewportRelativeCursorY; this._state.isFocused = false; - this._state.style = terminal.options.cursorStyle; + this._state.style = this._terminal.options.cursorStyle; this._state.width = this._cell.getWidth(); return; } @@ -157,10 +157,10 @@ export class CursorRenderLayer extends BaseRenderLayer { if (this._state) { // The cursor is already in the correct spot, don't redraw - if (this._state.x === terminal.buffer.x && + if (this._state.x === this._terminal.buffer.x && this._state.y === viewportRelativeCursorY && - this._state.isFocused === terminal.isFocused && - this._state.style === terminal.options.cursorStyle && + this._state.isFocused === this._terminal.isFocused && + this._state.style === this._terminal.options.cursorStyle && this._state.width === this._cell.getWidth()) { return; } @@ -168,13 +168,13 @@ export class CursorRenderLayer extends BaseRenderLayer { } this._ctx.save(); - this._cursorRenderers[terminal.options.cursorStyle || 'block'](terminal, terminal.buffer.x, viewportRelativeCursorY, this._cell); + this._cursorRenderers[this._terminal.options.cursorStyle || 'block'](this._terminal.buffer.x, viewportRelativeCursorY, this._cell); this._ctx.restore(); - this._state.x = terminal.buffer.x; + this._state.x = this._terminal.buffer.x; this._state.y = viewportRelativeCursorY; this._state.isFocused = false; - this._state.style = terminal.options.cursorStyle; + this._state.style = this._terminal.options.cursorStyle; this._state.width = this._cell.getWidth(); } @@ -191,30 +191,30 @@ export class CursorRenderLayer extends BaseRenderLayer { } } - private _renderBarCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void { + private _renderBarCursor(x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; this._fillLeftLineAtCell(x, y); this._ctx.restore(); } - private _renderBlockCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void { + private _renderBlockCursor(x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; this._fillCells(x, y, cell.getWidth(), 1); this._ctx.fillStyle = this._colors.cursorAccent.css; - this._fillCharTrueColor(terminal, cell, x, y); + this._fillCharTrueColor(cell, x, y); this._ctx.restore(); } - private _renderUnderlineCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void { + private _renderUnderlineCursor(x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; this._fillBottomLineAtCells(x, y); this._ctx.restore(); } - private _renderBlurCursor(terminal: ITerminal, x: number, y: number, cell: ICellData): void { + private _renderBlurCursor(x: number, y: number, cell: ICellData): void { this._ctx.save(); this._ctx.strokeStyle = this._colors.cursor.css; this._strokeRectAtCell(x, y, cell.getWidth(), 1); diff --git a/src/renderer/LinkRenderLayer.ts b/src/renderer/LinkRenderLayer.ts index f4fb966a..52625439 100644 --- a/src/renderer/LinkRenderLayer.ts +++ b/src/renderer/LinkRenderLayer.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { ITerminal, ILinkifierAccessor } from '../Types'; +import { ITerminal } from '../Types'; import { IRenderDimensions } from 'browser/renderer/Types'; import { BaseRenderLayer } from './BaseRenderLayer'; import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; @@ -13,19 +13,19 @@ import { IColorSet, ILinkifierEvent } from 'browser/Types'; export class LinkRenderLayer extends BaseRenderLayer { private _state: ILinkifierEvent = null; - constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ILinkifierAccessor) { - super(container, 'link', zIndex, true, colors); + constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ITerminal) { + super(container, 'link', zIndex, true, colors, terminal); terminal.linkifier.onLinkHover(e => this._onLinkHover(e)); terminal.linkifier.onLinkLeave(e => this._onLinkLeave(e)); } - public resize(terminal: ITerminal, dim: IRenderDimensions): void { - super.resize(terminal, dim); + public resize(dim: IRenderDimensions): void { + super.resize(dim); // Resizing the canvas discards the contents of the canvas so clear state this._state = null; } - public reset(terminal: ITerminal): void { + public reset(): void { this._clearCurrentLink(); } diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index 2ed61b76..04ad6989 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -34,10 +34,10 @@ export class Renderer extends Disposable implements IRenderer { this._characterJoinerRegistry = new CharacterJoinerRegistry(bufferService); this._renderLayers = [ - new TextRenderLayer(this._terminal.screenElement, 0, this._colors, this._characterJoinerRegistry, allowTransparency), - new SelectionRenderLayer(this._terminal.screenElement, 1, this._colors), + new TextRenderLayer(this._terminal.screenElement, 0, this._colors, this._characterJoinerRegistry, allowTransparency, this._terminal), + new SelectionRenderLayer(this._terminal.screenElement, 1, this._colors, this._terminal), new LinkRenderLayer(this._terminal.screenElement, 2, this._colors, this._terminal), - new CursorRenderLayer(this._terminal.screenElement, 3, this._colors) + new CursorRenderLayer(this._terminal.screenElement, 3, this._colors, this._terminal) ]; this.dimensions = { scaledCharWidth: null, @@ -77,8 +77,8 @@ export class Renderer extends Disposable implements IRenderer { // Clear layers and force a full render this._renderLayers.forEach(l => { - l.setColors(this._terminal, this._colors); - l.reset(this._terminal); + l.setColors(this._colors); + l.reset(); }); } @@ -87,7 +87,7 @@ export class Renderer extends Disposable implements IRenderer { this._updateDimensions(); // Resize all render layers - this._renderLayers.forEach(l => l.resize(this._terminal, this.dimensions)); + this._renderLayers.forEach(l => l.resize(this.dimensions)); // Resize the screen this._terminal.screenElement.style.width = `${this.dimensions.canvasWidth}px`; @@ -99,27 +99,27 @@ export class Renderer extends Disposable implements IRenderer { } public onBlur(): void { - this._runOperation(l => l.onBlur(this._terminal)); + this._runOperation(l => l.onBlur()); } public onFocus(): void { - this._runOperation(l => l.onFocus(this._terminal)); + this._runOperation(l => l.onFocus()); } public onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean = false): void { - this._runOperation(l => l.onSelectionChanged(this._terminal, start, end, columnSelectMode)); + this._runOperation(l => l.onSelectionChanged(start, end, columnSelectMode)); } public onCursorMove(): void { - this._runOperation(l => l.onCursorMove(this._terminal)); + this._runOperation(l => l.onCursorMove()); } public onOptionsChanged(): void { - this._runOperation(l => l.onOptionsChanged(this._terminal)); + this._runOperation(l => l.onOptionsChanged()); } public clear(): void { - this._runOperation(l => l.reset(this._terminal)); + this._runOperation(l => l.reset()); } private _runOperation(operation: (layer: IRenderLayer) => void): void { @@ -131,7 +131,7 @@ export class Renderer extends Disposable implements IRenderer { * necessary before queueing up the next one. */ public renderRows(start: number, end: number): void { - this._renderLayers.forEach(l => l.onGridChanged(this._terminal, start, end)); + this._renderLayers.forEach(l => l.onGridChanged(start, end)); } /** diff --git a/src/renderer/SelectionRenderLayer.ts b/src/renderer/SelectionRenderLayer.ts index 20b86a3f..1735f786 100644 --- a/src/renderer/SelectionRenderLayer.ts +++ b/src/renderer/SelectionRenderLayer.ts @@ -18,8 +18,8 @@ interface ISelectionState { export class SelectionRenderLayer extends BaseRenderLayer { private _state: ISelectionState; - constructor(container: HTMLElement, zIndex: number, colors: IColorSet) { - super(container, 'selection', zIndex, true, colors); + constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ITerminal) { + super(container, 'selection', zIndex, true, colors, terminal); this._clearState(); } @@ -32,22 +32,22 @@ export class SelectionRenderLayer extends BaseRenderLayer { }; } - public resize(terminal: ITerminal, dim: IRenderDimensions): void { - super.resize(terminal, dim); + public resize(dim: IRenderDimensions): void { + super.resize(dim); // Resizing the canvas discards the contents of the canvas so clear state this._clearState(); } - public reset(terminal: ITerminal): void { + public reset(): void { if (this._state.start && this._state.end) { this._clearState(); this._clearAll(); } } - public onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number], columnSelectMode: boolean): void { + public onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean): void { // Selection has not changed - if (!this._didStateChange(start, end, columnSelectMode, terminal.buffer.ydisp)) { + if (!this._didStateChange(start, end, columnSelectMode, this._terminal.buffer.ydisp)) { return; } @@ -61,13 +61,13 @@ export class SelectionRenderLayer extends BaseRenderLayer { } // Translate from buffer position to viewport position - const viewportStartRow = start[1] - terminal.buffer.ydisp; - const viewportEndRow = end[1] - terminal.buffer.ydisp; + const viewportStartRow = start[1] - this._terminal.buffer.ydisp; + const viewportEndRow = end[1] - this._terminal.buffer.ydisp; const viewportCappedStartRow = Math.max(viewportStartRow, 0); - const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1); + const viewportCappedEndRow = Math.min(viewportEndRow, this._terminal.rows - 1); // No need to draw the selection - if (viewportCappedStartRow >= terminal.rows || viewportCappedEndRow < 0) { + if (viewportCappedStartRow >= this._terminal.rows || viewportCappedEndRow < 0) { return; } @@ -81,17 +81,17 @@ export class SelectionRenderLayer extends BaseRenderLayer { } else { // Draw first row const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0; - const startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : terminal.cols; + const startRowEndCol = viewportCappedStartRow === viewportCappedEndRow ? end[0] : this._terminal.cols; this._fillCells(startCol, viewportCappedStartRow, startRowEndCol - startCol, 1); // Draw middle rows const middleRowsCount = Math.max(viewportCappedEndRow - viewportCappedStartRow - 1, 0); - this._fillCells(0, viewportCappedStartRow + 1, terminal.cols, middleRowsCount); + this._fillCells(0, viewportCappedStartRow + 1, this._terminal.cols, middleRowsCount); // Draw final row if (viewportCappedStartRow !== viewportCappedEndRow) { // Only draw viewportEndRow if it's not the same as viewportStartRow - const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : terminal.cols; + const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._terminal.cols; this._fillCells(0, viewportCappedEndRow, endCol, 1); } } @@ -100,7 +100,7 @@ export class SelectionRenderLayer extends BaseRenderLayer { this._state.start = [start[0], start[1]]; this._state.end = [end[0], end[1]]; this._state.columnSelectMode = columnSelectMode; - this._state.ydisp = terminal.buffer.ydisp; + this._state.ydisp = this._terminal.buffer.ydisp; } private _didStateChange(start: [number, number], end: [number, number], columnSelectMode: boolean, ydisp: number): boolean { diff --git a/src/renderer/TextRenderLayer.ts b/src/renderer/TextRenderLayer.ts index 03e5c112..b1e59451 100644 --- a/src/renderer/TextRenderLayer.ts +++ b/src/renderer/TextRenderLayer.ts @@ -29,17 +29,17 @@ export class TextRenderLayer extends BaseRenderLayer { private _characterJoinerRegistry: ICharacterJoinerRegistry; private _workCell = new CellData(); - constructor(container: HTMLElement, zIndex: number, colors: IColorSet, characterJoinerRegistry: ICharacterJoinerRegistry, alpha: boolean) { - super(container, 'text', zIndex, alpha, colors); + constructor(container: HTMLElement, zIndex: number, colors: IColorSet, characterJoinerRegistry: ICharacterJoinerRegistry, alpha: boolean, terminal: ITerminal) { + super(container, 'text', zIndex, alpha, colors, terminal); this._state = new GridCache(); this._characterJoinerRegistry = characterJoinerRegistry; } - public resize(terminal: ITerminal, dim: IRenderDimensions): void { - super.resize(terminal, dim); + public resize(dim: IRenderDimensions): void { + super.resize(dim); // Clear the character width cache if the font or width has changed - const terminalFont = this._getFont(terminal, false, false); + const terminalFont = this._getFont(false, false); if (this._characterWidth !== dim.scaledCharWidth || this._characterFont !== terminalFont) { this._characterWidth = dim.scaledCharWidth; this._characterFont = terminalFont; @@ -47,16 +47,15 @@ export class TextRenderLayer extends BaseRenderLayer { } // Resizing the canvas discards the contents of the canvas so clear state this._state.clear(); - this._state.resize(terminal.cols, terminal.rows); + this._state.resize(this._terminal.cols, this._terminal.rows); } - public reset(terminal: ITerminal): void { + public reset(): void { this._state.clear(); this._clearAll(); } private _forEachCell( - terminal: ITerminal, firstRow: number, lastRow: number, joinerRegistry: ICharacterJoinerRegistry | null, @@ -67,10 +66,10 @@ export class TextRenderLayer extends BaseRenderLayer { ) => void ): void { for (let y = firstRow; y <= lastRow; y++) { - const row = y + terminal.buffer.ydisp; - const line = terminal.buffer.lines.get(row); + const row = y + this._terminal.buffer.ydisp; + const line = this._terminal.buffer.lines.get(row); const joinedRanges = joinerRegistry ? joinerRegistry.getJoinedCharacters(row) : []; - for (let x = 0; x < terminal.cols; x++) { + for (let x = 0; x < this._terminal.cols; x++) { line.loadCell(x, this._workCell); let cell = this._workCell; @@ -143,16 +142,16 @@ export class TextRenderLayer extends BaseRenderLayer { * Draws the background for a specified range of columns. Tries to batch adjacent cells of the * same color together to reduce draw calls. */ - private _drawBackground(terminal: ITerminal, firstRow: number, lastRow: number): void { + private _drawBackground(firstRow: number, lastRow: number): void { const ctx = this._ctx; - const cols = terminal.cols; + const cols = this._terminal.cols; let startX: number = 0; let startY: number = 0; let prevFillStyle: string | null = null; ctx.save(); - this._forEachCell(terminal, firstRow, lastRow, null, (cell, x, y) => { + this._forEachCell(firstRow, lastRow, null, (cell, x, y) => { // libvte and xterm both draw the background (but not foreground) of invisible characters, // so we should too. let nextFillStyle = null; // null represents default background color @@ -202,12 +201,12 @@ export class TextRenderLayer extends BaseRenderLayer { ctx.restore(); } - private _drawForeground(terminal: ITerminal, firstRow: number, lastRow: number): void { - this._forEachCell(terminal, firstRow, lastRow, this._characterJoinerRegistry, (cell, x, y) => { + private _drawForeground(firstRow: number, lastRow: number): void { + this._forEachCell(firstRow, lastRow, this._characterJoinerRegistry, (cell, x, y) => { if (cell.isInvisible()) { return; } - this._drawChars(terminal, cell, x, y); + this._drawChars(cell, x, y); if (cell.isUnderline()) { this._ctx.save(); @@ -226,7 +225,7 @@ export class TextRenderLayer extends BaseRenderLayer { this._ctx.fillStyle = `rgb(${AttributeData.toColorRGB(cell.getFgColor()).join(',')})`; } else { let fg = cell.getFgColor(); - if (terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) { + if (this._terminal.options.drawBoldTextInBrightColors && cell.isBold() && fg < 8) { fg += 8; } this._ctx.fillStyle = this._colors.ansi[fg].css; @@ -239,7 +238,7 @@ export class TextRenderLayer extends BaseRenderLayer { }); } - public onGridChanged(terminal: ITerminal, firstRow: number, lastRow: number): void { + public onGridChanged(firstRow: number, lastRow: number): void { // Resize has not been called yet if (this._state.cache.length === 0) { return; @@ -249,13 +248,13 @@ export class TextRenderLayer extends BaseRenderLayer { this._charAtlas.beginFrame(); } - this._clearCells(0, firstRow, terminal.cols, lastRow - firstRow + 1); - this._drawBackground(terminal, firstRow, lastRow); - this._drawForeground(terminal, firstRow, lastRow); + this._clearCells(0, firstRow, this._terminal.cols, lastRow - firstRow + 1); + this._drawBackground(firstRow, lastRow); + this._drawForeground(firstRow, lastRow); } - public onOptionsChanged(terminal: ITerminal): void { - this._setTransparency(terminal, terminal.options.allowTransparency); + public onOptionsChanged(): void { + this._setTransparency(this._terminal.options.allowTransparency); } /** diff --git a/src/renderer/Types.d.ts b/src/renderer/Types.d.ts index 1546248a..422a01c6 100644 --- a/src/renderer/Types.d.ts +++ b/src/renderer/Types.d.ts @@ -12,38 +12,38 @@ export interface IRenderLayer extends IDisposable { /** * Called when the terminal loses focus. */ - onBlur(terminal: ITerminal): void; + onBlur(): void; /** * * Called when the terminal gets focus. */ - onFocus(terminal: ITerminal): void; + onFocus(): void; /** * Called when the cursor is moved. */ - onCursorMove(terminal: ITerminal): void; + onCursorMove(): void; /** * Called when options change. */ - onOptionsChanged(terminal: ITerminal): void; + onOptionsChanged(): void; /** * Called when the theme changes. */ - setColors(terminal: ITerminal, colorSet: IColorSet): void; + setColors(colorSet: IColorSet): void; /** * Called when the data in the grid has changed (or needs to be rendered * again). */ - onGridChanged(terminal: ITerminal, startRow: number, endRow: number): void; + onGridChanged(startRow: number, endRow: number): void; /** * Calls when the selection changes. */ - onSelectionChanged(terminal: ITerminal, start: [number, number], end: [number, number], columnSelectMode: boolean): void; + onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean): void; /** * Registers a handler to join characters to render as a group @@ -58,10 +58,10 @@ export interface IRenderLayer extends IDisposable { /** * Resize the render layer. */ - resize(terminal: ITerminal, dim: IRenderDimensions): void; + resize(dim: IRenderDimensions): void; /** * Clear the state of the render layer. */ - reset(terminal: ITerminal): void; + reset(): void; } From bd95c83ca2e59bd41a92252ebca6735322740e5a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 14 Jul 2019 10:15:58 -0700 Subject: [PATCH 06/56] Start using services in most render layers --- src/Terminal.ts | 2 +- src/renderer/CursorRenderLayer.ts | 60 ++++++++++++++++------------ src/renderer/LinkRenderLayer.ts | 8 ++-- src/renderer/Renderer.ts | 11 ++--- src/renderer/SelectionRenderLayer.ts | 17 +++++--- 5 files changed, 57 insertions(+), 41 deletions(-) diff --git a/src/Terminal.ts b/src/Terminal.ts index 0d8bf834..48792ac5 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -685,7 +685,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp private _createRenderer(): IRenderer { switch (this.options.rendererType) { - case 'canvas': return new Renderer(this._colorManager.colors, this, this._bufferService, this._charSizeService); + case 'canvas': return new Renderer(this._colorManager.colors, this, this._bufferService, this._charSizeService, this.optionsService); case 'dom': return new DomRenderer(this, this._colorManager.colors, this._charSizeService, this.optionsService); default: throw new Error(`Unrecognized rendererType "${this.options.rendererType}"`); } diff --git a/src/renderer/CursorRenderLayer.ts b/src/renderer/CursorRenderLayer.ts index 33674bb7..26e5e4ac 100644 --- a/src/renderer/CursorRenderLayer.ts +++ b/src/renderer/CursorRenderLayer.ts @@ -9,6 +9,7 @@ import { ITerminal } from '../Types'; import { ICellData } from 'common/Types'; import { CellData } from 'common/buffer/CellData'; import { IColorSet } from 'browser/Types'; +import { IBufferService, IOptionsService } from 'common/services/Services'; interface ICursorState { x: number; @@ -29,7 +30,14 @@ export class CursorRenderLayer extends BaseRenderLayer { private _cursorBlinkStateManager: CursorBlinkStateManager; private _cell: ICellData = new CellData(); - constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ITerminal) { + constructor( + container: HTMLElement, + zIndex: number, + colors: IColorSet, + terminal: ITerminal, + private readonly _bufferService: IBufferService, + private readonly _optionsService: IOptionsService + ) { super(container, 'cursor', zIndex, true, colors, terminal); this._state = { x: null, @@ -71,21 +79,21 @@ export class CursorRenderLayer extends BaseRenderLayer { if (this._cursorBlinkStateManager) { this._cursorBlinkStateManager.pause(); } - this._terminal.refresh(this._terminal.buffer.y, this._terminal.buffer.y); + this._terminal.refresh(this._bufferService.buffer.y, this._bufferService.buffer.y); } public onFocus(): void { if (this._cursorBlinkStateManager) { - this._cursorBlinkStateManager.resume(this._terminal); + this._cursorBlinkStateManager.resume(); } else { - this._terminal.refresh(this._terminal.buffer.y, this._terminal.buffer.y); + this._terminal.refresh(this._bufferService.buffer.y, this._bufferService.buffer.y); } } public onOptionsChanged(): void { - if (this._terminal.options.cursorBlink) { + if (this._optionsService.options.cursorBlink) { if (!this._cursorBlinkStateManager) { - this._cursorBlinkStateManager = new CursorBlinkStateManager(this._terminal, () => { + this._cursorBlinkStateManager = new CursorBlinkStateManager(this._terminal.isFocused, () => { this._render(true); }); } @@ -96,13 +104,13 @@ export class CursorRenderLayer extends BaseRenderLayer { } // Request a refresh from the terminal as management of rendering is being // moved back to the terminal - this._terminal.refresh(this._terminal.buffer.y, this._terminal.buffer.y); + this._terminal.refresh(this._bufferService.buffer.y, this._bufferService.buffer.y); } } public onCursorMove(): void { if (this._cursorBlinkStateManager) { - this._cursorBlinkStateManager.restartBlinkAnimation(this._terminal); + this._cursorBlinkStateManager.restartBlinkAnimation(); } } @@ -110,7 +118,7 @@ export class CursorRenderLayer extends BaseRenderLayer { if (!this._cursorBlinkStateManager || this._cursorBlinkStateManager.isPaused) { this._render(false); } else { - this._cursorBlinkStateManager.restartBlinkAnimation(this._terminal); + this._cursorBlinkStateManager.restartBlinkAnimation(); } } @@ -121,16 +129,16 @@ export class CursorRenderLayer extends BaseRenderLayer { return; } - const cursorY = this._terminal.buffer.ybase + this._terminal.buffer.y; - const viewportRelativeCursorY = cursorY - this._terminal.buffer.ydisp; + const cursorY = this._bufferService.buffer.ybase + this._bufferService.buffer.y; + const viewportRelativeCursorY = cursorY - this._bufferService.buffer.ydisp; // Don't draw the cursor if it's off-screen - if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= this._terminal.rows) { + if (viewportRelativeCursorY < 0 || viewportRelativeCursorY >= this._bufferService.rows) { this._clearCursor(); return; } - this._terminal.buffer.lines.get(cursorY).loadCell(this._terminal.buffer.x, this._cell); + this._bufferService.buffer.lines.get(cursorY).loadCell(this._bufferService.buffer.x, this._cell); if (this._cell.content === undefined) { return; } @@ -139,12 +147,12 @@ export class CursorRenderLayer extends BaseRenderLayer { this._clearCursor(); this._ctx.save(); this._ctx.fillStyle = this._colors.cursor.css; - this._renderBlurCursor(this._terminal.buffer.x, viewportRelativeCursorY, this._cell); + this._renderBlurCursor(this._bufferService.buffer.x, viewportRelativeCursorY, this._cell); this._ctx.restore(); - this._state.x = this._terminal.buffer.x; + this._state.x = this._bufferService.buffer.x; this._state.y = viewportRelativeCursorY; this._state.isFocused = false; - this._state.style = this._terminal.options.cursorStyle; + this._state.style = this._optionsService.options.cursorStyle; this._state.width = this._cell.getWidth(); return; } @@ -157,10 +165,10 @@ export class CursorRenderLayer extends BaseRenderLayer { if (this._state) { // The cursor is already in the correct spot, don't redraw - if (this._state.x === this._terminal.buffer.x && + if (this._state.x === this._bufferService.buffer.x && this._state.y === viewportRelativeCursorY && this._state.isFocused === this._terminal.isFocused && - this._state.style === this._terminal.options.cursorStyle && + this._state.style === this._optionsService.options.cursorStyle && this._state.width === this._cell.getWidth()) { return; } @@ -168,13 +176,13 @@ export class CursorRenderLayer extends BaseRenderLayer { } this._ctx.save(); - this._cursorRenderers[this._terminal.options.cursorStyle || 'block'](this._terminal.buffer.x, viewportRelativeCursorY, this._cell); + this._cursorRenderers[this._optionsService.options.cursorStyle || 'block'](this._bufferService.buffer.x, viewportRelativeCursorY, this._cell); this._ctx.restore(); - this._state.x = this._terminal.buffer.x; + this._state.x = this._bufferService.buffer.x; this._state.y = viewportRelativeCursorY; this._state.isFocused = false; - this._state.style = this._terminal.options.cursorStyle; + this._state.style = this._optionsService.options.cursorStyle; this._state.width = this._cell.getWidth(); } @@ -237,11 +245,11 @@ class CursorBlinkStateManager { private _animationTimeRestarted: number; constructor( - terminal: ITerminal, + isFocused: boolean, private _renderCallback: () => void ) { this.isCursorVisible = true; - if (terminal.isFocused) { + if (isFocused) { this._restartInterval(); } } @@ -263,7 +271,7 @@ class CursorBlinkStateManager { } } - public restartBlinkAnimation(terminal: ITerminal): void { + public restartBlinkAnimation(): void { if (this.isPaused) { return; } @@ -346,9 +354,9 @@ class CursorBlinkStateManager { } } - public resume(terminal: ITerminal): void { + public resume(): void { this._animationTimeRestarted = null; this._restartInterval(); - this.restartBlinkAnimation(terminal); + this.restartBlinkAnimation(); } } diff --git a/src/renderer/LinkRenderLayer.ts b/src/renderer/LinkRenderLayer.ts index 52625439..b57abaab 100644 --- a/src/renderer/LinkRenderLayer.ts +++ b/src/renderer/LinkRenderLayer.ts @@ -8,15 +8,15 @@ import { IRenderDimensions } from 'browser/renderer/Types'; import { BaseRenderLayer } from './BaseRenderLayer'; import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; import { is256Color } from 'browser/renderer/atlas/CharAtlasUtils'; -import { IColorSet, ILinkifierEvent } from 'browser/Types'; +import { IColorSet, ILinkifierEvent, ILinkifier } from 'browser/Types'; export class LinkRenderLayer extends BaseRenderLayer { private _state: ILinkifierEvent = null; - constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ITerminal) { + constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ITerminal, linkifier: ILinkifier) { super(container, 'link', zIndex, true, colors, terminal); - terminal.linkifier.onLinkHover(e => this._onLinkHover(e)); - terminal.linkifier.onLinkLeave(e => this._onLinkLeave(e)); + linkifier.onLinkHover(e => this._onLinkHover(e)); + linkifier.onLinkLeave(e => this._onLinkLeave(e)); } public resize(dim: IRenderDimensions): void { diff --git a/src/renderer/Renderer.ts b/src/renderer/Renderer.ts index 04ad6989..090cc8e8 100644 --- a/src/renderer/Renderer.ts +++ b/src/renderer/Renderer.ts @@ -14,7 +14,7 @@ import { CharacterJoinerRegistry } from 'browser/renderer/CharacterJoinerRegistr import { Disposable } from 'common/Lifecycle'; import { IColorSet } from 'browser/Types'; import { ICharSizeService } from 'browser/services/Services'; -import { IBufferService } from 'common/services/Services'; +import { IBufferService, IOptionsService } from 'common/services/Services'; export class Renderer extends Disposable implements IRenderer { private _renderLayers: IRenderLayer[]; @@ -27,7 +27,8 @@ export class Renderer extends Disposable implements IRenderer { private _colors: IColorSet, private readonly _terminal: ITerminal, readonly bufferService: IBufferService, - private readonly _charSizeService: ICharSizeService + private readonly _charSizeService: ICharSizeService, + readonly optionsService: IOptionsService ) { super(); const allowTransparency = this._terminal.options.allowTransparency; @@ -35,9 +36,9 @@ export class Renderer extends Disposable implements IRenderer { this._renderLayers = [ new TextRenderLayer(this._terminal.screenElement, 0, this._colors, this._characterJoinerRegistry, allowTransparency, this._terminal), - new SelectionRenderLayer(this._terminal.screenElement, 1, this._colors, this._terminal), - new LinkRenderLayer(this._terminal.screenElement, 2, this._colors, this._terminal), - new CursorRenderLayer(this._terminal.screenElement, 3, this._colors, this._terminal) + new SelectionRenderLayer(this._terminal.screenElement, 1, this._colors, this._terminal, bufferService), + new LinkRenderLayer(this._terminal.screenElement, 2, this._colors, this._terminal, this._terminal.linkifier), + new CursorRenderLayer(this._terminal.screenElement, 3, this._colors, this._terminal, bufferService, optionsService) ]; this.dimensions = { scaledCharWidth: null, diff --git a/src/renderer/SelectionRenderLayer.ts b/src/renderer/SelectionRenderLayer.ts index 1735f786..233c4020 100644 --- a/src/renderer/SelectionRenderLayer.ts +++ b/src/renderer/SelectionRenderLayer.ts @@ -7,6 +7,7 @@ import { ITerminal } from '../Types'; import { IRenderDimensions } from 'browser/renderer/Types'; import { BaseRenderLayer } from './BaseRenderLayer'; import { IColorSet } from 'browser/Types'; +import { IBufferService } from 'common/services/Services'; interface ISelectionState { start: [number, number]; @@ -18,7 +19,13 @@ interface ISelectionState { export class SelectionRenderLayer extends BaseRenderLayer { private _state: ISelectionState; - constructor(container: HTMLElement, zIndex: number, colors: IColorSet, terminal: ITerminal) { + constructor( + container: HTMLElement, + zIndex: number, + colors: IColorSet, + terminal: ITerminal, + private readonly _bufferService: IBufferService + ) { super(container, 'selection', zIndex, true, colors, terminal); this._clearState(); } @@ -47,7 +54,7 @@ export class SelectionRenderLayer extends BaseRenderLayer { public onSelectionChanged(start: [number, number], end: [number, number], columnSelectMode: boolean): void { // Selection has not changed - if (!this._didStateChange(start, end, columnSelectMode, this._terminal.buffer.ydisp)) { + if (!this._didStateChange(start, end, columnSelectMode, this._bufferService.buffer.ydisp)) { return; } @@ -61,8 +68,8 @@ export class SelectionRenderLayer extends BaseRenderLayer { } // Translate from buffer position to viewport position - const viewportStartRow = start[1] - this._terminal.buffer.ydisp; - const viewportEndRow = end[1] - this._terminal.buffer.ydisp; + const viewportStartRow = start[1] - this._bufferService.buffer.ydisp; + const viewportEndRow = end[1] - this._bufferService.buffer.ydisp; const viewportCappedStartRow = Math.max(viewportStartRow, 0); const viewportCappedEndRow = Math.min(viewportEndRow, this._terminal.rows - 1); @@ -100,7 +107,7 @@ export class SelectionRenderLayer extends BaseRenderLayer { this._state.start = [start[0], start[1]]; this._state.end = [end[0], end[1]]; this._state.columnSelectMode = columnSelectMode; - this._state.ydisp = this._terminal.buffer.ydisp; + this._state.ydisp = this._bufferService.buffer.ydisp; } private _didStateChange(start: [number, number], end: [number, number], columnSelectMode: boolean, ydisp: number): boolean { From a48260279cd8d0f27b49be1dd95a1b76b499ffb8 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 14 Jul 2019 11:20:25 -0700 Subject: [PATCH 07/56] Fix import in webgl addon --- addons/xterm-addon-webgl/src/WebglRenderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index 41973138..3d41e1b5 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -7,7 +7,7 @@ import { ITerminal } from '../../../src/Types'; import { GlyphRenderer } from './GlyphRenderer'; import { LinkRenderLayer } from './renderLayer/LinkRenderLayer'; import { CursorRenderLayer } from './renderLayer/CursorRenderLayer'; -import { acquireCharAtlas } from 'browser/renderer/atlas/CharAtlasCache'; +import { acquireCharAtlas } from './atlas/CharAtlasCache'; import { WebglCharAtlas } from './atlas/WebglCharAtlas'; import { RectangleRenderer } from './RectangleRenderer'; import { IWebGL2RenderingContext } from './Types'; From e5728ca78f763b44f97742d193069d0bf4320cc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 14 Jul 2019 20:34:51 +0200 Subject: [PATCH 08/56] test script for mouse modes --- fixtures/mouse_modes/test_modes.js | 97 ++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 fixtures/mouse_modes/test_modes.js diff --git a/fixtures/mouse_modes/test_modes.js b/fixtures/mouse_modes/test_modes.js new file mode 100644 index 00000000..98fdfd38 --- /dev/null +++ b/fixtures/mouse_modes/test_modes.js @@ -0,0 +1,97 @@ +let activeEnc = 0; + +const stdin = process.openStdin(); +process.stdin.setRawMode(true); + +// close handler - reset terminal on exit +stdin.addListener('data', function(data) { + if (data[0] === 0x04) { + process.stdin.setRawMode(false); + process.stdout.write('\x1bc'); + process.exit(); + } + if (data[0] === 0x01) { + switchActive(); + printMenu(); + } + console.log('\x1b[100;H\x1b[2A\x1b[2KReport:', data, [data.toString('binary')]); + // filter mouse reports + if (data[0] === 0x1b && data[1] === '['.charCodeAt(0)) { + applyReportData(data); + } +}); + +const BUTTONS = ['left', 'middle', 'right']; + +// encodings: ENCODING_NAME => [sequence, parse_report] +const ENC = { + 'X10' : [ + '\x1b[?9h', + // format: CSI M