From ec26820ea6e543aa69a09af8285d91387e8820bb Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 17 May 2022 11:23:33 -0700 Subject: [PATCH] Fix circular dependency mouseservice <-> renderservice --- src/browser/renderer/BaseRenderLayer.ts | 29 ++++++++++++++++---- src/browser/renderer/CursorRenderLayer.ts | 7 ++--- src/browser/renderer/LinkRenderLayer.ts | 6 ++-- src/browser/renderer/Renderer.ts | 4 +++ src/browser/renderer/SelectionRenderLayer.ts | 8 +++--- src/browser/renderer/TextRenderLayer.ts | 7 ++--- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/src/browser/renderer/BaseRenderLayer.ts b/src/browser/renderer/BaseRenderLayer.ts index 7bcc6881..447f5ade 100644 --- a/src/browser/renderer/BaseRenderLayer.ts +++ b/src/browser/renderer/BaseRenderLayer.ts @@ -18,7 +18,6 @@ import { isPowerlineGlyph, throwIfFalsy } from 'browser/renderer/RendererUtils'; import { channels, color, rgba } from 'common/Color'; import { removeElementFromParent } from 'browser/Dom'; import { tryDrawCustomChar } from 'browser/renderer/CustomGlyphs'; -import { ISelectionService } from 'browser/services/Services'; export abstract class BaseRenderLayer implements IRenderLayer { private _canvas: HTMLCanvasElement; @@ -30,6 +29,10 @@ export abstract class BaseRenderLayer implements IRenderLayer { private _scaledCharLeft: number = 0; private _scaledCharTop: number = 0; + private _selectionStart: [number, number] | undefined; + private _selectionEnd: [number, number] | undefined; + private _columnSelectMode: boolean = false; + protected _charAtlas: BaseCharAtlas | undefined; /** @@ -54,8 +57,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { private _rendererId: number, protected readonly _bufferService: IBufferService, protected readonly _optionsService: IOptionsService, - protected readonly _decorationService: IDecorationService, - protected readonly _selectionService: ISelectionService + protected readonly _decorationService: IDecorationService ) { this._canvas = document.createElement('canvas'); this._canvas.classList.add(`xterm-${id}-layer`); @@ -82,7 +84,12 @@ export abstract class BaseRenderLayer implements IRenderLayer { public onFocus(): void {} public onCursorMove(): void {} public onGridChanged(startRow: number, endRow: number): void {} - public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {} + + public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void { + this._selectionStart = start; + this._selectionEnd = end; + this._columnSelectMode = columnSelectMode; + } public setColors(colorSet: IColorSet): void { this._refreshCharAtlas(colorSet); @@ -461,7 +468,7 @@ export abstract class BaseRenderLayer implements IRenderLayer { // Apply selection foreground if applicable if (!isTop) { - if (this._colors.selectionForeground && this._selectionService.isCellInSelection(x, y)) { + if (this._colors.selectionForeground && this._isCellInSelection(x, y)) { fgOverride = this._colors.selectionForeground.rgba; } } @@ -555,5 +562,17 @@ export abstract class BaseRenderLayer implements IRenderLayer { return this._colors.foreground.rgba; } } + + private _isCellInSelection(x: number, y: number): boolean { + const start = this._selectionStart; + const end = this._selectionEnd; + if (!start || !end) { + return false; + } + return (y > start[1] && y < end[1]) || + (start[1] === end[1] && y === start[1] && x >= start[0] && x < end[0]) || + (start[1] < end[1] && y === end[1] && x < end[0]) || + (start[1] < end[1] && y === start[1] && x >= start[0]); + } } diff --git a/src/browser/renderer/CursorRenderLayer.ts b/src/browser/renderer/CursorRenderLayer.ts index 6405390e..3fa576a9 100644 --- a/src/browser/renderer/CursorRenderLayer.ts +++ b/src/browser/renderer/CursorRenderLayer.ts @@ -10,7 +10,7 @@ import { CellData } from 'common/buffer/CellData'; import { IColorSet } from 'browser/Types'; import { IBufferService, IOptionsService, ICoreService, IDecorationService } from 'common/services/Services'; import { IEventEmitter } from 'common/EventEmitter'; -import { ICoreBrowserService, ISelectionService } from 'browser/services/Services'; +import { ICoreBrowserService } from 'browser/services/Services'; interface ICursorState { x: number; @@ -41,10 +41,9 @@ export class CursorRenderLayer extends BaseRenderLayer { @IOptionsService optionsService: IOptionsService, @ICoreService private readonly _coreService: ICoreService, @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService, - @IDecorationService decorationService: IDecorationService, - @ISelectionService selectionService: ISelectionService + @IDecorationService decorationService: IDecorationService ) { - super(container, 'cursor', zIndex, true, colors, rendererId, bufferService, optionsService, decorationService, selectionService); + super(container, 'cursor', zIndex, true, colors, rendererId, bufferService, optionsService, decorationService); this._state = { x: 0, y: 0, diff --git a/src/browser/renderer/LinkRenderLayer.ts b/src/browser/renderer/LinkRenderLayer.ts index 4d350f4d..15086d9a 100644 --- a/src/browser/renderer/LinkRenderLayer.ts +++ b/src/browser/renderer/LinkRenderLayer.ts @@ -9,7 +9,6 @@ import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/atlas/Constants'; import { is256Color } from 'browser/renderer/atlas/CharAtlasUtils'; import { IColorSet, ILinkifierEvent, ILinkifier, ILinkifier2 } from 'browser/Types'; import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services'; -import { ISelectionService } from 'browser/services/Services'; export class LinkRenderLayer extends BaseRenderLayer { private _state: ILinkifierEvent | undefined; @@ -23,10 +22,9 @@ export class LinkRenderLayer extends BaseRenderLayer { linkifier2: ILinkifier2, @IBufferService bufferService: IBufferService, @IOptionsService optionsService: IOptionsService, - @IDecorationService decorationService: IDecorationService, - @ISelectionService selectionService: ISelectionService + @IDecorationService decorationService: IDecorationService ) { - super(container, 'link', zIndex, true, colors, rendererId, bufferService, optionsService, decorationService, selectionService); + super(container, 'link', zIndex, true, colors, rendererId, bufferService, optionsService, decorationService); linkifier.onShowLinkUnderline(e => this._onShowLinkUnderline(e)); linkifier.onHideLinkUnderline(e => this._onHideLinkUnderline(e)); diff --git a/src/browser/renderer/Renderer.ts b/src/browser/renderer/Renderer.ts index 8dfe09c9..8bc32278 100644 --- a/src/browser/renderer/Renderer.ts +++ b/src/browser/renderer/Renderer.ts @@ -119,6 +119,10 @@ export class Renderer extends Disposable implements IRenderer { public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void { this._runOperation(l => l.onSelectionChanged(start, end, columnSelectMode)); + // Selection foreground requires a full re-render + if (this._colors.selectionForeground) { + this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }); + } } public onCursorMove(): void { diff --git a/src/browser/renderer/SelectionRenderLayer.ts b/src/browser/renderer/SelectionRenderLayer.ts index 60c53eaf..ce4fe071 100644 --- a/src/browser/renderer/SelectionRenderLayer.ts +++ b/src/browser/renderer/SelectionRenderLayer.ts @@ -7,7 +7,6 @@ import { IRenderDimensions } from 'browser/renderer/Types'; import { BaseRenderLayer } from 'browser/renderer/BaseRenderLayer'; import { IColorSet } from 'browser/Types'; import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services'; -import { ISelectionService } from 'browser/services/Services'; interface ISelectionState { start?: [number, number]; @@ -26,10 +25,9 @@ export class SelectionRenderLayer extends BaseRenderLayer { rendererId: number, @IBufferService bufferService: IBufferService, @IOptionsService optionsService: IOptionsService, - @IDecorationService decorationService: IDecorationService, - @ISelectionService selectionService: ISelectionService + @IDecorationService decorationService: IDecorationService ) { - super(container, 'selection', zIndex, true, colors, rendererId, bufferService, optionsService, decorationService, selectionService); + super(container, 'selection', zIndex, true, colors, rendererId, bufferService, optionsService, decorationService); this._clearState(); } @@ -56,6 +54,8 @@ export class SelectionRenderLayer extends BaseRenderLayer { } public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void { + super.onSelectionChanged(start, end, columnSelectMode); + // Selection has not changed if (!this._didStateChange(start, end, columnSelectMode, this._bufferService.buffer.ydisp)) { return; diff --git a/src/browser/renderer/TextRenderLayer.ts b/src/browser/renderer/TextRenderLayer.ts index 97c7e6f6..ef5a9b62 100644 --- a/src/browser/renderer/TextRenderLayer.ts +++ b/src/browser/renderer/TextRenderLayer.ts @@ -12,7 +12,7 @@ import { NULL_CELL_CODE, Content } from 'common/buffer/Constants'; import { IColorSet } from 'browser/Types'; import { CellData } from 'common/buffer/CellData'; import { IOptionsService, IBufferService, IDecorationService } from 'common/services/Services'; -import { ICharacterJoinerService, ISelectionService } from 'browser/services/Services'; +import { ICharacterJoinerService } from 'browser/services/Services'; import { JoinedCellData } from 'browser/services/CharacterJoinerService'; /** @@ -38,10 +38,9 @@ export class TextRenderLayer extends BaseRenderLayer { @IBufferService bufferService: IBufferService, @IOptionsService optionsService: IOptionsService, @ICharacterJoinerService private readonly _characterJoinerService: ICharacterJoinerService, - @IDecorationService decorationService: IDecorationService, - @ISelectionService selectionService: ISelectionService + @IDecorationService decorationService: IDecorationService ) { - super(container, 'text', zIndex, alpha, colors, rendererId, bufferService, optionsService, decorationService, selectionService); + super(container, 'text', zIndex, alpha, colors, rendererId, bufferService, optionsService, decorationService); this._state = new GridCache(); }