diff --git a/addons/xterm-addon-canvas/src/CanvasRenderer.ts b/addons/xterm-addon-canvas/src/CanvasRenderer.ts index 63ed4ed8c..ff92e94bc 100644 --- a/addons/xterm-addon-canvas/src/CanvasRenderer.ts +++ b/addons/xterm-addon-canvas/src/CanvasRenderer.ts @@ -92,13 +92,6 @@ export class CanvasRenderer extends Disposable implements IRenderer { } } - public setColors(colors: IColorSet): void { - // Clear layers and force a full render - for (const l of this._renderLayers) { - l.reset(); - } - } - public handleResize(cols: number, rows: number): void { // Update character and canvas dimensions this._updateDimensions(); diff --git a/addons/xterm-addon-canvas/src/Types.d.ts b/addons/xterm-addon-canvas/src/Types.d.ts index 19b1b426b..1840284f5 100644 --- a/addons/xterm-addon-canvas/src/Types.d.ts +++ b/addons/xterm-addon-canvas/src/Types.d.ts @@ -41,7 +41,6 @@ export interface IRenderer extends IDisposable { */ readonly onRequestRedraw: IEvent; - setColors(colors: IColorSet): void; handleDevicePixelRatioChange(): void; handleResize(cols: number, rows: number): void; handleCharSizeChanged(): void; diff --git a/addons/xterm-addon-webgl/src/RectangleRenderer.ts b/addons/xterm-addon-webgl/src/RectangleRenderer.ts index 62a611017..043687117 100644 --- a/addons/xterm-addon-webgl/src/RectangleRenderer.ts +++ b/addons/xterm-addon-webgl/src/RectangleRenderer.ts @@ -14,6 +14,7 @@ import { RENDER_MODEL_BG_OFFSET, RENDER_MODEL_FG_OFFSET, RENDER_MODEL_INDICIES_P import { Disposable, toDisposable } from 'common/Lifecycle'; import { DIM_OPACITY } from 'browser/renderer/shared/Constants'; import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; +import { IThemeService } from 'browser/services/Services'; const enum VertexAttribLocations { POSITION = 0, @@ -84,9 +85,9 @@ export class RectangleRenderer extends Disposable { constructor( private _terminal: Terminal, - private _colors: ReadonlyColorSet, private _gl: IWebGL2RenderingContext, - private _dimensions: IRenderDimensions + private _dimensions: IRenderDimensions, + private readonly _themeService: IThemeService ) { super(); @@ -133,7 +134,11 @@ export class RectangleRenderer extends Disposable { gl.vertexAttribPointer(VertexAttribLocations.COLOR, 4, gl.FLOAT, false, BYTES_PER_RECTANGLE, 4 * Float32Array.BYTES_PER_ELEMENT); gl.vertexAttribDivisor(VertexAttribLocations.COLOR, 1); - this._updateCachedColors(); + this._updateCachedColors(_themeService.colors); + this.register(this._themeService.onChangeColors(e => { + this._updateCachedColors(e); + this._updateViewportRectangle(); + })); } public render(): void { @@ -155,17 +160,12 @@ export class RectangleRenderer extends Disposable { this._updateViewportRectangle(); } - public setColors(): void { - this._updateCachedColors(); - this._updateViewportRectangle(); - } - public setDimensions(dimensions: IRenderDimensions): void { this._dimensions = dimensions; } - private _updateCachedColors(): void { - this._bgFloat = this._colorToFloat32Array(this._colors.background); + private _updateCachedColors(colors: ReadonlyColorSet): void { + this._bgFloat = this._colorToFloat32Array(colors.background); } private _updateViewportRectangle(): void { @@ -236,27 +236,27 @@ export class RectangleRenderer extends Disposable { switch (fg & Attributes.CM_MASK) { case Attributes.CM_P16: case Attributes.CM_P256: - $rgba = this._colors.ansi[fg & Attributes.PCOLOR_MASK].rgba; + $rgba = this._themeService.colors.ansi[fg & Attributes.PCOLOR_MASK].rgba; break; case Attributes.CM_RGB: $rgba = (fg & Attributes.RGB_MASK) << 8; break; case Attributes.CM_DEFAULT: default: - $rgba = this._colors.foreground.rgba; + $rgba = this._themeService.colors.foreground.rgba; } } else { switch (bg & Attributes.CM_MASK) { case Attributes.CM_P16: case Attributes.CM_P256: - $rgba = this._colors.ansi[bg & Attributes.PCOLOR_MASK].rgba; + $rgba = this._themeService.colors.ansi[bg & Attributes.PCOLOR_MASK].rgba; break; case Attributes.CM_RGB: $rgba = (bg & Attributes.RGB_MASK) << 8; break; case Attributes.CM_DEFAULT: default: - $rgba = this._colors.background.rgba; + $rgba = this._themeService.colors.background.rgba; $isDefault = true; } } diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index 65361f67a..ed99a225b 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -64,15 +64,15 @@ export class WebglRenderer extends Disposable implements IRenderer { ) { super(); - this.register(this._themeService.onChangeColors(e => this._handleColorChange(e))); + this.register(this._themeService.onChangeColors(() => this._handleColorChange())); this._cellColorResolver = new CellColorResolver(this._terminal, this._model.selection, this._decorationService, this._coreBrowserService, this._themeService); this._core = (this._terminal as any)._core; this._renderLayers = [ - new LinkRenderLayer(this._core.screenElement!, 2, this._themeService.colors, this._core, this._coreBrowserService), - new CursorRenderLayer(_terminal, this._core.screenElement!, 3, this._themeService.colors, this._onRequestRedraw, this._coreBrowserService, coreService) + new LinkRenderLayer(this._core.screenElement!, 2, this._terminal, this._core.linkifier2, this._coreBrowserService, this._themeService), + new CursorRenderLayer(_terminal, this._core.screenElement!, 3, this._onRequestRedraw, this._coreBrowserService, coreService, this._themeService) ]; this.dimensions = { scaledCharWidth: 0, @@ -147,15 +147,7 @@ export class WebglRenderer extends Disposable implements IRenderer { return this._charAtlas?.cacheCanvas; } - private _handleColorChange(colors: ReadonlyColorSet): void { - // Clear layers and force a full render - for (const l of this._renderLayers) { - l.setColors(this._terminal, colors); - l.reset(this._terminal); - } - - this._rectangleRenderer.setColors(); - + private _handleColorChange(): void { this._refreshCharAtlas(); // Force a full refresh @@ -254,7 +246,7 @@ export class WebglRenderer extends Disposable implements IRenderer { this._rectangleRenderer?.dispose(); this._glyphRenderer?.dispose(); - this._rectangleRenderer = this.register(new RectangleRenderer(this._terminal, this._themeService.colors, this._gl, this.dimensions)); + this._rectangleRenderer = this.register(new RectangleRenderer(this._terminal, this._gl, this.dimensions, this._themeService)); this._glyphRenderer = this.register(new GlyphRenderer(this._terminal, this._gl, this.dimensions)); // Update dimensions and acquire char atlas diff --git a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts index d4a0a86cd..e99a14643 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/BaseRenderLayer.ts @@ -8,7 +8,7 @@ import { acquireTextureAtlas } from 'browser/renderer/shared/CharAtlasCache'; import { Terminal } from 'xterm'; import { IColorSet, ReadonlyColorSet } from 'browser/Types'; import { TEXT_BASELINE } from 'browser/renderer/shared/Constants'; -import { ICoreBrowserService } from 'browser/services/Services'; +import { ICoreBrowserService, IThemeService } from 'browser/services/Services'; import { IRenderDimensions, ITextureAtlas } from 'browser/renderer/shared/Types'; import { CellData } from 'common/buffer/CellData'; import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils'; @@ -27,12 +27,13 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer protected _charAtlas: ITextureAtlas | undefined; constructor( + terminal: Terminal, private _container: HTMLElement, id: string, zIndex: number, private _alpha: boolean, - protected _colors: ReadonlyColorSet, - protected readonly _coreBrowserService: ICoreBrowserService + protected readonly _coreBrowserService: ICoreBrowserService, + protected readonly _themeService: IThemeService ) { super(); this._canvas = document.createElement('canvas'); @@ -40,6 +41,10 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer this._canvas.style.zIndex = zIndex.toString(); this._initCanvas(); this._container.appendChild(this._canvas); + this.register(this._themeService.onChangeColors(e => { + this._refreshCharAtlas(terminal, e); + this.reset(terminal); + })); this.register(toDisposable(() => { this._canvas.remove(); this._charAtlas?.dispose(); @@ -61,10 +66,6 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer public handleGridChanged(terminal: Terminal, startRow: number, endRow: number): void {} public handleSelectionChanged(terminal: Terminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {} - public setColors(terminal: Terminal, colorSet: ReadonlyColorSet): void { - this._refreshCharAtlas(terminal, colorSet); - } - protected _setTransparency(terminal: Terminal, alpha: boolean): void { // Do nothing when alpha doesn't change if (alpha === this._alpha) { @@ -80,7 +81,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer this._container.replaceChild(this._canvas, oldCanvas); // Regenerate char atlas and force a full redraw - this._refreshCharAtlas(terminal, this._colors); + this._refreshCharAtlas(terminal, this._themeService.colors); this.handleGridChanged(terminal, 0, terminal.rows - 1); } @@ -114,7 +115,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer this._clearAll(); } - this._refreshCharAtlas(terminal, this._colors); + this._refreshCharAtlas(terminal, this._themeService.colors); } public abstract reset(terminal: Terminal): void; @@ -184,7 +185,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer if (this._alpha) { this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height); } else { - this._ctx.fillStyle = this._colors.background.css; + this._ctx.fillStyle = this._themeService.colors.background.css; this._ctx.fillRect(0, 0, this._canvas.width, this._canvas.height); } } @@ -204,7 +205,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer width * this._scaledCellWidth, height * this._scaledCellHeight); } else { - this._ctx.fillStyle = this._colors.background.css; + this._ctx.fillStyle = this._themeService.colors.background.css; this._ctx.fillRect( x * this._scaledCellWidth, y * this._scaledCellHeight, diff --git a/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts index b1718d75c..74801f4eb 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts @@ -10,7 +10,7 @@ import { CellData } from 'common/buffer/CellData'; import { IColorSet, ReadonlyColorSet } from 'browser/Types'; import { IRenderDimensions, IRequestRedrawEvent } from 'browser/renderer/shared/Types'; import { IEventEmitter } from 'common/EventEmitter'; -import { ICoreBrowserService } from 'browser/services/Services'; +import { ICoreBrowserService, IThemeService } from 'browser/services/Services'; import { ICoreService } from 'common/services/Services'; import { toDisposable } from 'common/Lifecycle'; @@ -37,12 +37,12 @@ export class CursorRenderLayer extends BaseRenderLayer { terminal: Terminal, container: HTMLElement, zIndex: number, - colors: ReadonlyColorSet, private _onRequestRefreshRowsEvent: IEventEmitter, coreBrowserService: ICoreBrowserService, - private readonly _coreService: ICoreService + private readonly _coreService: ICoreService, + themeService: IThemeService ) { - super(container, 'cursor', zIndex, true, colors, coreBrowserService); + super(terminal, container, 'cursor', zIndex, true, coreBrowserService, themeService); this._state = { x: 0, y: 0, @@ -146,7 +146,7 @@ export class CursorRenderLayer extends BaseRenderLayer { if (!this._coreBrowserService.isFocused) { this._clearCursor(); this._ctx.save(); - this._ctx.fillStyle = this._colors.cursor.css; + this._ctx.fillStyle = this._themeService.colors.cursor.css; const cursorStyle = terminal.options.cursorStyle; if (cursorStyle && cursorStyle !== 'block') { this._cursorRenderers[cursorStyle](terminal, cursorX, viewportRelativeCursorY, this._cell); @@ -211,30 +211,30 @@ export class CursorRenderLayer extends BaseRenderLayer { private _renderBarCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); - this._ctx.fillStyle = this._colors.cursor.css; + this._ctx.fillStyle = this._themeService.colors.cursor.css; this._fillLeftLineAtCell(x, y, terminal.options.cursorWidth); this._ctx.restore(); } private _renderBlockCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); - this._ctx.fillStyle = this._colors.cursor.css; + this._ctx.fillStyle = this._themeService.colors.cursor.css; this._fillCells(x, y, cell.getWidth(), 1); - this._ctx.fillStyle = this._colors.cursorAccent.css; + this._ctx.fillStyle = this._themeService.colors.cursorAccent.css; this._fillCharTrueColor(terminal, cell, x, y); this._ctx.restore(); } private _renderUnderlineCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); - this._ctx.fillStyle = this._colors.cursor.css; + this._ctx.fillStyle = this._themeService.colors.cursor.css; this._fillBottomLineAtCells(x, y); this._ctx.restore(); } private _renderBlurCursor(terminal: Terminal, x: number, y: number, cell: ICellData): void { this._ctx.save(); - this._ctx.strokeStyle = this._colors.cursor.css; + this._ctx.strokeStyle = this._themeService.colors.cursor.css; this._strokeRectAtCell(x, y, cell.getWidth(), 1); this._ctx.restore(); } diff --git a/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts index 9c841843a..2d2af192c 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/LinkRenderLayer.ts @@ -3,14 +3,13 @@ * @license MIT */ +import { is256Color } from 'browser/renderer/shared/CharAtlasUtils'; +import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants'; +import { IRenderDimensions } from 'browser/renderer/shared/Types'; +import { ICoreBrowserService, IThemeService } from 'browser/services/Services'; +import { ILinkifier2, ILinkifierEvent, ITerminal } from 'browser/Types'; import { Terminal } from 'xterm'; import { BaseRenderLayer } from './BaseRenderLayer'; -import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants'; -import { ITerminal, IColorSet, ILinkifierEvent, ReadonlyColorSet } from 'browser/Types'; -import { IRenderDimensions } from 'browser/renderer/shared/Types'; -import { ICoreBrowserService } from 'browser/services/Services'; -import { is256Color } from 'browser/renderer/shared/CharAtlasUtils'; -import { toDisposable } from 'common/Lifecycle'; export class LinkRenderLayer extends BaseRenderLayer { private _state: ILinkifierEvent | undefined; @@ -18,14 +17,15 @@ export class LinkRenderLayer extends BaseRenderLayer { constructor( container: HTMLElement, zIndex: number, - colors: ReadonlyColorSet, - terminal: ITerminal, - coreBrowserService: ICoreBrowserService + terminal: Terminal, + linkifier2: ILinkifier2, + coreBrowserService: ICoreBrowserService, + themeService: IThemeService ) { - super(container, 'link', zIndex, true, colors, coreBrowserService); + super(terminal, container, 'link', zIndex, true, coreBrowserService, themeService); - this.register(terminal.linkifier2.onShowLinkUnderline(e => this._handleShowLinkUnderline(e))); - this.register(terminal.linkifier2.onHideLinkUnderline(e => this._handleHideLinkUnderline(e))); + this.register(linkifier2.onShowLinkUnderline(e => this._handleShowLinkUnderline(e))); + this.register(linkifier2.onHideLinkUnderline(e => this._handleHideLinkUnderline(e))); } public resize(terminal: Terminal, dim: IRenderDimensions): void { @@ -52,12 +52,12 @@ export class LinkRenderLayer extends BaseRenderLayer { private _handleShowLinkUnderline(e: ILinkifierEvent): void { if (e.fg === INVERTED_DEFAULT_COLOR) { - this._ctx.fillStyle = this._colors.background.css; + this._ctx.fillStyle = this._themeService.colors.background.css; } else if (e.fg !== undefined && is256Color(e.fg)) { // 256 color support - this._ctx.fillStyle = this._colors.ansi[e.fg!].css; + this._ctx.fillStyle = this._themeService.colors.ansi[e.fg!].css; } else { - this._ctx.fillStyle = this._colors.foreground.css; + this._ctx.fillStyle = this._themeService.colors.foreground.css; } if (e.y1 === e.y2) { diff --git a/addons/xterm-addon-webgl/src/renderLayer/Types.ts b/addons/xterm-addon-webgl/src/renderLayer/Types.ts index 32013ee35..089680ca5 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/Types.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/Types.ts @@ -28,11 +28,6 @@ export interface IRenderLayer extends IDisposable { */ handleOptionsChanged(terminal: Terminal): void; - /** - * Called when the theme changes. - */ - setColors(terminal: Terminal, colorSet: ReadonlyColorSet): void; - /** * Called when the data in the grid has changed (or needs to be rendered * again). diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index 467c4544d..a08378954 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -280,9 +280,6 @@ export class MockRenderer implements IRenderer { throw new Error('Method not implemented.'); } public dimensions!: IRenderDimensions; - public setColors(colors: IColorSet): void { - throw new Error('Method not implemented.'); - } public registerDecoration(decorationOptions: IDecorationOptions): IDecoration { throw new Error('Method not implemented.'); } @@ -408,9 +405,6 @@ export class MockRenderService implements IRenderService { public setRenderer(renderer: IRenderer): void { throw new Error('Method not implemented.'); } - public setColors(colors: IColorSet): void { - throw new Error('Method not implemented.'); - } public handleDevicePixelRatioChange(): void { throw new Error('Method not implemented.'); }