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 {