Reorganize src/common into platform (base, encoding, data, buffer, parser, input), integration (services, terminal), and public API layers. - Move core utilities to common/base/ - Move TextDecoder to common/encoding/ - Move Types, CircularList, Color, TaskQueue, SortedList to common/services/ - Move CoreTerminal, InputHandler, WindowsMode to common/terminal/ - Define ICharset in common/data/Charsets.ts (re-exported from Types) - Update imports across src/, addons/, and test/ - Add per-layer tsconfig.json files and REARCHITECTURE.md - Root common/tsconfig.json remains the composite build entry Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
98 lines
2.7 KiB
TypeScript
98 lines
2.7 KiB
TypeScript
/**
|
|
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
|
* @license MIT
|
|
*/
|
|
|
|
import { ICoreBrowserService } from 'browser/services/Services';
|
|
import { Disposable, toDisposable } from 'common/base/Lifecycle';
|
|
import { IOptionsService } from 'common/services/Services';
|
|
|
|
export class TextBlinkStateManager extends Disposable {
|
|
private _intervalDuration: number = 0;
|
|
private _interval: number | undefined;
|
|
private _blinkOn: boolean = true;
|
|
private _needsBlinkInViewport: boolean = false;
|
|
private _isViewportVisible: boolean = true;
|
|
|
|
constructor(
|
|
private readonly _renderCallback: () => void,
|
|
private readonly _coreBrowserService: ICoreBrowserService,
|
|
private readonly _optionsService: IOptionsService
|
|
) {
|
|
super();
|
|
this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {
|
|
this.setIntervalDuration(duration);
|
|
}));
|
|
this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);
|
|
this._register(toDisposable(() => this._clearInterval()));
|
|
}
|
|
|
|
public get isBlinkOn(): boolean {
|
|
return this._blinkOn;
|
|
}
|
|
|
|
public get isEnabled(): boolean {
|
|
return this._intervalDuration > 0;
|
|
}
|
|
|
|
public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {
|
|
if (this._needsBlinkInViewport === needsBlinkInViewport) {
|
|
return;
|
|
}
|
|
|
|
this._needsBlinkInViewport = needsBlinkInViewport;
|
|
this._updateIntervalState();
|
|
}
|
|
|
|
public setViewportVisible(isVisible: boolean): void {
|
|
if (this._isViewportVisible === isVisible) {
|
|
return;
|
|
}
|
|
|
|
this._isViewportVisible = isVisible;
|
|
this._updateIntervalState();
|
|
}
|
|
|
|
public setIntervalDuration(duration: number): void {
|
|
if (duration === this._intervalDuration) {
|
|
return;
|
|
}
|
|
|
|
this._intervalDuration = duration;
|
|
this._clearInterval();
|
|
this._updateIntervalState();
|
|
}
|
|
|
|
private _updateIntervalState(): void {
|
|
const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;
|
|
if (shouldBlink) {
|
|
if (this._interval !== undefined) {
|
|
return;
|
|
}
|
|
const wasBlinkOn = this._blinkOn;
|
|
this._blinkOn = true;
|
|
this._interval = this._coreBrowserService.window.setInterval(() => {
|
|
this._blinkOn = !this._blinkOn;
|
|
this._renderCallback();
|
|
}, this._intervalDuration);
|
|
if (!wasBlinkOn) {
|
|
this._renderCallback();
|
|
}
|
|
return;
|
|
}
|
|
|
|
this._clearInterval();
|
|
if (!this._blinkOn) {
|
|
this._blinkOn = true;
|
|
this._renderCallback();
|
|
}
|
|
}
|
|
|
|
private _clearInterval(): void {
|
|
if (this._interval !== undefined) {
|
|
this._coreBrowserService.window.clearInterval(this._interval);
|
|
this._interval = undefined;
|
|
}
|
|
}
|
|
}
|