@xterm/xterm 6.1.0-beta.28 → 6.1.0-beta.280
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -38
- package/css/xterm.css +29 -22
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +8 -34
- package/lib/xterm.mjs.map +4 -4
- package/package.json +56 -45
- package/src/browser/AccessibilityManager.ts +18 -13
- package/src/browser/Clipboard.ts +8 -5
- package/src/browser/ColorContrastCache.ts +3 -3
- package/src/browser/CoreBrowserTerminal.ts +179 -348
- package/src/browser/Dom.ts +178 -0
- package/src/browser/Linkifier.ts +14 -14
- package/src/browser/OscLinkProvider.ts +86 -18
- package/src/browser/RenderDebouncer.ts +7 -9
- package/src/browser/TimeBasedDebouncer.ts +12 -5
- package/src/browser/Types.ts +16 -14
- package/src/browser/Viewport.ts +58 -23
- package/src/browser/decorations/BufferDecorationRenderer.ts +3 -3
- package/src/browser/decorations/ColorZoneStore.ts +1 -1
- package/src/browser/decorations/OverviewRulerRenderer.ts +36 -20
- package/src/browser/input/CompositionHelper.ts +47 -11
- package/src/browser/input/Mouse.ts +5 -9
- package/src/browser/input/MoveToCell.ts +3 -3
- package/src/browser/public/Terminal.ts +33 -36
- package/src/browser/renderer/dom/DomRenderer.ts +265 -89
- package/src/browser/renderer/dom/DomRendererRowFactory.ts +34 -27
- package/src/browser/renderer/dom/WidthCache.ts +57 -55
- package/src/browser/renderer/shared/Constants.ts +7 -0
- package/src/browser/renderer/shared/RendererUtils.ts +1 -1
- package/src/browser/renderer/shared/SelectionRenderModel.ts +2 -2
- package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
- package/src/browser/renderer/shared/Types.ts +10 -4
- package/src/browser/scrollable/abstractScrollbar.ts +300 -0
- package/src/browser/scrollable/fastDomNode.ts +126 -0
- package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
- package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
- package/src/browser/scrollable/mouseEvent.ts +292 -0
- package/src/browser/scrollable/scrollable.ts +486 -0
- package/src/browser/scrollable/scrollableElement.ts +581 -0
- package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
- package/src/browser/scrollable/scrollbarArrow.ts +110 -0
- package/src/browser/scrollable/scrollbarState.ts +246 -0
- package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
- package/src/browser/scrollable/touch.ts +485 -0
- package/src/browser/scrollable/verticalScrollbar.ts +143 -0
- package/src/browser/scrollable/widget.ts +23 -0
- package/src/browser/selection/SelectionModel.ts +1 -1
- package/src/browser/services/CharSizeService.ts +4 -4
- package/src/browser/services/CharacterJoinerService.ts +13 -11
- package/src/browser/services/CoreBrowserService.ts +7 -5
- package/src/browser/services/KeyboardService.ts +67 -0
- package/src/browser/services/LinkProviderService.ts +3 -3
- package/src/browser/services/MouseCoordsService.ts +47 -0
- package/src/browser/services/MouseService.ts +619 -23
- package/src/browser/services/RenderService.ts +33 -21
- package/src/browser/services/SelectionService.ts +72 -54
- package/src/browser/services/Services.ts +44 -21
- package/src/browser/services/ThemeService.ts +9 -9
- package/src/common/Async.ts +141 -0
- package/src/common/CircularList.ts +24 -3
- package/src/common/Color.ts +13 -5
- package/src/common/CoreTerminal.ts +61 -35
- package/src/common/Event.ts +118 -0
- package/src/common/InputHandler.ts +286 -105
- package/src/common/Lifecycle.ts +113 -0
- package/src/common/Platform.ts +15 -5
- package/src/common/SortedList.ts +8 -4
- package/src/common/StringBuilder.ts +67 -0
- package/src/common/TaskQueue.ts +17 -8
- package/src/common/Types.ts +68 -206
- package/src/common/Version.ts +1 -1
- package/src/common/WindowsMode.ts +2 -2
- package/src/common/buffer/AttributeData.ts +3 -2
- package/src/common/buffer/Buffer.ts +47 -32
- package/src/common/buffer/BufferLine.ts +175 -100
- package/src/common/buffer/BufferLineStringCache.ts +69 -0
- package/src/common/buffer/BufferReflow.ts +7 -4
- package/src/common/buffer/BufferSet.ts +13 -9
- package/src/common/buffer/CellData.ts +61 -4
- package/src/common/buffer/Constants.ts +13 -13
- package/src/common/buffer/Marker.ts +4 -4
- package/src/common/buffer/Types.ts +153 -3
- package/src/common/data/Charsets.ts +4 -7
- package/src/common/data/EscapeSequences.ts +71 -70
- package/src/common/input/Keyboard.ts +17 -10
- package/src/common/input/KittyKeyboard.ts +526 -0
- package/src/common/input/TextDecoder.ts +3 -3
- package/src/common/input/UnicodeV6.ts +3 -2
- package/src/common/input/Win32InputMode.ts +297 -0
- package/src/common/input/WriteBuffer.ts +108 -39
- package/src/common/input/XParseColor.ts +2 -2
- package/src/common/parser/ApcParser.ts +196 -0
- package/src/common/parser/Constants.ts +14 -4
- package/src/common/parser/DcsParser.ts +15 -16
- package/src/common/parser/EscapeSequenceParser.ts +214 -72
- package/src/common/parser/OscParser.ts +14 -15
- package/src/common/parser/Params.ts +31 -12
- package/src/common/parser/Types.ts +40 -30
- package/src/common/public/BufferApiView.ts +3 -3
- package/src/common/public/BufferLineApiView.ts +4 -4
- package/src/common/public/BufferNamespaceApi.ts +5 -5
- package/src/common/public/ParserApi.ts +5 -2
- package/src/common/public/UnicodeApi.ts +1 -1
- package/src/common/services/BufferService.ts +17 -13
- package/src/common/services/CharsetService.ts +6 -2
- package/src/common/services/CoreService.ts +23 -10
- package/src/common/services/DecorationService.ts +260 -15
- package/src/common/services/InstantiationService.ts +2 -2
- package/src/common/services/LogService.ts +2 -32
- package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +22 -133
- package/src/common/services/OptionsService.ts +17 -7
- package/src/common/services/OscLinkService.ts +3 -2
- package/src/common/services/ServiceRegistry.ts +14 -8
- package/src/common/services/Services.ts +54 -50
- package/src/common/services/UnicodeService.ts +6 -11
- package/typings/xterm.d.ts +329 -34
- package/src/common/Clone.ts +0 -23
- package/src/common/TypedArrayUtils.ts +0 -17
- package/src/vs/base/browser/browser.ts +0 -141
- package/src/vs/base/browser/canIUse.ts +0 -49
- package/src/vs/base/browser/dom.ts +0 -2369
- package/src/vs/base/browser/fastDomNode.ts +0 -316
- package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
- package/src/vs/base/browser/iframe.ts +0 -135
- package/src/vs/base/browser/keyboardEvent.ts +0 -213
- package/src/vs/base/browser/mouseEvent.ts +0 -229
- package/src/vs/base/browser/touch.ts +0 -372
- package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
- package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
- package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
- package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
- package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
- package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
- package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
- package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
- package/src/vs/base/browser/ui/widget.ts +0 -57
- package/src/vs/base/browser/window.ts +0 -14
- package/src/vs/base/common/arrays.ts +0 -887
- package/src/vs/base/common/arraysFind.ts +0 -202
- package/src/vs/base/common/assert.ts +0 -71
- package/src/vs/base/common/async.ts +0 -1992
- package/src/vs/base/common/cancellation.ts +0 -148
- package/src/vs/base/common/charCode.ts +0 -450
- package/src/vs/base/common/collections.ts +0 -140
- package/src/vs/base/common/decorators.ts +0 -130
- package/src/vs/base/common/equals.ts +0 -146
- package/src/vs/base/common/errors.ts +0 -303
- package/src/vs/base/common/event.ts +0 -1778
- package/src/vs/base/common/functional.ts +0 -32
- package/src/vs/base/common/hash.ts +0 -316
- package/src/vs/base/common/iterator.ts +0 -159
- package/src/vs/base/common/keyCodes.ts +0 -526
- package/src/vs/base/common/keybindings.ts +0 -284
- package/src/vs/base/common/lazy.ts +0 -47
- package/src/vs/base/common/lifecycle.ts +0 -801
- package/src/vs/base/common/linkedList.ts +0 -142
- package/src/vs/base/common/map.ts +0 -202
- package/src/vs/base/common/numbers.ts +0 -98
- package/src/vs/base/common/observable.ts +0 -76
- package/src/vs/base/common/observableInternal/api.ts +0 -31
- package/src/vs/base/common/observableInternal/autorun.ts +0 -281
- package/src/vs/base/common/observableInternal/base.ts +0 -489
- package/src/vs/base/common/observableInternal/debugName.ts +0 -145
- package/src/vs/base/common/observableInternal/derived.ts +0 -428
- package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
- package/src/vs/base/common/observableInternal/logging.ts +0 -328
- package/src/vs/base/common/observableInternal/promise.ts +0 -209
- package/src/vs/base/common/observableInternal/utils.ts +0 -610
- package/src/vs/base/common/platform.ts +0 -281
- package/src/vs/base/common/scrollable.ts +0 -522
- package/src/vs/base/common/sequence.ts +0 -34
- package/src/vs/base/common/stopwatch.ts +0 -43
- package/src/vs/base/common/strings.ts +0 -557
- package/src/vs/base/common/symbols.ts +0 -9
- package/src/vs/base/common/uint.ts +0 -59
- package/src/vs/patches/nls.ts +0 -90
- package/src/vs/typings/base-common.d.ts +0 -20
- package/src/vs/typings/require.d.ts +0 -42
- package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
- package/src/vs/typings/vscode-globals-product.d.ts +0 -33
|
@@ -3,26 +3,31 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { DomRendererRowFactory, RowCss } from '
|
|
7
|
-
import { WidthCache } from '
|
|
8
|
-
import { INVERTED_DEFAULT_COLOR } from '
|
|
9
|
-
import { createRenderDimensions } from '
|
|
10
|
-
import { createSelectionRenderModel } from '
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
6
|
+
import { DomRendererRowFactory, RowCss } from './DomRendererRowFactory';
|
|
7
|
+
import { WidthCache } from './WidthCache';
|
|
8
|
+
import { INVERTED_DEFAULT_COLOR, RendererConstants } from '../shared/Constants';
|
|
9
|
+
import { createRenderDimensions } from '../shared/RendererUtils';
|
|
10
|
+
import { createSelectionRenderModel } from '../shared/SelectionRenderModel';
|
|
11
|
+
import { TextBlinkStateManager } from '../shared/TextBlinkStateManager';
|
|
12
|
+
import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from '../shared/Types';
|
|
13
|
+
import { ICharSizeService, ICoreBrowserService, IThemeService } from '../../services/Services';
|
|
14
|
+
import { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from '../../Types';
|
|
15
|
+
import { color } from '../../../common/Color';
|
|
16
|
+
import { Disposable, toDisposable } from '../../../common/Lifecycle';
|
|
17
|
+
import { IBufferService, ICoreService, IInstantiationService, IOptionsService } from '../../../common/services/Services';
|
|
18
|
+
import { Emitter } from '../../../common/Event';
|
|
19
|
+
import { addDisposableListener } from '../../Dom';
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
const enum Constants {
|
|
23
|
+
TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-',
|
|
24
|
+
ROW_CONTAINER_CLASS = 'xterm-rows',
|
|
25
|
+
FG_CLASS_PREFIX = 'xterm-fg-',
|
|
26
|
+
BG_CLASS_PREFIX = 'xterm-bg-',
|
|
27
|
+
FOCUS_CLASS = 'xterm-focus',
|
|
28
|
+
SELECTION_CLASS = 'xterm-selection',
|
|
29
|
+
CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle'
|
|
30
|
+
}
|
|
26
31
|
|
|
27
32
|
let nextTerminalId = 1;
|
|
28
33
|
|
|
@@ -42,10 +47,18 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
42
47
|
private _selectionContainer: HTMLElement;
|
|
43
48
|
private _widthCache: WidthCache;
|
|
44
49
|
private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();
|
|
50
|
+
private _lastSelectionStart: [number, number] | undefined;
|
|
51
|
+
private _lastSelectionEnd: [number, number] | undefined;
|
|
52
|
+
private _lastSelectionColumnMode: boolean = false;
|
|
53
|
+
private _cursorBlinkStateManager: CursorBlinkStateManager;
|
|
54
|
+
private _textBlinkStateManager: TextBlinkStateManager;
|
|
55
|
+
private _rowHasBlinkingCells: boolean[] = [];
|
|
56
|
+
private _rowHasBlinkingCellsCount: number = 0;
|
|
45
57
|
|
|
46
58
|
public dimensions: IRenderDimensions;
|
|
47
59
|
|
|
48
|
-
|
|
60
|
+
private readonly _onRequestRedraw = this._register(new Emitter<IRequestRedrawEvent>());
|
|
61
|
+
public readonly onRequestRedraw = this._onRequestRedraw.event;
|
|
49
62
|
|
|
50
63
|
constructor(
|
|
51
64
|
private readonly _terminal: ITerminal,
|
|
@@ -65,12 +78,12 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
65
78
|
) {
|
|
66
79
|
super();
|
|
67
80
|
this._rowContainer = this._document.createElement('div');
|
|
68
|
-
this._rowContainer.classList.add(ROW_CONTAINER_CLASS);
|
|
81
|
+
this._rowContainer.classList.add(Constants.ROW_CONTAINER_CLASS);
|
|
69
82
|
this._rowContainer.style.lineHeight = 'normal';
|
|
70
83
|
this._rowContainer.setAttribute('aria-hidden', 'true');
|
|
71
84
|
this._refreshRowElements(this._bufferService.cols, this._bufferService.rows);
|
|
72
85
|
this._selectionContainer = this._document.createElement('div');
|
|
73
|
-
this._selectionContainer.classList.add(SELECTION_CLASS);
|
|
86
|
+
this._selectionContainer.classList.add(Constants.SELECTION_CLASS);
|
|
74
87
|
this._selectionContainer.setAttribute('aria-hidden', 'true');
|
|
75
88
|
|
|
76
89
|
this.dimensions = createRenderDimensions();
|
|
@@ -82,15 +95,24 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
82
95
|
|
|
83
96
|
this._rowFactory = instantiationService.createInstance(DomRendererRowFactory, document);
|
|
84
97
|
|
|
85
|
-
this._element.classList.add(TERMINAL_CLASS_PREFIX + this._terminalClass);
|
|
98
|
+
this._element.classList.add(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);
|
|
86
99
|
this._screenElement.appendChild(this._rowContainer);
|
|
87
100
|
this._screenElement.appendChild(this._selectionContainer);
|
|
88
101
|
|
|
89
102
|
this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));
|
|
90
103
|
this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));
|
|
91
104
|
|
|
105
|
+
this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);
|
|
106
|
+
this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));
|
|
107
|
+
this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));
|
|
108
|
+
this._textBlinkStateManager = this._register(new TextBlinkStateManager(
|
|
109
|
+
() => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),
|
|
110
|
+
this._coreBrowserService,
|
|
111
|
+
this._optionsService
|
|
112
|
+
));
|
|
113
|
+
|
|
92
114
|
this._register(toDisposable(() => {
|
|
93
|
-
this._element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass);
|
|
115
|
+
this._element.classList.remove(Constants.TERMINAL_CLASS_PREFIX + this._terminalClass);
|
|
94
116
|
|
|
95
117
|
// Outside influences such as React unmounts may manipulate the DOM before our disposal.
|
|
96
118
|
// https://github.com/xtermjs/xterm.js/issues/2960
|
|
@@ -101,7 +123,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
101
123
|
this._dimensionsStyleElement.remove();
|
|
102
124
|
}));
|
|
103
125
|
|
|
104
|
-
this._widthCache = new WidthCache(
|
|
126
|
+
this._widthCache = new WidthCache();
|
|
105
127
|
this._widthCache.setFont(
|
|
106
128
|
this._optionsService.rawOptions.fontFamily,
|
|
107
129
|
this._optionsService.rawOptions.fontSize,
|
|
@@ -140,7 +162,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
140
162
|
}
|
|
141
163
|
|
|
142
164
|
const styles =
|
|
143
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} span {` +
|
|
165
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +
|
|
144
166
|
` display: inline-block;` + // TODO: find workaround for inline-block (creates ~20% render penalty)
|
|
145
167
|
` height: 100%;` +
|
|
146
168
|
` vertical-align: top;` +
|
|
@@ -161,19 +183,22 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
161
183
|
|
|
162
184
|
// Base CSS
|
|
163
185
|
let styles =
|
|
164
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} {` +
|
|
186
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} {` +
|
|
165
187
|
// Disabling pointer events circumvents a browser behavior that prevents `click` events from
|
|
166
188
|
// being delivered if the target element is replaced during the click. This happened due to
|
|
167
189
|
// refresh() being called during the mousedown handler to start a selection.
|
|
168
190
|
` pointer-events: none;` +
|
|
169
191
|
` color: ${colors.foreground.css};` +
|
|
192
|
+
`}`;
|
|
193
|
+
styles +=
|
|
194
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}, ${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} span {` +
|
|
170
195
|
` font-family: ${this._optionsService.rawOptions.fontFamily};` +
|
|
171
196
|
` font-size: ${this._optionsService.rawOptions.fontSize}px;` +
|
|
172
197
|
` font-kerning: none;` +
|
|
173
198
|
` white-space: pre` +
|
|
174
199
|
`}`;
|
|
175
200
|
styles +=
|
|
176
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .xterm-dim {` +
|
|
201
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .xterm-dim {` +
|
|
177
202
|
` color: ${color.multiplyOpacity(colors.foreground, 0.5).css};` +
|
|
178
203
|
`}`;
|
|
179
204
|
// Text styles
|
|
@@ -186,6 +211,9 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
186
211
|
`}` +
|
|
187
212
|
`${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +
|
|
188
213
|
` font-style: italic;` +
|
|
214
|
+
`}` +
|
|
215
|
+
`${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +
|
|
216
|
+
` visibility: hidden;` +
|
|
189
217
|
`}`;
|
|
190
218
|
// Blink animation
|
|
191
219
|
const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;
|
|
@@ -216,66 +244,70 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
216
244
|
`}`;
|
|
217
245
|
// Cursor
|
|
218
246
|
styles +=
|
|
219
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +
|
|
247
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +
|
|
220
248
|
` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +
|
|
221
249
|
`}` +
|
|
222
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +
|
|
250
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +
|
|
223
251
|
` animation: ${blinkAnimationBarId} 1s step-end infinite;` +
|
|
224
252
|
`}` +
|
|
225
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
|
|
253
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
|
|
226
254
|
` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +
|
|
227
255
|
`}` +
|
|
256
|
+
// Disable cursor blinking when idle
|
|
257
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS}.${Constants.CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` +
|
|
258
|
+
` animation: none !important;` +
|
|
259
|
+
`}` +
|
|
228
260
|
// !important helps fix an issue where the cursor will not render on top of the selection,
|
|
229
261
|
// however it's very hard to fix this issue and retain the blink animation without the use of
|
|
230
262
|
// !important. So this edge case fails when cursor blink is on.
|
|
231
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
|
|
263
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
|
|
232
264
|
` background-color: ${colors.cursor.css};` +
|
|
233
265
|
` color: ${colors.cursorAccent.css};` +
|
|
234
266
|
`}` +
|
|
235
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +
|
|
267
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +
|
|
236
268
|
` background-color: ${colors.cursor.css} !important;` +
|
|
237
269
|
` color: ${colors.cursorAccent.css} !important;` +
|
|
238
270
|
`}` +
|
|
239
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +
|
|
271
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +
|
|
240
272
|
` outline: 1px solid ${colors.cursor.css};` +
|
|
241
273
|
` outline-offset: -1px;` +
|
|
242
274
|
`}` +
|
|
243
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +
|
|
275
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +
|
|
244
276
|
` box-shadow: ${this._optionsService.rawOptions.cursorWidth}px 0 0 ${colors.cursor.css} inset;` +
|
|
245
277
|
`}` +
|
|
246
|
-
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +
|
|
278
|
+
`${this._terminalSelector} .${Constants.ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +
|
|
247
279
|
` border-bottom: 1px ${colors.cursor.css};` +
|
|
248
280
|
` border-bottom-style: solid;` +
|
|
249
281
|
` height: calc(100% - 1px);` +
|
|
250
282
|
`}`;
|
|
251
283
|
// Selection
|
|
252
284
|
styles +=
|
|
253
|
-
`${this._terminalSelector} .${SELECTION_CLASS} {` +
|
|
285
|
+
`${this._terminalSelector} .${Constants.SELECTION_CLASS} {` +
|
|
254
286
|
` position: absolute;` +
|
|
255
287
|
` top: 0;` +
|
|
256
288
|
` left: 0;` +
|
|
257
289
|
` z-index: 1;` +
|
|
258
290
|
` pointer-events: none;` +
|
|
259
291
|
`}` +
|
|
260
|
-
`${this._terminalSelector}.focus .${SELECTION_CLASS} div {` +
|
|
292
|
+
`${this._terminalSelector}.focus .${Constants.SELECTION_CLASS} div {` +
|
|
261
293
|
` position: absolute;` +
|
|
262
294
|
` background-color: ${colors.selectionBackgroundOpaque.css};` +
|
|
263
295
|
`}` +
|
|
264
|
-
`${this._terminalSelector} .${SELECTION_CLASS} div {` +
|
|
296
|
+
`${this._terminalSelector} .${Constants.SELECTION_CLASS} div {` +
|
|
265
297
|
` position: absolute;` +
|
|
266
298
|
` background-color: ${colors.selectionInactiveBackgroundOpaque.css};` +
|
|
267
299
|
`}`;
|
|
268
300
|
// Colors
|
|
269
301
|
for (const [i, c] of colors.ansi.entries()) {
|
|
270
302
|
styles +=
|
|
271
|
-
`${this._terminalSelector} .${FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +
|
|
272
|
-
`${this._terminalSelector} .${FG_CLASS_PREFIX}${i}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(c, 0.5).css}; }` +
|
|
273
|
-
`${this._terminalSelector} .${BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;
|
|
303
|
+
`${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i} { color: ${c.css}; }` +
|
|
304
|
+
`${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${i}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(c, 0.5).css}; }` +
|
|
305
|
+
`${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${i} { background-color: ${c.css}; }`;
|
|
274
306
|
}
|
|
275
307
|
styles +=
|
|
276
|
-
`${this._terminalSelector} .${FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${color.opaque(colors.background).css}; }` +
|
|
277
|
-
`${this._terminalSelector} .${FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(color.opaque(colors.background), 0.5).css}; }` +
|
|
278
|
-
`${this._terminalSelector} .${BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${colors.foreground.css}; }`;
|
|
308
|
+
`${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { color: ${color.opaque(colors.background).css}; }` +
|
|
309
|
+
`${this._terminalSelector} .${Constants.FG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR}.${RowCss.DIM_CLASS} { color: ${color.multiplyOpacity(color.opaque(colors.background), 0.5).css}; }` +
|
|
310
|
+
`${this._terminalSelector} .${Constants.BG_CLASS_PREFIX}${INVERTED_DEFAULT_COLOR} { background-color: ${colors.foreground.css}; }`;
|
|
279
311
|
|
|
280
312
|
this._themeStyleElement.textContent = styles;
|
|
281
313
|
}
|
|
@@ -307,10 +339,14 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
307
339
|
const row = this._document.createElement('div');
|
|
308
340
|
this._rowContainer.appendChild(row);
|
|
309
341
|
this._rowElements.push(row);
|
|
342
|
+
this._rowHasBlinkingCells.push(false);
|
|
310
343
|
}
|
|
311
344
|
// Remove excess elements
|
|
312
345
|
while (this._rowElements.length > rows) {
|
|
313
346
|
this._rowContainer.removeChild(this._rowElements.pop()!);
|
|
347
|
+
if (this._rowHasBlinkingCells.pop()) {
|
|
348
|
+
this._rowHasBlinkingCellsCount--;
|
|
349
|
+
}
|
|
314
350
|
}
|
|
315
351
|
}
|
|
316
352
|
|
|
@@ -327,61 +363,105 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
327
363
|
}
|
|
328
364
|
|
|
329
365
|
public handleBlur(): void {
|
|
330
|
-
this._rowContainer.classList.remove(FOCUS_CLASS);
|
|
366
|
+
this._rowContainer.classList.remove(Constants.FOCUS_CLASS);
|
|
367
|
+
this._cursorBlinkStateManager.pause();
|
|
331
368
|
this.renderRows(0, this._bufferService.rows - 1);
|
|
332
369
|
}
|
|
333
370
|
|
|
334
371
|
public handleFocus(): void {
|
|
335
|
-
this._rowContainer.classList.add(FOCUS_CLASS);
|
|
372
|
+
this._rowContainer.classList.add(Constants.FOCUS_CLASS);
|
|
373
|
+
this._cursorBlinkStateManager.resume();
|
|
336
374
|
this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y);
|
|
337
375
|
}
|
|
338
376
|
|
|
377
|
+
public handleViewportVisibilityChange(isVisible: boolean): void {
|
|
378
|
+
this._textBlinkStateManager.setViewportVisible(isVisible);
|
|
379
|
+
}
|
|
380
|
+
|
|
339
381
|
public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {
|
|
382
|
+
const rows = this._bufferService.rows;
|
|
383
|
+
|
|
340
384
|
// Remove all selections
|
|
341
385
|
this._selectionContainer.replaceChildren();
|
|
342
386
|
this._rowFactory.handleSelectionChanged(start, end, columnSelectMode);
|
|
343
|
-
this.renderRows(0, this._bufferService.rows - 1);
|
|
344
387
|
|
|
345
|
-
//
|
|
388
|
+
// Determine old selection viewport band
|
|
389
|
+
let oldViewportStart = 0;
|
|
390
|
+
let oldViewportEnd = -1;
|
|
391
|
+
if (this._lastSelectionStart && this._lastSelectionEnd) {
|
|
392
|
+
this._selectionRenderModel.update(this._terminal, this._lastSelectionStart, this._lastSelectionEnd, this._lastSelectionColumnMode);
|
|
393
|
+
if (this._selectionRenderModel.hasSelection) {
|
|
394
|
+
oldViewportStart = this._selectionRenderModel.viewportCappedStartRow;
|
|
395
|
+
oldViewportEnd = this._selectionRenderModel.viewportCappedEndRow;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Determine new selection viewport band and create overlays
|
|
400
|
+
let newViewportStart = 0;
|
|
401
|
+
let newViewportEnd = -1;
|
|
346
402
|
if (!start || !end) {
|
|
347
403
|
return;
|
|
348
404
|
}
|
|
349
|
-
|
|
350
405
|
this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);
|
|
351
|
-
if (
|
|
352
|
-
|
|
406
|
+
if (this._selectionRenderModel.hasSelection) {
|
|
407
|
+
const viewportStartRow = this._selectionRenderModel.viewportStartRow;
|
|
408
|
+
const viewportEndRow = this._selectionRenderModel.viewportEndRow;
|
|
409
|
+
const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;
|
|
410
|
+
const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;
|
|
411
|
+
|
|
412
|
+
newViewportStart = viewportCappedStartRow;
|
|
413
|
+
newViewportEnd = viewportCappedEndRow;
|
|
414
|
+
|
|
415
|
+
// Create the selections
|
|
416
|
+
const documentFragment = this._document.createDocumentFragment();
|
|
417
|
+
|
|
418
|
+
if (columnSelectMode) {
|
|
419
|
+
const isXFlipped = start[0] > end[0];
|
|
420
|
+
documentFragment.appendChild(
|
|
421
|
+
this._createSelectionElement(viewportCappedStartRow, isXFlipped ? end[0] : start[0], isXFlipped ? start[0] : end[0], viewportCappedEndRow - viewportCappedStartRow + 1)
|
|
422
|
+
);
|
|
423
|
+
} else {
|
|
424
|
+
// Draw first row
|
|
425
|
+
const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;
|
|
426
|
+
const endCol = viewportCappedStartRow === viewportEndRow ? end[0] : this._bufferService.cols;
|
|
427
|
+
documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));
|
|
428
|
+
// Draw middle rows
|
|
429
|
+
const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;
|
|
430
|
+
documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._bufferService.cols, middleRowsCount));
|
|
431
|
+
// Draw final row
|
|
432
|
+
if (viewportCappedStartRow !== viewportCappedEndRow) {
|
|
433
|
+
// Only draw viewportEndRow if it's not the same as viewporttartRow
|
|
434
|
+
const finalEndCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;
|
|
435
|
+
documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, finalEndCol));
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
this._selectionContainer.appendChild(documentFragment);
|
|
353
439
|
}
|
|
354
440
|
|
|
355
|
-
//
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
// Draw first row
|
|
371
|
-
const startCol = viewportStartRow === viewportCappedStartRow ? start[0] : 0;
|
|
372
|
-
const endCol = viewportCappedStartRow === viewportEndRow ? end[0] : this._bufferService.cols;
|
|
373
|
-
documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow, startCol, endCol));
|
|
374
|
-
// Draw middle rows
|
|
375
|
-
const middleRowsCount = viewportCappedEndRow - viewportCappedStartRow - 1;
|
|
376
|
-
documentFragment.appendChild(this._createSelectionElement(viewportCappedStartRow + 1, 0, this._bufferService.cols, middleRowsCount));
|
|
377
|
-
// Draw final row
|
|
378
|
-
if (viewportCappedStartRow !== viewportCappedEndRow) {
|
|
379
|
-
// Only draw viewportEndRow if it's not the same as viewporttartRow
|
|
380
|
-
const endCol = viewportEndRow === viewportCappedEndRow ? end[0] : this._bufferService.cols;
|
|
381
|
-
documentFragment.appendChild(this._createSelectionElement(viewportCappedEndRow, 0, endCol));
|
|
441
|
+
// Compute minimal row range to redraw
|
|
442
|
+
let renderStartRow = Math.min(oldViewportStart, newViewportStart);
|
|
443
|
+
let renderEndRow = Math.max(oldViewportEnd, newViewportEnd);
|
|
444
|
+
|
|
445
|
+
if (renderEndRow >= 0) {
|
|
446
|
+
// Clamp to viewport
|
|
447
|
+
renderStartRow = Math.max(renderStartRow, 0);
|
|
448
|
+
renderEndRow = Math.min(renderEndRow, rows - 1);
|
|
449
|
+
|
|
450
|
+
// Ensure cursor row is included when a selection is present
|
|
451
|
+
const buffer = this._bufferService.buffer;
|
|
452
|
+
const cursorViewportRow = buffer.y;
|
|
453
|
+
if (this._selectionRenderModel.hasSelection && cursorViewportRow >= 0 && cursorViewportRow < rows) {
|
|
454
|
+
renderStartRow = Math.min(renderStartRow, cursorViewportRow);
|
|
455
|
+
renderEndRow = Math.max(renderEndRow, cursorViewportRow);
|
|
382
456
|
}
|
|
457
|
+
|
|
458
|
+
this.renderRows(renderStartRow, renderEndRow);
|
|
383
459
|
}
|
|
384
|
-
|
|
460
|
+
|
|
461
|
+
// Update last selection state
|
|
462
|
+
this._lastSelectionStart = start;
|
|
463
|
+
this._lastSelectionEnd = end;
|
|
464
|
+
this._lastSelectionColumnMode = columnSelectMode;
|
|
385
465
|
}
|
|
386
466
|
|
|
387
467
|
/**
|
|
@@ -406,7 +486,8 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
406
486
|
}
|
|
407
487
|
|
|
408
488
|
public handleCursorMove(): void {
|
|
409
|
-
//
|
|
489
|
+
// Reset idle timer on cursor movement (which happens on input)
|
|
490
|
+
this._cursorBlinkStateManager.restartBlinkAnimation();
|
|
410
491
|
}
|
|
411
492
|
|
|
412
493
|
private _handleOptionsChanged(): void {
|
|
@@ -436,6 +517,11 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
436
517
|
*/
|
|
437
518
|
e.replaceChildren();
|
|
438
519
|
}
|
|
520
|
+
if (this._rowHasBlinkingCellsCount > 0) {
|
|
521
|
+
this._rowHasBlinkingCells.fill(false);
|
|
522
|
+
this._rowHasBlinkingCellsCount = 0;
|
|
523
|
+
this._textBlinkStateManager.setNeedsBlinkInViewport(false);
|
|
524
|
+
}
|
|
439
525
|
}
|
|
440
526
|
|
|
441
527
|
public renderRows(start: number, end: number): void {
|
|
@@ -445,13 +531,19 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
445
531
|
const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;
|
|
446
532
|
const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;
|
|
447
533
|
const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;
|
|
534
|
+
const rowInfo = { hasBlinkingCells: false };
|
|
448
535
|
|
|
449
536
|
for (let y = start; y <= end; y++) {
|
|
450
537
|
const row = y + buffer.ydisp;
|
|
451
538
|
const rowElement = this._rowElements[y];
|
|
539
|
+
if (!rowElement) {
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
452
542
|
const lineData = buffer.lines.get(row);
|
|
453
|
-
if (!
|
|
454
|
-
|
|
543
|
+
if (!lineData) {
|
|
544
|
+
rowElement.replaceChildren();
|
|
545
|
+
this._setRowBlinkState(y, false);
|
|
546
|
+
continue;
|
|
455
547
|
}
|
|
456
548
|
rowElement.replaceChildren(
|
|
457
549
|
...this._rowFactory.createRow(
|
|
@@ -462,17 +554,21 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
462
554
|
cursorInactiveStyle,
|
|
463
555
|
cursorX,
|
|
464
556
|
cursorBlink,
|
|
557
|
+
this._textBlinkStateManager.isBlinkOn,
|
|
465
558
|
this.dimensions.css.cell.width,
|
|
466
559
|
this._widthCache,
|
|
467
560
|
-1,
|
|
468
|
-
-1
|
|
561
|
+
-1,
|
|
562
|
+
rowInfo
|
|
469
563
|
)
|
|
470
564
|
);
|
|
565
|
+
this._setRowBlinkState(y, rowInfo.hasBlinkingCells);
|
|
471
566
|
}
|
|
567
|
+
this._updateTextBlinkState();
|
|
472
568
|
}
|
|
473
569
|
|
|
474
570
|
private get _terminalSelector(): string {
|
|
475
|
-
return `.${TERMINAL_CLASS_PREFIX}${this._terminalClass}`;
|
|
571
|
+
return `.${Constants.TERMINAL_CLASS_PREFIX}${this._terminalClass}`;
|
|
476
572
|
}
|
|
477
573
|
|
|
478
574
|
private _handleLinkHover(e: ILinkifierEvent): void {
|
|
@@ -513,14 +609,20 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
513
609
|
const cursorBlink = this._optionsService.rawOptions.cursorBlink;
|
|
514
610
|
const cursorStyle = this._optionsService.rawOptions.cursorStyle;
|
|
515
611
|
const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;
|
|
612
|
+
const rowInfo = { hasBlinkingCells: false };
|
|
516
613
|
|
|
517
614
|
// refresh rows within link range
|
|
518
615
|
for (let i = y; i <= y2; ++i) {
|
|
519
616
|
const row = i + buffer.ydisp;
|
|
520
617
|
const rowElement = this._rowElements[i];
|
|
618
|
+
if (!rowElement) {
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
521
621
|
const bufferline = buffer.lines.get(row);
|
|
522
|
-
if (!
|
|
523
|
-
|
|
622
|
+
if (!bufferline) {
|
|
623
|
+
rowElement.replaceChildren();
|
|
624
|
+
this._setRowBlinkState(i, false);
|
|
625
|
+
continue;
|
|
524
626
|
}
|
|
525
627
|
rowElement.replaceChildren(
|
|
526
628
|
...this._rowFactory.createRow(
|
|
@@ -531,12 +633,86 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
531
633
|
cursorInactiveStyle,
|
|
532
634
|
cursorX,
|
|
533
635
|
cursorBlink,
|
|
636
|
+
this._textBlinkStateManager.isBlinkOn,
|
|
534
637
|
this.dimensions.css.cell.width,
|
|
535
638
|
this._widthCache,
|
|
536
639
|
enabled ? (i === y ? x : 0) : -1,
|
|
537
|
-
enabled ? ((i === y2 ? x2 : cols) - 1) : -1
|
|
640
|
+
enabled ? ((i === y2 ? x2 : cols) - 1) : -1,
|
|
641
|
+
rowInfo
|
|
538
642
|
)
|
|
539
643
|
);
|
|
644
|
+
this._setRowBlinkState(i, rowInfo.hasBlinkingCells);
|
|
540
645
|
}
|
|
646
|
+
this._updateTextBlinkState();
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {
|
|
650
|
+
const previous = this._rowHasBlinkingCells[row];
|
|
651
|
+
if (previous === hasBlinkingCells) {
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
this._rowHasBlinkingCells[row] = hasBlinkingCells;
|
|
655
|
+
this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
private _updateTextBlinkState(): void {
|
|
659
|
+
this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
class CursorBlinkStateManager {
|
|
664
|
+
private _idleTimeout: number | undefined;
|
|
665
|
+
private _isIdlePaused: boolean = false;
|
|
666
|
+
|
|
667
|
+
constructor(
|
|
668
|
+
private readonly _rowContainer: HTMLElement,
|
|
669
|
+
private readonly _coreBrowserService: ICoreBrowserService
|
|
670
|
+
) {
|
|
671
|
+
if (this._coreBrowserService.isFocused) {
|
|
672
|
+
this._resetIdleTimer();
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
public dispose(): void {
|
|
677
|
+
this._clearIdleTimer();
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
public restartBlinkAnimation(): void {
|
|
681
|
+
if (this._isIdlePaused) {
|
|
682
|
+
this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);
|
|
683
|
+
}
|
|
684
|
+
this._resetIdleTimer();
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
public pause(): void {
|
|
688
|
+
this._isIdlePaused = false;
|
|
689
|
+
this._clearIdleTimer();
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
public resume(): void {
|
|
693
|
+
this._isIdlePaused = false;
|
|
694
|
+
this._rowContainer.classList.remove(Constants.CURSOR_BLINK_IDLE_CLASS);
|
|
695
|
+
this._resetIdleTimer();
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
private _resetIdleTimer(): void {
|
|
699
|
+
this._isIdlePaused = false;
|
|
700
|
+
this._clearIdleTimer();
|
|
701
|
+
this._idleTimeout = this._coreBrowserService.window.setTimeout(() => {
|
|
702
|
+
this._stopBlinkingDueToIdle();
|
|
703
|
+
}, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
private _clearIdleTimer(): void {
|
|
707
|
+
if (this._idleTimeout !== undefined) {
|
|
708
|
+
this._coreBrowserService.window.clearTimeout(this._idleTimeout);
|
|
709
|
+
this._idleTimeout = undefined;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
private _stopBlinkingDueToIdle(): void {
|
|
714
|
+
this._rowContainer.classList.add(Constants.CURSOR_BLINK_IDLE_CLASS);
|
|
715
|
+
this._isIdlePaused = true;
|
|
716
|
+
this._idleTimeout = undefined;
|
|
541
717
|
}
|
|
542
718
|
}
|