@xterm/xterm 6.1.0-beta.25 → 6.1.0-beta.251
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 +25 -22
- package/src/browser/AccessibilityManager.ts +11 -6
- package/src/browser/Clipboard.ts +6 -3
- package/src/browser/CoreBrowserTerminal.ts +149 -319
- package/src/browser/Dom.ts +178 -0
- package/src/browser/Linkifier.ts +11 -11
- package/src/browser/OscLinkProvider.ts +82 -14
- package/src/browser/RenderDebouncer.ts +2 -2
- package/src/browser/TimeBasedDebouncer.ts +2 -2
- package/src/browser/Types.ts +12 -11
- package/src/browser/Viewport.ts +55 -20
- package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
- package/src/browser/decorations/OverviewRulerRenderer.ts +33 -17
- package/src/browser/input/CompositionHelper.ts +44 -8
- package/src/browser/public/Terminal.ts +25 -28
- package/src/browser/renderer/dom/DomRenderer.ts +242 -76
- package/src/browser/renderer/dom/DomRendererRowFactory.ts +19 -13
- package/src/browser/renderer/dom/WidthCache.ts +54 -52
- package/src/browser/renderer/shared/Constants.ts +7 -0
- package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
- package/src/browser/renderer/shared/Types.ts +8 -2
- 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/services/CharSizeService.ts +2 -2
- package/src/browser/services/CoreBrowserService.ts +7 -5
- package/src/browser/services/KeyboardService.ts +67 -0
- package/src/browser/services/LinkProviderService.ts +1 -1
- package/src/browser/services/MouseCoordsService.ts +47 -0
- package/src/browser/services/MouseService.ts +518 -25
- package/src/browser/services/RenderService.ts +28 -16
- package/src/browser/services/SelectionService.ts +45 -39
- package/src/browser/services/Services.ts +40 -17
- package/src/browser/services/ThemeService.ts +2 -2
- package/src/common/Async.ts +141 -0
- package/src/common/CircularList.ts +2 -2
- package/src/common/Color.ts +8 -0
- package/src/common/CoreTerminal.ts +32 -22
- package/src/common/Event.ts +118 -0
- package/src/common/InputHandler.ts +286 -87
- package/src/common/Lifecycle.ts +113 -0
- package/src/common/Platform.ts +13 -3
- package/src/common/SortedList.ts +7 -3
- package/src/common/StringBuilder.ts +67 -0
- package/src/common/TaskQueue.ts +14 -5
- package/src/common/Types.ts +51 -31
- package/src/common/Version.ts +9 -0
- package/src/common/buffer/Buffer.ts +34 -19
- package/src/common/buffer/BufferLine.ts +140 -68
- package/src/common/buffer/BufferLineStringCache.ts +69 -0
- package/src/common/buffer/BufferReflow.ts +4 -1
- package/src/common/buffer/BufferSet.ts +11 -6
- package/src/common/buffer/CellData.ts +57 -0
- package/src/common/buffer/Marker.ts +2 -2
- package/src/common/buffer/Types.ts +6 -2
- package/src/common/data/EscapeSequences.ts +71 -70
- package/src/common/input/Keyboard.ts +14 -7
- package/src/common/input/KittyKeyboard.ts +526 -0
- package/src/common/input/Win32InputMode.ts +297 -0
- package/src/common/input/WriteBuffer.ts +107 -38
- 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 +11 -12
- package/src/common/parser/EscapeSequenceParser.ts +205 -63
- package/src/common/parser/OscParser.ts +11 -12
- package/src/common/parser/Params.ts +27 -8
- package/src/common/parser/Types.ts +36 -2
- package/src/common/public/BufferLineApiView.ts +2 -2
- package/src/common/public/BufferNamespaceApi.ts +3 -3
- package/src/common/public/ParserApi.ts +3 -0
- package/src/common/services/BufferService.ts +14 -9
- package/src/common/services/CharsetService.ts +4 -0
- package/src/common/services/CoreService.ts +22 -9
- package/src/common/services/DecorationService.ts +255 -8
- package/src/common/services/LogService.ts +1 -31
- package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +21 -132
- package/src/common/services/OptionsService.ts +13 -4
- package/src/common/services/ServiceRegistry.ts +9 -7
- package/src/common/services/Services.ts +49 -40
- package/src/common/services/UnicodeService.ts +1 -1
- package/typings/xterm.d.ts +318 -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
|
@@ -7,10 +7,10 @@ import { RenderDebouncer } from 'browser/RenderDebouncer';
|
|
|
7
7
|
import { IRenderDebouncerWithCallback } from 'browser/Types';
|
|
8
8
|
import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types';
|
|
9
9
|
import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
|
|
10
|
-
import { Disposable, MutableDisposable, toDisposable } from '
|
|
10
|
+
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
|
11
11
|
import { DebouncedIdleTask } from 'common/TaskQueue';
|
|
12
|
-
import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
|
|
13
|
-
import { Emitter } from '
|
|
12
|
+
import { IBufferService, ICoreService, IDecorationService, ILogService, IOptionsService } from 'common/services/Services';
|
|
13
|
+
import { Emitter } from 'common/Event';
|
|
14
14
|
|
|
15
15
|
interface ISelectionState {
|
|
16
16
|
start: [number, number] | undefined;
|
|
@@ -27,8 +27,9 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
27
27
|
|
|
28
28
|
private _renderer: MutableDisposable<IRenderer> = this._register(new MutableDisposable());
|
|
29
29
|
private _renderDebouncer: IRenderDebouncerWithCallback;
|
|
30
|
-
private _pausedResizeTask
|
|
30
|
+
private _pausedResizeTask: DebouncedIdleTask;
|
|
31
31
|
private _observerDisposable = this._register(new MutableDisposable());
|
|
32
|
+
private _intersectionObserver: IntersectionObserver | undefined;
|
|
32
33
|
|
|
33
34
|
private _isPaused: boolean = false;
|
|
34
35
|
private _needsFullRefresh: boolean = false;
|
|
@@ -58,6 +59,7 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
58
59
|
private _rowCount: number,
|
|
59
60
|
screenElement: HTMLElement,
|
|
60
61
|
@IOptionsService private readonly _optionsService: IOptionsService,
|
|
62
|
+
@ILogService private readonly _logService: ILogService,
|
|
61
63
|
@ICharSizeService private readonly _charSizeService: ICharSizeService,
|
|
62
64
|
@ICoreService private readonly _coreService: ICoreService,
|
|
63
65
|
@IDecorationService decorationService: IDecorationService,
|
|
@@ -67,6 +69,8 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
67
69
|
) {
|
|
68
70
|
super();
|
|
69
71
|
|
|
72
|
+
this._pausedResizeTask = this._register(new DebouncedIdleTask(this._logService));
|
|
73
|
+
|
|
70
74
|
this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);
|
|
71
75
|
this._register(this._renderDebouncer);
|
|
72
76
|
|
|
@@ -111,7 +115,7 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
111
115
|
this._register(this._optionsService.onMultipleOptionChange([
|
|
112
116
|
'cursorBlink',
|
|
113
117
|
'cursorStyle'
|
|
114
|
-
], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, true)));
|
|
118
|
+
], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, undefined, true)));
|
|
115
119
|
|
|
116
120
|
this._register(themeService.onChangeColors(() => this._fullRefresh()));
|
|
117
121
|
|
|
@@ -124,13 +128,18 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
124
128
|
// and resume based on terminal visibility if so
|
|
125
129
|
if ('IntersectionObserver' in w) {
|
|
126
130
|
const observer = new w.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });
|
|
131
|
+
this._observerDisposable.value = toDisposable(() => {
|
|
132
|
+
this._intersectionObserver?.disconnect();
|
|
133
|
+
this._intersectionObserver = undefined;
|
|
134
|
+
});
|
|
135
|
+
this._intersectionObserver = observer;
|
|
127
136
|
observer.observe(screenElement);
|
|
128
|
-
this._observerDisposable.value = toDisposable(() => observer.disconnect());
|
|
129
137
|
}
|
|
130
138
|
}
|
|
131
139
|
|
|
132
140
|
private _handleIntersectionChange(entry: IntersectionObserverEntry): void {
|
|
133
141
|
this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;
|
|
142
|
+
this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused);
|
|
134
143
|
|
|
135
144
|
// Terminal was hidden on open
|
|
136
145
|
if (!this._isPaused && !this._charSizeService.hasValidSize) {
|
|
@@ -144,7 +153,7 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
144
153
|
}
|
|
145
154
|
}
|
|
146
155
|
|
|
147
|
-
public refreshRows(start: number, end: number, isRedrawOnly: boolean = false): void {
|
|
156
|
+
public refreshRows(start: number, end: number, sync: boolean = false, isRedrawOnly: boolean = false): void {
|
|
148
157
|
if (this._isPaused) {
|
|
149
158
|
this._needsFullRefresh = true;
|
|
150
159
|
return;
|
|
@@ -164,7 +173,12 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
164
173
|
if (!isRedrawOnly) {
|
|
165
174
|
this._isNextRenderRedrawOnly = false;
|
|
166
175
|
}
|
|
167
|
-
|
|
176
|
+
|
|
177
|
+
if (sync) {
|
|
178
|
+
this._renderRows(start, end);
|
|
179
|
+
} else {
|
|
180
|
+
this._renderDebouncer.refresh(start, end, this._rowCount);
|
|
181
|
+
}
|
|
168
182
|
}
|
|
169
183
|
|
|
170
184
|
private _renderRows(start: number, end: number): void {
|
|
@@ -234,7 +248,7 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
234
248
|
this._renderer.value = renderer;
|
|
235
249
|
// If the value was not set, the terminal is being disposed so ignore it
|
|
236
250
|
if (this._renderer.value) {
|
|
237
|
-
this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
|
|
251
|
+
this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, e.sync, true));
|
|
238
252
|
|
|
239
253
|
// Force a refresh
|
|
240
254
|
this._needsSelectionRefresh = true;
|
|
@@ -342,13 +356,11 @@ class SynchronizedOutputHandler {
|
|
|
342
356
|
this._end = Math.max(this._end, end);
|
|
343
357
|
}
|
|
344
358
|
|
|
345
|
-
|
|
346
|
-
this._timeout =
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);
|
|
351
|
-
}
|
|
359
|
+
this._timeout ??= this._coreBrowserService.window.setTimeout(() => {
|
|
360
|
+
this._timeout = undefined;
|
|
361
|
+
this._coreService.decPrivateModes.synchronizedOutput = false;
|
|
362
|
+
this._onTimeout();
|
|
363
|
+
}, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);
|
|
352
364
|
}
|
|
353
365
|
|
|
354
366
|
public flush(): { start: number, end: number } | undefined {
|
|
@@ -8,37 +8,36 @@ import { getCoordsRelativeToElement } from 'browser/input/Mouse';
|
|
|
8
8
|
import { moveToCellSequence } from 'browser/input/MoveToCell';
|
|
9
9
|
import { SelectionModel } from 'browser/selection/SelectionModel';
|
|
10
10
|
import { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types';
|
|
11
|
-
import { ICoreBrowserService,
|
|
12
|
-
import { Disposable, toDisposable } from '
|
|
11
|
+
import { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from 'browser/services/Services';
|
|
12
|
+
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
|
13
13
|
import * as Browser from 'common/Platform';
|
|
14
|
-
import { IBufferLine, IDisposable } from 'common/Types';
|
|
14
|
+
import { IBufferLine, ICellData, IDisposable } from 'common/Types';
|
|
15
15
|
import { getRangeLength } from 'common/buffer/BufferRange';
|
|
16
16
|
import { CellData } from 'common/buffer/CellData';
|
|
17
17
|
import { IBuffer } from 'common/buffer/Types';
|
|
18
18
|
import { IBufferService, ICoreService, IOptionsService } from 'common/services/Services';
|
|
19
|
-
import { Emitter } from '
|
|
19
|
+
import { Emitter } from 'common/Event';
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const ALT_CLICK_MOVE_CURSOR_TIME = 500;
|
|
21
|
+
const enum Constants {
|
|
22
|
+
/**
|
|
23
|
+
* The number of pixels the mouse needs to be above or below the viewport in
|
|
24
|
+
* order to scroll at the maximum speed.
|
|
25
|
+
*/
|
|
26
|
+
DRAG_SCROLL_MAX_THRESHOLD = 50,
|
|
27
|
+
/**
|
|
28
|
+
* The maximum scrolling speed
|
|
29
|
+
*/
|
|
30
|
+
DRAG_SCROLL_MAX_SPEED = 15,
|
|
31
|
+
/**
|
|
32
|
+
* The number of milliseconds between drag scroll updates.
|
|
33
|
+
*/
|
|
34
|
+
DRAG_SCROLL_INTERVAL = 50,
|
|
35
|
+
/**
|
|
36
|
+
* The maximum amount of time that can have elapsed for an alt click to move the
|
|
37
|
+
* cursor.
|
|
38
|
+
*/
|
|
39
|
+
ALT_CLICK_MOVE_CURSOR_TIME = 500
|
|
40
|
+
}
|
|
42
41
|
|
|
43
42
|
const NON_BREAKING_SPACE_CHAR = String.fromCharCode(160);
|
|
44
43
|
const ALL_NON_BREAKING_SPACE_REGEX = new RegExp(NON_BREAKING_SPACE_CHAR, 'g');
|
|
@@ -103,7 +102,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
103
102
|
|
|
104
103
|
private _mouseMoveListener: EventListener;
|
|
105
104
|
private _mouseUpListener: EventListener;
|
|
106
|
-
private _trimListener
|
|
105
|
+
private readonly _trimListener = this._register(new MutableDisposable<IDisposable>());
|
|
107
106
|
private _workCell: CellData = new CellData();
|
|
108
107
|
|
|
109
108
|
private _mouseDownTimeStamp: number = 0;
|
|
@@ -126,7 +125,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
126
125
|
private readonly _linkifier: ILinkifier2,
|
|
127
126
|
@IBufferService private readonly _bufferService: IBufferService,
|
|
128
127
|
@ICoreService private readonly _coreService: ICoreService,
|
|
129
|
-
@
|
|
128
|
+
@IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,
|
|
130
129
|
@IOptionsService private readonly _optionsService: IOptionsService,
|
|
131
130
|
@IRenderService private readonly _renderService: IRenderService,
|
|
132
131
|
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService
|
|
@@ -141,7 +140,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
141
140
|
this.clearSelection();
|
|
142
141
|
}
|
|
143
142
|
});
|
|
144
|
-
this._trimListener = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));
|
|
143
|
+
this._trimListener.value = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));
|
|
145
144
|
this._register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));
|
|
146
145
|
|
|
147
146
|
this.enable();
|
|
@@ -395,7 +394,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
395
394
|
* @param event The mouse event.
|
|
396
395
|
*/
|
|
397
396
|
private _getMouseBufferCoords(event: MouseEvent): [number, number] | undefined {
|
|
398
|
-
const coords = this.
|
|
397
|
+
const coords = this._mouseCoordsService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);
|
|
399
398
|
if (!coords) {
|
|
400
399
|
return undefined;
|
|
401
400
|
}
|
|
@@ -424,9 +423,9 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
424
423
|
offset -= terminalHeight;
|
|
425
424
|
}
|
|
426
425
|
|
|
427
|
-
offset = Math.min(Math.max(offset, -DRAG_SCROLL_MAX_THRESHOLD), DRAG_SCROLL_MAX_THRESHOLD);
|
|
428
|
-
offset /= DRAG_SCROLL_MAX_THRESHOLD;
|
|
429
|
-
return (offset / Math.abs(offset)) + Math.round(offset * (DRAG_SCROLL_MAX_SPEED - 1));
|
|
426
|
+
offset = Math.min(Math.max(offset, -Constants.DRAG_SCROLL_MAX_THRESHOLD), Constants.DRAG_SCROLL_MAX_THRESHOLD);
|
|
427
|
+
offset /= Constants.DRAG_SCROLL_MAX_THRESHOLD;
|
|
428
|
+
return (offset / Math.abs(offset)) + Math.round(offset * (Constants.DRAG_SCROLL_MAX_SPEED - 1));
|
|
430
429
|
}
|
|
431
430
|
|
|
432
431
|
/**
|
|
@@ -500,7 +499,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
500
499
|
this._screenElement.ownerDocument.addEventListener('mousemove', this._mouseMoveListener);
|
|
501
500
|
this._screenElement.ownerDocument.addEventListener('mouseup', this._mouseUpListener);
|
|
502
501
|
}
|
|
503
|
-
this._dragScrollIntervalTimer = this._coreBrowserService.window.setInterval(() => this._dragScroll(), DRAG_SCROLL_INTERVAL);
|
|
502
|
+
this._dragScrollIntervalTimer = this._coreBrowserService.window.setInterval(() => this._dragScroll(), Constants.DRAG_SCROLL_INTERVAL);
|
|
504
503
|
}
|
|
505
504
|
|
|
506
505
|
/**
|
|
@@ -532,6 +531,9 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
532
531
|
* @param event The mouse event.
|
|
533
532
|
*/
|
|
534
533
|
private _handleSingleClick(event: MouseEvent): void {
|
|
534
|
+
// Track if there was a selection before clearing
|
|
535
|
+
const hadSelection = this.hasSelection;
|
|
536
|
+
|
|
535
537
|
this._model.selectionStartLength = 0;
|
|
536
538
|
this._model.isSelectAllActive = false;
|
|
537
539
|
this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;
|
|
@@ -543,6 +545,11 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
543
545
|
}
|
|
544
546
|
this._model.selectionEnd = undefined;
|
|
545
547
|
|
|
548
|
+
// Fire selection change event if a selection was cleared
|
|
549
|
+
if (hadSelection) {
|
|
550
|
+
this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);
|
|
551
|
+
}
|
|
552
|
+
|
|
546
553
|
// Ensure the line exists
|
|
547
554
|
const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);
|
|
548
555
|
if (!line) {
|
|
@@ -667,7 +674,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
667
674
|
}
|
|
668
675
|
|
|
669
676
|
/**
|
|
670
|
-
* The callback that occurs every DRAG_SCROLL_INTERVAL ms that does the
|
|
677
|
+
* The callback that occurs every Constants.DRAG_SCROLL_INTERVAL ms that does the
|
|
671
678
|
* scrolling of the viewport.
|
|
672
679
|
*/
|
|
673
680
|
private _dragScroll(): void {
|
|
@@ -705,9 +712,9 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
705
712
|
|
|
706
713
|
this._removeMouseDownListeners();
|
|
707
714
|
|
|
708
|
-
if (this.selectionText.length <= 1 && timeElapsed < ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {
|
|
715
|
+
if (this.selectionText.length <= 1 && timeElapsed < Constants.ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {
|
|
709
716
|
if (this._bufferService.buffer.ybase === this._bufferService.buffer.ydisp) {
|
|
710
|
-
const coordinates = this.
|
|
717
|
+
const coordinates = this._mouseCoordsService.getCoords(
|
|
711
718
|
event,
|
|
712
719
|
this._element,
|
|
713
720
|
this._bufferService.cols,
|
|
@@ -762,8 +769,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
762
769
|
// reverseIndex) and delete in a splice is only ever used when the same
|
|
763
770
|
// number of elements was just added. Given this is could actually be
|
|
764
771
|
// beneficial to leave the selection as is for these cases.
|
|
765
|
-
this._trimListener.
|
|
766
|
-
this._trimListener = e.activeBuffer.lines.onTrim(amount => this._handleTrim(amount));
|
|
772
|
+
this._trimListener.value = e.activeBuffer.lines.onTrim(amount => this._handleTrim(amount));
|
|
767
773
|
}
|
|
768
774
|
|
|
769
775
|
/**
|
|
@@ -1013,7 +1019,7 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
1013
1019
|
* word logic.
|
|
1014
1020
|
* @param cell The cell to check.
|
|
1015
1021
|
*/
|
|
1016
|
-
private _isCharWordSeparator(cell:
|
|
1022
|
+
private _isCharWordSeparator(cell: ICellData): boolean {
|
|
1017
1023
|
// Zero width characters are never separators as they are always to the
|
|
1018
1024
|
// right of wide characters
|
|
1019
1025
|
if (cell.getWidth() === 0) {
|
|
@@ -7,8 +7,8 @@ import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types';
|
|
|
7
7
|
import { IColorSet, ILink, ReadonlyColorSet } from 'browser/Types';
|
|
8
8
|
import { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types';
|
|
9
9
|
import { createDecorator } from 'common/services/ServiceRegistry';
|
|
10
|
-
import { AllColorIndex, IDisposable } from 'common/Types';
|
|
11
|
-
import type {
|
|
10
|
+
import { AllColorIndex, IDisposable, IKeyboardResult } from 'common/Types';
|
|
11
|
+
import type { IEvent } from 'common/Event';
|
|
12
12
|
|
|
13
13
|
export const ICharSizeService = createDecorator<ICharSizeService>('CharSizeService');
|
|
14
14
|
export interface ICharSizeService {
|
|
@@ -18,7 +18,7 @@ export interface ICharSizeService {
|
|
|
18
18
|
readonly height: number;
|
|
19
19
|
readonly hasValidSize: boolean;
|
|
20
20
|
|
|
21
|
-
readonly onCharSizeChange:
|
|
21
|
+
readonly onCharSizeChange: IEvent<void>;
|
|
22
22
|
|
|
23
23
|
measure(): void;
|
|
24
24
|
}
|
|
@@ -29,8 +29,8 @@ export interface ICoreBrowserService {
|
|
|
29
29
|
|
|
30
30
|
readonly isFocused: boolean;
|
|
31
31
|
|
|
32
|
-
readonly onDprChange:
|
|
33
|
-
readonly onWindowChange:
|
|
32
|
+
readonly onDprChange: IEvent<number>;
|
|
33
|
+
readonly onWindowChange: IEvent<Window & typeof globalThis>;
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.
|
|
@@ -49,35 +49,49 @@ export interface ICoreBrowserService {
|
|
|
49
49
|
readonly dpr: number;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export const
|
|
53
|
-
export interface
|
|
52
|
+
export const IMouseCoordsService = createDecorator<IMouseCoordsService>('MouseCoordsService');
|
|
53
|
+
export interface IMouseCoordsService {
|
|
54
54
|
serviceBrand: undefined;
|
|
55
55
|
|
|
56
56
|
getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;
|
|
57
57
|
getMouseReportCoords(event: MouseEvent, element: HTMLElement): { col: number, row: number, x: number, y: number } | undefined;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
export const IMouseService = createDecorator<IMouseService>('MouseService');
|
|
61
|
+
export interface IMouseService {
|
|
62
|
+
serviceBrand: undefined;
|
|
63
|
+
|
|
64
|
+
bindMouse(target: IMouseServiceTarget, register: (disposable: IDisposable) => void, focus: () => void): void;
|
|
65
|
+
reset(): void;
|
|
66
|
+
}
|
|
67
|
+
export interface IMouseServiceTarget {
|
|
68
|
+
element: HTMLElement;
|
|
69
|
+
screenElement: HTMLElement;
|
|
70
|
+
document: Document;
|
|
71
|
+
handleTouchScroll?(amount: number): void;
|
|
72
|
+
}
|
|
73
|
+
|
|
60
74
|
export const IRenderService = createDecorator<IRenderService>('RenderService');
|
|
61
75
|
export interface IRenderService extends IDisposable {
|
|
62
76
|
serviceBrand: undefined;
|
|
63
77
|
|
|
64
|
-
onDimensionsChange:
|
|
78
|
+
onDimensionsChange: IEvent<IRenderDimensions>;
|
|
65
79
|
/**
|
|
66
80
|
* Fires when buffer changes are rendered. This does not fire when only cursor
|
|
67
81
|
* or selections are rendered.
|
|
68
82
|
*/
|
|
69
|
-
onRenderedViewportChange:
|
|
83
|
+
onRenderedViewportChange: IEvent<{ start: number, end: number }>;
|
|
70
84
|
/**
|
|
71
85
|
* Fires on render
|
|
72
86
|
*/
|
|
73
|
-
onRender:
|
|
74
|
-
onRefreshRequest:
|
|
87
|
+
onRender: IEvent<{ start: number, end: number }>;
|
|
88
|
+
onRefreshRequest: IEvent<{ start: number, end: number }>;
|
|
75
89
|
|
|
76
90
|
dimensions: IRenderDimensions;
|
|
77
91
|
|
|
78
92
|
addRefreshCallback(callback: FrameRequestCallback): number;
|
|
79
93
|
|
|
80
|
-
refreshRows(start: number, end: number): void;
|
|
94
|
+
refreshRows(start: number, end: number, sync?: boolean): void;
|
|
81
95
|
clearTextureAtlas(): void;
|
|
82
96
|
resize(cols: number, rows: number): void;
|
|
83
97
|
hasRenderer(): boolean;
|
|
@@ -101,10 +115,10 @@ export interface ISelectionService {
|
|
|
101
115
|
readonly selectionStart: [number, number] | undefined;
|
|
102
116
|
readonly selectionEnd: [number, number] | undefined;
|
|
103
117
|
|
|
104
|
-
readonly onLinuxMouseSelection:
|
|
105
|
-
readonly onRequestRedraw:
|
|
106
|
-
readonly onRequestScrollLines:
|
|
107
|
-
readonly onSelectionChange:
|
|
118
|
+
readonly onLinuxMouseSelection: IEvent<string>;
|
|
119
|
+
readonly onRequestRedraw: IEvent<ISelectionRequestRedrawEvent>;
|
|
120
|
+
readonly onRequestScrollLines: IEvent<ISelectionRequestScrollLinesEvent>;
|
|
121
|
+
readonly onSelectionChange: IEvent<void>;
|
|
108
122
|
|
|
109
123
|
disable(): void;
|
|
110
124
|
enable(): void;
|
|
@@ -136,7 +150,7 @@ export interface IThemeService {
|
|
|
136
150
|
|
|
137
151
|
readonly colors: ReadonlyColorSet;
|
|
138
152
|
|
|
139
|
-
readonly onChangeColors:
|
|
153
|
+
readonly onChangeColors: IEvent<ReadonlyColorSet>;
|
|
140
154
|
|
|
141
155
|
restoreColor(slot?: AllColorIndex): void;
|
|
142
156
|
/**
|
|
@@ -156,3 +170,12 @@ export interface ILinkProviderService extends IDisposable {
|
|
|
156
170
|
export interface ILinkProvider {
|
|
157
171
|
provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;
|
|
158
172
|
}
|
|
173
|
+
|
|
174
|
+
export const IKeyboardService = createDecorator<IKeyboardService>('KeyboardService');
|
|
175
|
+
export interface IKeyboardService {
|
|
176
|
+
serviceBrand: undefined;
|
|
177
|
+
evaluateKeyDown(event: KeyboardEvent): IKeyboardResult;
|
|
178
|
+
evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined;
|
|
179
|
+
readonly useKitty: boolean;
|
|
180
|
+
readonly useWin32InputMode: boolean;
|
|
181
|
+
}
|
|
@@ -7,10 +7,10 @@ import { ColorContrastCache } from 'browser/ColorContrastCache';
|
|
|
7
7
|
import { IThemeService } from 'browser/services/Services';
|
|
8
8
|
import { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from 'browser/Types';
|
|
9
9
|
import { color, css, NULL_COLOR } from 'common/Color';
|
|
10
|
-
import { Disposable } from '
|
|
10
|
+
import { Disposable } from 'common/Lifecycle';
|
|
11
11
|
import { IOptionsService, ITheme } from 'common/services/Services';
|
|
12
12
|
import { AllColorIndex, IColor, SpecialColorIndex } from 'common/Types';
|
|
13
|
-
import { Emitter } from '
|
|
13
|
+
import { Emitter } from 'common/Event';
|
|
14
14
|
|
|
15
15
|
interface IRestoreColorSet {
|
|
16
16
|
foreground: IColor;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2026 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*
|
|
5
|
+
* Minimal async helpers for xterm.js core.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { DisposableStore, IDisposable, toDisposable } from 'common/Lifecycle';
|
|
9
|
+
|
|
10
|
+
export function timeout(millis: number): Promise<void> {
|
|
11
|
+
return new Promise(resolve => setTimeout(resolve, millis));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a timeout that can be disposed using its returned value.
|
|
16
|
+
* @param handler The timeout handler.
|
|
17
|
+
* @param timeout An optional timeout in milliseconds.
|
|
18
|
+
* @param store An optional {@link DisposableStore} that will have the timeout disposable managed
|
|
19
|
+
* automatically.
|
|
20
|
+
*/
|
|
21
|
+
export function disposableTimeout(handler: () => void, timeout = 0, store?: DisposableStore): IDisposable {
|
|
22
|
+
const timer = setTimeout(() => {
|
|
23
|
+
handler();
|
|
24
|
+
if (store) {
|
|
25
|
+
disposable.dispose();
|
|
26
|
+
}
|
|
27
|
+
}, timeout);
|
|
28
|
+
const disposable = toDisposable(() => {
|
|
29
|
+
clearTimeout(timer);
|
|
30
|
+
});
|
|
31
|
+
store?.add(disposable);
|
|
32
|
+
return disposable;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class TimeoutTimer implements IDisposable {
|
|
36
|
+
private _token: any = -1;
|
|
37
|
+
private _isDisposed = false;
|
|
38
|
+
|
|
39
|
+
public dispose(): void {
|
|
40
|
+
this.cancel();
|
|
41
|
+
this._isDisposed = true;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public cancel(): void {
|
|
45
|
+
if (this._token !== -1) {
|
|
46
|
+
clearTimeout(this._token);
|
|
47
|
+
this._token = -1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
public cancelAndSet(runner: () => void, timeout: number): void {
|
|
52
|
+
if (this._isDisposed) {
|
|
53
|
+
throw new Error('Calling cancelAndSet on a disposed TimeoutTimer');
|
|
54
|
+
}
|
|
55
|
+
this.cancel();
|
|
56
|
+
this._token = setTimeout(() => {
|
|
57
|
+
this._token = -1;
|
|
58
|
+
runner();
|
|
59
|
+
}, timeout);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public setIfNotSet(runner: () => void, timeout: number): void {
|
|
63
|
+
if (this._isDisposed) {
|
|
64
|
+
throw new Error('Calling setIfNotSet on a disposed TimeoutTimer');
|
|
65
|
+
}
|
|
66
|
+
if (this._token !== -1) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this._token = setTimeout(() => {
|
|
70
|
+
this._token = -1;
|
|
71
|
+
runner();
|
|
72
|
+
}, timeout);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Schedules a single runner on the microtask queue. Unlike {@link TimeoutTimer}, a scheduled
|
|
78
|
+
* microtask cannot be unqueued; {@link cancel} prevents the runner from executing if it has not
|
|
79
|
+
* run yet.
|
|
80
|
+
*/
|
|
81
|
+
export class MicrotaskTimer implements IDisposable {
|
|
82
|
+
private _isScheduled = false;
|
|
83
|
+
private _isDisposed = false;
|
|
84
|
+
|
|
85
|
+
public dispose(): void {
|
|
86
|
+
this.cancel();
|
|
87
|
+
this._isDisposed = true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
public cancel(): void {
|
|
91
|
+
this._isScheduled = false;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public set(runner: () => void): void {
|
|
95
|
+
if (this._isDisposed) {
|
|
96
|
+
throw new Error('Calling set on a disposed MicrotaskTimer');
|
|
97
|
+
}
|
|
98
|
+
if (this._isScheduled) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
this._isScheduled = true;
|
|
102
|
+
queueMicrotask(() => {
|
|
103
|
+
if (!this._isScheduled) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this._isScheduled = false;
|
|
107
|
+
runner();
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export class IntervalTimer implements IDisposable {
|
|
113
|
+
private _disposable: IDisposable | undefined;
|
|
114
|
+
private _isDisposed = false;
|
|
115
|
+
|
|
116
|
+
public cancel(): void {
|
|
117
|
+
this._disposable?.dispose();
|
|
118
|
+
this._disposable = undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {
|
|
122
|
+
if (this._isDisposed) {
|
|
123
|
+
throw new Error('Calling cancelAndSet on a disposed IntervalTimer');
|
|
124
|
+
}
|
|
125
|
+
this.cancel();
|
|
126
|
+
const handle = context.setInterval(() => {
|
|
127
|
+
runner();
|
|
128
|
+
}, interval);
|
|
129
|
+
this._disposable = {
|
|
130
|
+
dispose: () => {
|
|
131
|
+
context.clearInterval(handle as any);
|
|
132
|
+
this._disposable = undefined;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public dispose(): void {
|
|
138
|
+
this.cancel();
|
|
139
|
+
this._isDisposed = true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { ICircularList } from 'common/Types';
|
|
7
|
-
import { Disposable } from '
|
|
8
|
-
import { Emitter } from '
|
|
7
|
+
import { Disposable } from 'common/Lifecycle';
|
|
8
|
+
import { Emitter } from 'common/Event';
|
|
9
9
|
|
|
10
10
|
export interface IInsertEvent {
|
|
11
11
|
index: number;
|
package/src/common/Color.ts
CHANGED
|
@@ -184,6 +184,14 @@ export namespace css {
|
|
|
184
184
|
return channels.toColor($r, $g, $b, $a);
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
// Handle the "transparent" keyword
|
|
188
|
+
if (css === 'transparent') {
|
|
189
|
+
return {
|
|
190
|
+
css: 'transparent',
|
|
191
|
+
rgba: 0x00000000
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
187
195
|
// Validate the context is available for canvas-based color parsing
|
|
188
196
|
if (!$ctx || !$litmusColor) {
|
|
189
197
|
throw new Error('css.toColor: Unsupported css format');
|