diff --git a/addons/xterm-addon-canvas/src/BaseRenderLayer.ts b/addons/xterm-addon-canvas/src/BaseRenderLayer.ts index 2a9e09bac5..da7ae91250 100644 --- a/addons/xterm-addon-canvas/src/BaseRenderLayer.ts +++ b/addons/xterm-addon-canvas/src/BaseRenderLayer.ts @@ -19,8 +19,9 @@ import { ICellData } from 'common/Types'; import { Terminal } from 'xterm'; import { IRenderLayer } from './Types'; import { CellColorResolver } from 'browser/renderer/shared/CellColorResolver'; +import { Disposable } from 'common/Lifecycle'; -export abstract class BaseRenderLayer implements IRenderLayer { +export abstract class BaseRenderLayer extends Disposable implements IRenderLayer { private _canvas: HTMLCanvasElement; protected _ctx!: CanvasRenderingContext2D; private _scaledCharWidth: number = 0; @@ -51,6 +52,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { protected readonly _decorationService: IDecorationService, protected readonly _coreBrowserService: ICoreBrowserService ) { + super(); this._cellColorResolver = new CellColorResolver(this._terminal, this._colors, this._selectionModel, this._decorationService, this._coreBrowserService); this._canvas = document.createElement('canvas'); this._canvas.classList.add(`xterm-${id}-layer`); diff --git a/addons/xterm-addon-canvas/src/CanvasAddon.ts b/addons/xterm-addon-canvas/src/CanvasAddon.ts index f90dad1553..0378670bb8 100644 --- a/addons/xterm-addon-canvas/src/CanvasAddon.ts +++ b/addons/xterm-addon-canvas/src/CanvasAddon.ts @@ -9,20 +9,26 @@ import { CanvasRenderer } from './CanvasRenderer'; import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services'; import { ITerminalAddon, Terminal } from 'xterm'; import { EventEmitter, forwardEvent } from 'common/EventEmitter'; +import { Disposable, toDisposable } from 'common/Lifecycle'; -export class CanvasAddon implements ITerminalAddon { +export class CanvasAddon extends Disposable implements ITerminalAddon { private _terminal?: Terminal; private _renderer?: CanvasRenderer; - private readonly _onChangeTextureAtlas = new EventEmitter(); + private readonly _onChangeTextureAtlas = this.register(new EventEmitter()); public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event; + public get textureAtlas(): HTMLCanvasElement | undefined { + return this._renderer?.textureAtlas; + } + public activate(terminal: Terminal): void { const core = (terminal as any)._core; if (!terminal.element) { - core.onWillOpen(() => this.activate(terminal)); + this.register(core.onWillOpen(() => this.activate(terminal))); return; } + this._terminal = terminal; const bufferService: IBufferService = core._bufferService; const renderService: IRenderService = core._renderService; @@ -35,24 +41,17 @@ export class CanvasAddon implements ITerminalAddon { const colors: IColorSet = core._colorManager.colors; const screenElement: HTMLElement = core.screenElement; const linkifier = core.linkifier2; + this._renderer = new CanvasRenderer(terminal, colors, screenElement, linkifier, bufferService, charSizeService, optionsService, characterJoinerService, coreService, coreBrowserService, decorationService); - forwardEvent(this._renderer.onChangeTextureAtlas, this._onChangeTextureAtlas); + this.register(forwardEvent(this._renderer.onChangeTextureAtlas, this._onChangeTextureAtlas)); renderService.setRenderer(this._renderer); renderService.onResize(bufferService.cols, bufferService.rows); - } - - public dispose(): void { - if (!this._terminal) { - throw new Error('Cannot dispose CanvasAddon because it is activated'); - } - const renderService: IRenderService = (this._terminal as any)._core._renderService; - renderService.setRenderer((this._terminal as any)._core._createRenderer()); - renderService.onResize(this._terminal.cols, this._terminal.rows); - this._renderer?.dispose(); - this._renderer = undefined; - } - public get textureAtlas(): HTMLCanvasElement | undefined { - return this._renderer?.textureAtlas; + this.register(toDisposable(() => { + renderService.setRenderer((this._terminal as any)._core._createRenderer()); + renderService.onResize(terminal.cols, terminal.rows); + this._renderer?.dispose(); + this._renderer = undefined; + })); } } diff --git a/addons/xterm-addon-canvas/src/CanvasRenderer.ts b/addons/xterm-addon-canvas/src/CanvasRenderer.ts index eb1c085ff8..868bedd6b7 100644 --- a/addons/xterm-addon-canvas/src/CanvasRenderer.ts +++ b/addons/xterm-addon-canvas/src/CanvasRenderer.ts @@ -24,9 +24,9 @@ export class CanvasRenderer extends Disposable implements IRenderer { public dimensions: IRenderDimensions; - private readonly _onRequestRedraw = new EventEmitter(); + private readonly _onRequestRedraw = this.register(new EventEmitter()); public readonly onRequestRedraw = this._onRequestRedraw.event; - private readonly _onChangeTextureAtlas = new EventEmitter(); + private readonly _onChangeTextureAtlas = this.register(new EventEmitter()); public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event; constructor( diff --git a/addons/xterm-addon-canvas/src/CursorRenderLayer.ts b/addons/xterm-addon-canvas/src/CursorRenderLayer.ts index 78dc543222..9c3ce718c6 100644 --- a/addons/xterm-addon-canvas/src/CursorRenderLayer.ts +++ b/addons/xterm-addon-canvas/src/CursorRenderLayer.ts @@ -12,6 +12,7 @@ import { IBufferService, IOptionsService, ICoreService, IDecorationService } fro import { IEventEmitter } from 'common/EventEmitter'; import { ICoreBrowserService } from 'browser/services/Services'; import { Terminal } from 'xterm'; +import { toDisposable } from 'common/Lifecycle'; interface ICursorState { x: number; @@ -57,14 +58,10 @@ export class CursorRenderLayer extends BaseRenderLayer { 'block': this._renderBlockCursor.bind(this), 'underline': this._renderUnderlineCursor.bind(this) }; - } - - public dispose(): void { - if (this._cursorBlinkStateManager) { - this._cursorBlinkStateManager.dispose(); + this.register(toDisposable(() => { + this._cursorBlinkStateManager?.dispose(); this._cursorBlinkStateManager = undefined; - } - super.dispose(); + })); } public resize(dim: IRenderDimensions): void { diff --git a/addons/xterm-addon-canvas/src/LinkRenderLayer.ts b/addons/xterm-addon-canvas/src/LinkRenderLayer.ts index db622b3fe7..da9ebe16b2 100644 --- a/addons/xterm-addon-canvas/src/LinkRenderLayer.ts +++ b/addons/xterm-addon-canvas/src/LinkRenderLayer.ts @@ -28,8 +28,8 @@ export class LinkRenderLayer extends BaseRenderLayer { ) { super(terminal, container, 'link', zIndex, true, colors, bufferService, optionsService, decorationService, coreBrowserService); - linkifier2.onShowLinkUnderline(e => this._onShowLinkUnderline(e)); - linkifier2.onHideLinkUnderline(e => this._onHideLinkUnderline(e)); + this.register(linkifier2.onShowLinkUnderline(e => this._onShowLinkUnderline(e))); + this.register(linkifier2.onHideLinkUnderline(e => this._onHideLinkUnderline(e))); } public resize(dim: IRenderDimensions): void { diff --git a/addons/xterm-addon-canvas/src/TextRenderLayer.ts b/addons/xterm-addon-canvas/src/TextRenderLayer.ts index 8d80514b43..8d5508e688 100644 --- a/addons/xterm-addon-canvas/src/TextRenderLayer.ts +++ b/addons/xterm-addon-canvas/src/TextRenderLayer.ts @@ -293,19 +293,4 @@ export class TextRenderLayer extends BaseRenderLayer { this._characterOverlapCache[chars] = overlaps; return overlaps; } - - /** - * Clear the charcater at the cell specified. - * @param x The column of the char. - * @param y The row of the char. - */ - // private _clearChar(x: number, y: number): void { - // let colsToClear = 1; - // // Clear the adjacent character if it was wide - // const state = this._state.cache[x][y]; - // if (state && state[CHAR_DATA_WIDTH_INDEX] === 2) { - // colsToClear = 2; - // } - // this.clearCells(x, y, colsToClear, 1); - // } } diff --git a/addons/xterm-addon-canvas/src/Types.d.ts b/addons/xterm-addon-canvas/src/Types.d.ts index 0527eae9db..75c5ccc962 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; - dispose(): void; setColors(colors: IColorSet): void; onDevicePixelRatioChange(): void; onResize(cols: number, rows: number): void;