Skip to content

Commit 8a00898

Browse files
committed
Implement blink rendering
Fixes #944
1 parent 8f9045e commit 8a00898

9 files changed

Lines changed: 176 additions & 42 deletions

File tree

addons/addon-webgl/src/WebglRenderer.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IThemeS
1313
import { CharData, IBufferLine, ICellData } from 'common/Types';
1414
import { AttributeData } from 'common/buffer/AttributeData';
1515
import { CellData } from 'common/buffer/CellData';
16-
import { Attributes, Content, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants';
16+
import { Attributes, Content, FgFlags, NULL_CELL_CHAR, NULL_CELL_CODE } from 'common/buffer/Constants';
17+
import { TextBlinkStateManager } from 'browser/renderer/shared/TextBlinkStateManager';
1718
import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
1819
import { Terminal } from '@xterm/xterm';
1920
import { GlyphRenderer } from './GlyphRenderer';
@@ -30,6 +31,7 @@ import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
3031
export class WebglRenderer extends Disposable implements IRenderer {
3132
private _renderLayers: IRenderLayer[];
3233
private _cursorBlinkStateManager: MutableDisposable<CursorBlinkStateManager> = new MutableDisposable();
34+
private _textBlinkStateManager: TextBlinkStateManager;
3335
private _charAtlasDisposable = this._register(new MutableDisposable());
3436
private _charAtlas: ITextureAtlas | undefined;
3537
private _devicePixelRatio: number;
@@ -105,6 +107,12 @@ export class WebglRenderer extends Disposable implements IRenderer {
105107
this._updateDimensions();
106108
this._updateCursorBlink();
107109
this._register(_optionsService.onOptionChange(() => this._handleOptionsChanged()));
110+
this._textBlinkStateManager = new TextBlinkStateManager(
111+
() => this._requestRedrawViewport(),
112+
this._coreBrowserService
113+
);
114+
this._textBlinkStateManager.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);
115+
this._register(toDisposable(() => this._textBlinkStateManager.dispose()));
108116

109117
this._deviceMaxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);
110118

@@ -250,6 +258,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
250258
this._updateDimensions();
251259
this._refreshCharAtlas();
252260
this._updateCursorBlink();
261+
this._textBlinkStateManager.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);
253262
}
254263

255264
/**
@@ -506,6 +515,10 @@ export class WebglRenderer extends Disposable implements IRenderer {
506515
}
507516
}
508517

518+
if (this._textBlinkStateManager.isEnabled && !this._textBlinkStateManager.isBlinkOn && cell.isBlink()) {
519+
this._cellColorResolver.result.fg |= FgFlags.INVISIBLE;
520+
}
521+
509522
if (code !== NULL_CELL_CODE) {
510523
this._model.lineLengths[y] = x + 1;
511524
}

src/browser/renderer/dom/DomRenderer.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { WidthCache } from 'browser/renderer/dom/WidthCache';
88
import { INVERTED_DEFAULT_COLOR, RendererConstants } from 'browser/renderer/shared/Constants';
99
import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
1010
import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRenderModel';
11+
import { TextBlinkStateManager } from 'browser/renderer/shared/TextBlinkStateManager';
1112
import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from 'browser/renderer/shared/Types';
1213
import { ICharSizeService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
1314
import { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from 'browser/Types';
@@ -45,10 +46,12 @@ export class DomRenderer extends Disposable implements IRenderer {
4546
private _widthCache: WidthCache;
4647
private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();
4748
private _cursorBlinkStateManager: CursorBlinkStateManager;
49+
private _textBlinkStateManager: TextBlinkStateManager;
4850

4951
public dimensions: IRenderDimensions;
5052

51-
public readonly onRequestRedraw = this._register(new Emitter<IRequestRedrawEvent>()).event;
53+
private readonly _onRequestRedraw = this._register(new Emitter<IRequestRedrawEvent>());
54+
public readonly onRequestRedraw = this._onRequestRedraw.event;
5255

5356
constructor(
5457
private readonly _terminal: ITerminal,
@@ -95,6 +98,12 @@ export class DomRenderer extends Disposable implements IRenderer {
9598
this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);
9699
this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));
97100
this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));
101+
this._textBlinkStateManager = new TextBlinkStateManager(
102+
() => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),
103+
this._coreBrowserService
104+
);
105+
this._textBlinkStateManager.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);
106+
this._register(toDisposable(() => this._textBlinkStateManager.dispose()));
98107

99108
this._register(toDisposable(() => {
100109
this._element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass);
@@ -193,6 +202,9 @@ export class DomRenderer extends Disposable implements IRenderer {
193202
`}` +
194203
`${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +
195204
` font-style: italic;` +
205+
`}` +
206+
`${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +
207+
` visibility: hidden;` +
196208
`}`;
197209
// Blink animation
198210
const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;
@@ -436,6 +448,7 @@ export class DomRenderer extends Disposable implements IRenderer {
436448
this._optionsService.rawOptions.fontWeightBold
437449
);
438450
this._setDefaultSpacing();
451+
this._textBlinkStateManager.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);
439452
}
440453

441454
public clear(): void {
@@ -476,6 +489,7 @@ export class DomRenderer extends Disposable implements IRenderer {
476489
cursorInactiveStyle,
477490
cursorX,
478491
cursorBlink,
492+
this._textBlinkStateManager.isBlinkOn,
479493
this.dimensions.css.cell.width,
480494
this._widthCache,
481495
-1,
@@ -545,6 +559,7 @@ export class DomRenderer extends Disposable implements IRenderer {
545559
cursorInactiveStyle,
546560
cursorX,
547561
cursorBlink,
562+
this._textBlinkStateManager.isBlinkOn,
548563
this.dimensions.css.cell.width,
549564
this._widthCache,
550565
enabled ? (i === y ? x : 0) : -1,

0 commit comments

Comments
 (0)