diff --git a/addons/xterm-addon-webgl/src/WebglRenderer.ts b/addons/xterm-addon-webgl/src/WebglRenderer.ts index 62a10187..24e55fed 100644 --- a/addons/xterm-addon-webgl/src/WebglRenderer.ts +++ b/addons/xterm-addon-webgl/src/WebglRenderer.ts @@ -337,8 +337,8 @@ export class WebglRenderer extends Disposable implements IRenderer { // Nothing has changed, no updates needed if (this._model.cells[i] === code && - this._model.cells[i + RENDER_MODEL_BG_OFFSET] === cell.bg && - this._model.cells[i + RENDER_MODEL_FG_OFFSET] === cell.fg) { + this._model.cells[i + RENDER_MODEL_BG_OFFSET] === cell.bg && + this._model.cells[i + RENDER_MODEL_FG_OFFSET] === cell.fg) { continue; } diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index e2a29f02..abf985b7 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -55,7 +55,7 @@ import { CoreTerminal } from 'common/CoreTerminal'; import { color, rgba } from 'browser/Color'; import { CharacterJoinerService } from 'browser/services/CharacterJoinerService'; import { toRgbString } from 'common/input/XParseColor'; -import { DecorationsService, IDecorationsService } from 'browser/services/DecorationsService'; +import { DecorationService, IDecorationService } from 'browser/services/DecorationsService'; // Let it work inside Node.js for automated testing purposes. const document: Document = (typeof window !== 'undefined') ? window.document : null as any; @@ -81,7 +81,7 @@ export class Terminal extends CoreTerminal implements ITerminal { private _charSizeService: ICharSizeService | undefined; private _mouseService: IMouseService | undefined; private _renderService: IRenderService | undefined; - private _decorationsService: IDecorationsService | undefined; + private _decorationsService: IDecorationService | undefined; private _characterJoinerService: ICharacterJoinerService | undefined; private _selectionService: ISelectionService | undefined; private _soundService: ISoundService | undefined; @@ -515,7 +515,7 @@ export class Terminal extends CoreTerminal implements ITerminal { this.register(this._renderService.onRenderedBufferChange(e => this._onRender.fire(e))); this.onResize(e => this._renderService!.resize(e.cols, e.rows)); - this._decorationsService = this.register(this._instantiationService.createInstance(DecorationsService, this.screenElement)); + this._decorationsService = this.register(this._instantiationService.createInstance(DecorationService, this.screenElement)); this._compositionView = document.createElement('div'); this._compositionView.classList.add('composition-view'); @@ -1007,12 +1007,13 @@ export class Terminal extends CoreTerminal implements ITerminal { } public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined { - if (!this._decorationsService) { - throw new Error('cannot register a decoration without a decorations service'); + // Disallow decorations on the alt buffer + if (this.buffer !== this.buffers.normal) { + return undefined; } - - return this._decorationsService.registerDecoration(decorationOptions); + return this._decorationsService!.registerDecoration(decorationOptions); } + /** * Gets whether the terminal has an active selection. */ diff --git a/src/browser/TestUtils.test.ts b/src/browser/TestUtils.test.ts index d6d4b95e..10a1435b 100644 --- a/src/browser/TestUtils.test.ts +++ b/src/browser/TestUtils.test.ts @@ -286,6 +286,9 @@ export class MockRenderer implements IRenderer { public setColors(colors: IColorSet): void { throw new Error('Method not implemented.'); } + public registerDecoration(decorationOptions: IDecorationOptions): IDecoration { + throw new Error('Method not implemented.'); + } public onResize(cols: number, rows: number): void { } public onCharSizeChanged(): void { } public onBlur(): void { } @@ -296,9 +299,6 @@ export class MockRenderer implements IRenderer { public onDevicePixelRatioChange(): void { } public clear(): void { } public renderRows(start: number, end: number): void { } - public registerDecoration(decorationOptions: IDecorationOptions): IDecoration { - throw new Error('Method not implemented.'); - } } export class MockViewport implements IViewport { diff --git a/src/browser/renderer/Types.d.ts b/src/browser/renderer/Types.d.ts index ab6f8df1..6818a926 100644 --- a/src/browser/renderer/Types.d.ts +++ b/src/browser/renderer/Types.d.ts @@ -6,7 +6,6 @@ import { IDisposable } from 'common/Types'; import { IColorSet } from 'browser/Types'; import { IEvent } from 'common/EventEmitter'; -import { IDecorationOptions, IDecoration } from 'xterm'; export interface IRenderDimensions { scaledCharWidth: number; diff --git a/src/browser/renderer/dom/DomRenderer.ts b/src/browser/renderer/dom/DomRenderer.ts index 6c9f5e2f..ee283399 100644 --- a/src/browser/renderer/dom/DomRenderer.ts +++ b/src/browser/renderer/dom/DomRenderer.ts @@ -13,7 +13,6 @@ import { IOptionsService, IBufferService, IInstantiationService } from 'common/s import { EventEmitter, IEvent } from 'common/EventEmitter'; import { color } from 'browser/Color'; import { removeElementFromParent } from 'browser/Dom'; -import { IDecorationOptions, IDecoration } from 'xterm'; const TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-'; const ROW_CONTAINER_CLASS = 'xterm-rows'; diff --git a/src/browser/services/DecorationsService.ts b/src/browser/services/DecorationsService.ts index 610355de..36aabf9a 100644 --- a/src/browser/services/DecorationsService.ts +++ b/src/browser/services/DecorationsService.ts @@ -11,13 +11,13 @@ import { IBufferService } from 'common/services/Services'; import { IDisposable } from 'common/Types'; import { IDecorationOptions, IDecoration, IMarker } from 'xterm'; -export interface IDecorationsService extends IDisposable { +export interface IDecorationService extends IDisposable { registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined; refresh(): void; dispose(): void; } -export class DecorationsService extends Disposable implements IDecorationsService { +export class DecorationService extends Disposable implements IDecorationService { private _decorations: Decoration[] = []; private _animationFrame: number | undefined; @@ -67,7 +67,7 @@ export class DecorationsService extends Disposable implements IDecorationsServic } } -export const IDecorationsService = createDecorator('DecorationsService'); +export const IDecorationService = createDecorator('DecorationsService'); class Decoration extends Disposable implements IDecoration { private static _nextId = 1; private _marker: IMarker; @@ -117,7 +117,7 @@ class Decoration extends Disposable implements IDecoration { this._element.style.height = `${this._decorationOptions.height}px`; this._element.style.top = `${(this.marker.line - this._bufferService.buffers.active.ydisp) * this._renderService.dimensions.scaledCellHeight}px`; if (this._decorationOptions.x && this._decorationOptions.x < 0) { - throw new Error(`Decoration options x value cannot be negative, but was ${this._decorationOptions.x}`); + throw new Error(`Decoration options x value cannot be negative, but was ${this._decorationOptions.x}.`); } if (this._decorationOptions.anchor === 'right') { @@ -128,17 +128,11 @@ class Decoration extends Disposable implements IDecoration { } private _resolveDimensions(): void { - if (this._renderService.dimensions.scaledCellWidth) { - this._decorationOptions.width = this._decorationOptions.width ? this._decorationOptions.width * this._renderService.dimensions.scaledCellWidth : this._renderService.dimensions.scaledCellWidth; - } else { - throw new Error('unknown cell width'); - } - - if (this._renderService.dimensions.scaledCellHeight) { - this._decorationOptions.height = this._decorationOptions.height ? this._decorationOptions.height * this._renderService.dimensions.scaledCellHeight : this._renderService.dimensions.scaledCellHeight; - } else { - throw new Error('unknown cell height'); + if (!this._renderService.dimensions.scaledCellWidth || !this._renderService.dimensions.scaledCellHeight) { + throw new Error(`Cannot resolve dimensions for decoration when scaled cell dimensions are undefined ${this._renderService.dimensions}.`); } + this._decorationOptions.width = this._decorationOptions.width ? this._decorationOptions.width * this._renderService.dimensions.scaledCellWidth : this._renderService.dimensions.scaledCellWidth; + this._decorationOptions.height = this._decorationOptions.height ? this._decorationOptions.height * this._renderService.dimensions.scaledCellHeight : this._renderService.dimensions.scaledCellHeight; } private _render(): void { diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index 0b3db559..91b992f9 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -936,7 +936,8 @@ declare module 'xterm' { * (EXPERIMENTAL) Adds a decoration to the terminal using * @param decorationOptions, which takes a marker and an optional anchor, * width, height, and x offset from the anchor. Returns the decoration or - * undefined if the marker has already been disposed of. + * undefined if the alt buffer is active or the marker has already been disposed of. + * @throws if the @param decorationOptions includes a negative x offset. */ registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined;