@xterm/xterm 5.6.0-beta.14 → 5.6.0-beta.141
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 +10 -3
- package/css/xterm.css +71 -4
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +53 -0
- package/lib/xterm.mjs.map +7 -0
- package/package.json +46 -35
- package/src/browser/AccessibilityManager.ts +54 -26
- package/src/browser/{Terminal.ts → CoreBrowserTerminal.ts} +159 -145
- package/src/browser/Linkifier.ts +26 -14
- package/src/browser/LocalizableStrings.ts +15 -4
- package/src/browser/TimeBasedDebouncer.ts +2 -2
- package/src/browser/{Types.d.ts → Types.ts} +67 -15
- package/src/browser/Viewport.ts +148 -370
- package/src/browser/decorations/BufferDecorationRenderer.ts +14 -9
- package/src/browser/decorations/OverviewRulerRenderer.ts +40 -44
- package/src/browser/input/CompositionHelper.ts +2 -1
- package/src/browser/input/MoveToCell.ts +3 -1
- package/src/browser/public/Terminal.ts +26 -19
- package/src/browser/renderer/dom/DomRenderer.ts +19 -14
- package/src/browser/renderer/dom/DomRendererRowFactory.ts +35 -15
- package/src/browser/renderer/shared/Constants.ts +0 -8
- package/src/browser/renderer/shared/Types.ts +84 -0
- package/src/browser/services/CharSizeService.ts +6 -6
- package/src/browser/services/CoreBrowserService.ts +16 -20
- package/src/browser/services/LinkProviderService.ts +2 -2
- package/src/browser/services/RenderService.ts +116 -25
- package/src/browser/services/SelectionService.ts +16 -8
- package/src/browser/services/Services.ts +13 -13
- package/src/browser/services/ThemeService.ts +19 -58
- package/src/browser/shared/Constants.ts +8 -0
- package/src/common/CircularList.ts +5 -5
- package/src/common/CoreTerminal.ts +35 -41
- package/src/common/InputHandler.ts +97 -59
- package/src/common/TaskQueue.ts +7 -7
- package/src/common/{Types.d.ts → Types.ts} +14 -17
- package/src/common/buffer/Buffer.ts +15 -7
- package/src/common/buffer/BufferReflow.ts +9 -6
- package/src/common/buffer/BufferSet.ts +5 -5
- package/src/common/buffer/Marker.ts +4 -4
- package/src/common/buffer/{Types.d.ts → Types.ts} +2 -2
- package/src/common/input/Keyboard.ts +0 -24
- package/src/common/input/WriteBuffer.ts +9 -8
- package/src/common/parser/EscapeSequenceParser.ts +4 -4
- package/src/common/public/BufferNamespaceApi.ts +3 -3
- package/src/common/services/BufferService.ts +14 -11
- package/src/common/services/CoreMouseService.ts +53 -6
- package/src/common/services/CoreService.ts +13 -8
- package/src/common/services/DecorationService.ts +8 -9
- package/src/common/services/InstantiationService.ts +1 -1
- package/src/common/services/LogService.ts +2 -2
- package/src/common/services/OptionsService.ts +8 -6
- package/src/common/services/ServiceRegistry.ts +1 -1
- package/src/common/services/Services.ts +39 -17
- package/src/common/services/UnicodeService.ts +2 -2
- package/src/vs/base/browser/browser.ts +141 -0
- package/src/vs/base/browser/canIUse.ts +49 -0
- package/src/vs/base/browser/dom.ts +2369 -0
- package/src/vs/base/browser/fastDomNode.ts +316 -0
- package/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
- package/src/vs/base/browser/iframe.ts +135 -0
- package/src/vs/base/browser/keyboardEvent.ts +213 -0
- package/src/vs/base/browser/mouseEvent.ts +229 -0
- package/src/vs/base/browser/touch.ts +372 -0
- package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
- package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
- package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
- package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
- package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
- package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
- package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
- package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
- package/src/vs/base/browser/ui/widget.ts +57 -0
- package/src/vs/base/browser/window.ts +14 -0
- package/src/vs/base/common/arrays.ts +887 -0
- package/src/vs/base/common/arraysFind.ts +202 -0
- package/src/vs/base/common/assert.ts +71 -0
- package/src/vs/base/common/async.ts +1992 -0
- package/src/vs/base/common/cancellation.ts +148 -0
- package/src/vs/base/common/charCode.ts +450 -0
- package/src/vs/base/common/collections.ts +140 -0
- package/src/vs/base/common/decorators.ts +130 -0
- package/src/vs/base/common/equals.ts +146 -0
- package/src/vs/base/common/errors.ts +303 -0
- package/src/vs/base/common/event.ts +1778 -0
- package/src/vs/base/common/functional.ts +32 -0
- package/src/vs/base/common/hash.ts +316 -0
- package/src/vs/base/common/iterator.ts +159 -0
- package/src/vs/base/common/keyCodes.ts +526 -0
- package/src/vs/base/common/keybindings.ts +284 -0
- package/src/vs/base/common/lazy.ts +47 -0
- package/src/vs/base/common/lifecycle.ts +801 -0
- package/src/vs/base/common/linkedList.ts +142 -0
- package/src/vs/base/common/map.ts +202 -0
- package/src/vs/base/common/numbers.ts +98 -0
- package/src/vs/base/common/observable.ts +76 -0
- package/src/vs/base/common/observableInternal/api.ts +31 -0
- package/src/vs/base/common/observableInternal/autorun.ts +281 -0
- package/src/vs/base/common/observableInternal/base.ts +489 -0
- package/src/vs/base/common/observableInternal/debugName.ts +145 -0
- package/src/vs/base/common/observableInternal/derived.ts +428 -0
- package/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
- package/src/vs/base/common/observableInternal/logging.ts +328 -0
- package/src/vs/base/common/observableInternal/promise.ts +209 -0
- package/src/vs/base/common/observableInternal/utils.ts +610 -0
- package/src/vs/base/common/platform.ts +281 -0
- package/src/vs/base/common/scrollable.ts +522 -0
- package/src/vs/base/common/sequence.ts +34 -0
- package/src/vs/base/common/stopwatch.ts +43 -0
- package/src/vs/base/common/strings.ts +557 -0
- package/src/vs/base/common/symbols.ts +9 -0
- package/src/vs/base/common/uint.ts +59 -0
- package/src/vs/patches/nls.ts +90 -0
- package/src/vs/typings/base-common.d.ts +20 -0
- package/src/vs/typings/require.d.ts +42 -0
- package/src/vs/typings/vscode-globals-nls.d.ts +36 -0
- package/src/vs/typings/vscode-globals-product.d.ts +33 -0
- package/typings/xterm.d.ts +87 -14
- package/src/browser/Lifecycle.ts +0 -33
- package/src/browser/renderer/shared/CellColorResolver.ts +0 -236
- package/src/browser/renderer/shared/CharAtlasCache.ts +0 -96
- package/src/browser/renderer/shared/CharAtlasUtils.ts +0 -75
- package/src/browser/renderer/shared/CursorBlinkStateManager.ts +0 -146
- package/src/browser/renderer/shared/CustomGlyphs.ts +0 -687
- package/src/browser/renderer/shared/DevicePixelObserver.ts +0 -41
- package/src/browser/renderer/shared/TextureAtlas.ts +0 -1100
- package/src/browser/renderer/shared/Types.d.ts +0 -173
- package/src/common/EventEmitter.ts +0 -78
- package/src/common/Lifecycle.ts +0 -108
- /package/src/browser/selection/{Types.d.ts → Types.ts} +0 -0
- /package/src/common/parser/{Types.d.ts → Types.ts} +0 -0
|
@@ -3,21 +3,21 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
|
7
6
|
import { ICoreBrowserService } from './Services';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
7
|
+
import { Emitter, Event } from 'vs/base/common/event';
|
|
8
|
+
import { addDisposableListener } from 'vs/base/browser/dom';
|
|
9
|
+
import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
10
10
|
|
|
11
11
|
export class CoreBrowserService extends Disposable implements ICoreBrowserService {
|
|
12
12
|
public serviceBrand: undefined;
|
|
13
13
|
|
|
14
14
|
private _isFocused = false;
|
|
15
15
|
private _cachedIsFocused: boolean | undefined = undefined;
|
|
16
|
-
private _screenDprMonitor = this.
|
|
16
|
+
private _screenDprMonitor = this._register(new ScreenDprMonitor(this._window));
|
|
17
17
|
|
|
18
|
-
private readonly _onDprChange = this.
|
|
18
|
+
private readonly _onDprChange = this._register(new Emitter<number>());
|
|
19
19
|
public readonly onDprChange = this._onDprChange.event;
|
|
20
|
-
private readonly _onWindowChange = this.
|
|
20
|
+
private readonly _onWindowChange = this._register(new Emitter<Window & typeof globalThis>());
|
|
21
21
|
public readonly onWindowChange = this._onWindowChange.event;
|
|
22
22
|
|
|
23
23
|
constructor(
|
|
@@ -28,15 +28,11 @@ export class CoreBrowserService extends Disposable implements ICoreBrowserServic
|
|
|
28
28
|
super();
|
|
29
29
|
|
|
30
30
|
// Monitor device pixel ratio
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
33
|
-
|
|
34
|
-
this.
|
|
35
|
-
|
|
36
|
-
);
|
|
37
|
-
this.register(
|
|
38
|
-
addDisposableDomListener(this._textarea, 'blur', () => (this._isFocused = false))
|
|
39
|
-
);
|
|
31
|
+
this._register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w)));
|
|
32
|
+
this._register(Event.forward(this._screenDprMonitor.onDprChange, this._onDprChange));
|
|
33
|
+
|
|
34
|
+
this._register(addDisposableListener(this._textarea, 'focus', () => this._isFocused = true));
|
|
35
|
+
this._register(addDisposableListener(this._textarea, 'blur', () => this._isFocused = false));
|
|
40
36
|
}
|
|
41
37
|
|
|
42
38
|
public get window(): Window & typeof globalThis {
|
|
@@ -69,7 +65,7 @@ export class CoreBrowserService extends Disposable implements ICoreBrowserServic
|
|
|
69
65
|
* window.devicePixelRatio value changes. This is done not with polling but with
|
|
70
66
|
* the use of window.matchMedia to watch media queries. When the event fires,
|
|
71
67
|
* the listener will be reattached using a different media query to ensure that
|
|
72
|
-
* any further changes will
|
|
68
|
+
* any further changes will _register.
|
|
73
69
|
*
|
|
74
70
|
* The listener should fire on both window zoom changes and switching to a
|
|
75
71
|
* monitor with a different DPI.
|
|
@@ -78,9 +74,9 @@ class ScreenDprMonitor extends Disposable {
|
|
|
78
74
|
private _currentDevicePixelRatio: number;
|
|
79
75
|
private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;
|
|
80
76
|
private _resolutionMediaMatchList: MediaQueryList | undefined;
|
|
81
|
-
private _windowResizeListener = this.
|
|
77
|
+
private _windowResizeListener = this._register(new MutableDisposable());
|
|
82
78
|
|
|
83
|
-
private readonly _onDprChange = this.
|
|
79
|
+
private readonly _onDprChange = this._register(new Emitter<number>());
|
|
84
80
|
public readonly onDprChange = this._onDprChange.event;
|
|
85
81
|
|
|
86
82
|
constructor(private _parentWindow: Window) {
|
|
@@ -95,7 +91,7 @@ class ScreenDprMonitor extends Disposable {
|
|
|
95
91
|
this._setWindowResizeListener();
|
|
96
92
|
|
|
97
93
|
// Setup additional disposables
|
|
98
|
-
this.
|
|
94
|
+
this._register(toDisposable(() => this.clearListener()));
|
|
99
95
|
}
|
|
100
96
|
|
|
101
97
|
|
|
@@ -106,7 +102,7 @@ class ScreenDprMonitor extends Disposable {
|
|
|
106
102
|
}
|
|
107
103
|
|
|
108
104
|
private _setWindowResizeListener(): void {
|
|
109
|
-
this._windowResizeListener.value =
|
|
105
|
+
this._windowResizeListener.value = addDisposableListener(this._parentWindow, 'resize', () => this._setDprAndFireIfDiffers());
|
|
110
106
|
}
|
|
111
107
|
|
|
112
108
|
private _setDprAndFireIfDiffers(): void {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ILinkProvider, ILinkProviderService } from 'browser/services/Services';
|
|
2
|
-
import { Disposable, toDisposable } from 'common/
|
|
2
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
3
3
|
import { IDisposable } from 'common/Types';
|
|
4
4
|
|
|
5
5
|
export class LinkProviderService extends Disposable implements ILinkProviderService {
|
|
@@ -9,7 +9,7 @@ export class LinkProviderService extends Disposable implements ILinkProviderServ
|
|
|
9
9
|
|
|
10
10
|
constructor() {
|
|
11
11
|
super();
|
|
12
|
-
this.
|
|
12
|
+
this._register(toDisposable(() => this.linkProviders.length = 0));
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
|
|
@@ -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 {
|
|
11
|
-
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
|
|
10
|
+
import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
12
11
|
import { DebouncedIdleTask } from 'common/TaskQueue';
|
|
13
|
-
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
|
|
12
|
+
import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
|
|
13
|
+
import { Emitter } from 'vs/base/common/event';
|
|
14
14
|
|
|
15
15
|
interface ISelectionState {
|
|
16
16
|
start: [number, number] | undefined;
|
|
@@ -18,13 +18,17 @@ interface ISelectionState {
|
|
|
18
18
|
columnSelectMode: boolean;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
const enum Constants {
|
|
22
|
+
SYNCHRONIZED_OUTPUT_TIMEOUT_MS = 1000
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
export class RenderService extends Disposable implements IRenderService {
|
|
22
26
|
public serviceBrand: undefined;
|
|
23
27
|
|
|
24
|
-
private _renderer: MutableDisposable<IRenderer> = this.
|
|
28
|
+
private _renderer: MutableDisposable<IRenderer> = this._register(new MutableDisposable());
|
|
25
29
|
private _renderDebouncer: IRenderDebouncerWithCallback;
|
|
26
30
|
private _pausedResizeTask = new DebouncedIdleTask();
|
|
27
|
-
private _observerDisposable = this.
|
|
31
|
+
private _observerDisposable = this._register(new MutableDisposable());
|
|
28
32
|
|
|
29
33
|
private _isPaused: boolean = false;
|
|
30
34
|
private _needsFullRefresh: boolean = false;
|
|
@@ -32,19 +36,20 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
32
36
|
private _needsSelectionRefresh: boolean = false;
|
|
33
37
|
private _canvasWidth: number = 0;
|
|
34
38
|
private _canvasHeight: number = 0;
|
|
39
|
+
private _syncOutputHandler: SynchronizedOutputHandler;
|
|
35
40
|
private _selectionState: ISelectionState = {
|
|
36
41
|
start: undefined,
|
|
37
42
|
end: undefined,
|
|
38
43
|
columnSelectMode: false
|
|
39
44
|
};
|
|
40
45
|
|
|
41
|
-
private readonly _onDimensionsChange = this.
|
|
46
|
+
private readonly _onDimensionsChange = this._register(new Emitter<IRenderDimensions>());
|
|
42
47
|
public readonly onDimensionsChange = this._onDimensionsChange.event;
|
|
43
|
-
private readonly _onRenderedViewportChange = this.
|
|
48
|
+
private readonly _onRenderedViewportChange = this._register(new Emitter<{ start: number, end: number }>());
|
|
44
49
|
public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;
|
|
45
|
-
private readonly _onRender = this.
|
|
50
|
+
private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());
|
|
46
51
|
public readonly onRender = this._onRender.event;
|
|
47
|
-
private readonly _onRefreshRequest = this.
|
|
52
|
+
private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());
|
|
48
53
|
public readonly onRefreshRequest = this._onRefreshRequest.event;
|
|
49
54
|
|
|
50
55
|
public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }
|
|
@@ -52,33 +57,41 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
52
57
|
constructor(
|
|
53
58
|
private _rowCount: number,
|
|
54
59
|
screenElement: HTMLElement,
|
|
55
|
-
@IOptionsService
|
|
60
|
+
@IOptionsService private readonly _optionsService: IOptionsService,
|
|
56
61
|
@ICharSizeService private readonly _charSizeService: ICharSizeService,
|
|
62
|
+
@ICoreService private readonly _coreService: ICoreService,
|
|
57
63
|
@IDecorationService decorationService: IDecorationService,
|
|
58
64
|
@IBufferService bufferService: IBufferService,
|
|
59
|
-
@ICoreBrowserService
|
|
65
|
+
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,
|
|
60
66
|
@IThemeService themeService: IThemeService
|
|
61
67
|
) {
|
|
62
68
|
super();
|
|
63
69
|
|
|
64
|
-
this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end),
|
|
65
|
-
this.
|
|
70
|
+
this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);
|
|
71
|
+
this._register(this._renderDebouncer);
|
|
66
72
|
|
|
67
|
-
this.
|
|
73
|
+
this._syncOutputHandler = new SynchronizedOutputHandler(
|
|
74
|
+
this._coreBrowserService,
|
|
75
|
+
this._coreService,
|
|
76
|
+
() => this._fullRefresh()
|
|
77
|
+
);
|
|
78
|
+
this._register(toDisposable(() => this._syncOutputHandler.dispose()));
|
|
68
79
|
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
80
|
+
this._register(this._coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));
|
|
81
|
+
|
|
82
|
+
this._register(bufferService.onResize(() => this._fullRefresh()));
|
|
83
|
+
this._register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));
|
|
84
|
+
this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));
|
|
85
|
+
this._register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));
|
|
73
86
|
|
|
74
87
|
// Do a full refresh whenever any decoration is added or removed. This may not actually result
|
|
75
88
|
// in changes but since decorations should be used sparingly or added/removed all in the same
|
|
76
89
|
// frame this should have minimal performance impact.
|
|
77
|
-
this.
|
|
78
|
-
this.
|
|
90
|
+
this._register(decorationService.onDecorationRegistered(() => this._fullRefresh()));
|
|
91
|
+
this._register(decorationService.onDecorationRemoved(() => this._fullRefresh()));
|
|
79
92
|
|
|
80
93
|
// Clear the renderer when the a change that could affect glyphs occurs
|
|
81
|
-
this.
|
|
94
|
+
this._register(this._optionsService.onMultipleOptionChange([
|
|
82
95
|
'customGlyphs',
|
|
83
96
|
'drawBoldTextInBrightColors',
|
|
84
97
|
'letterSpacing',
|
|
@@ -96,15 +109,15 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
96
109
|
}));
|
|
97
110
|
|
|
98
111
|
// Refresh the cursor line when the cursor changes
|
|
99
|
-
this.
|
|
112
|
+
this._register(this._optionsService.onMultipleOptionChange([
|
|
100
113
|
'cursorBlink',
|
|
101
114
|
'cursorStyle'
|
|
102
115
|
], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, true)));
|
|
103
116
|
|
|
104
|
-
this.
|
|
117
|
+
this._register(themeService.onChangeColors(() => this._fullRefresh()));
|
|
105
118
|
|
|
106
|
-
this._registerIntersectionObserver(
|
|
107
|
-
this.
|
|
119
|
+
this._registerIntersectionObserver(this._coreBrowserService.window, screenElement);
|
|
120
|
+
this._register(this._coreBrowserService.onWindowChange((w) => this._registerIntersectionObserver(w, screenElement)));
|
|
108
121
|
}
|
|
109
122
|
|
|
110
123
|
private _registerIntersectionObserver(w: Window & typeof globalThis, screenElement: HTMLElement): void {
|
|
@@ -137,6 +150,18 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
137
150
|
this._needsFullRefresh = true;
|
|
138
151
|
return;
|
|
139
152
|
}
|
|
153
|
+
|
|
154
|
+
if (this._coreService.decPrivateModes.synchronizedOutput) {
|
|
155
|
+
this._syncOutputHandler.bufferRows(start, end);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const buffered = this._syncOutputHandler.flush();
|
|
160
|
+
if (buffered) {
|
|
161
|
+
start = Math.min(start, buffered.start);
|
|
162
|
+
end = Math.max(end, buffered.end);
|
|
163
|
+
}
|
|
164
|
+
|
|
140
165
|
if (!isRedrawOnly) {
|
|
141
166
|
this._isNextRenderRedrawOnly = false;
|
|
142
167
|
}
|
|
@@ -148,6 +173,13 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
148
173
|
return;
|
|
149
174
|
}
|
|
150
175
|
|
|
176
|
+
// Skip rendering if synchronized output mode is enabled. This check must happen here
|
|
177
|
+
// (in addition to refreshRows) to handle renders that were queued before the mode was enabled.
|
|
178
|
+
if (this._coreService.decPrivateModes.synchronizedOutput) {
|
|
179
|
+
this._syncOutputHandler.bufferRows(start, end);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
151
183
|
// Since this is debounced, a resize event could have happened between the time a refresh was
|
|
152
184
|
// requested and when this triggers. Clamp the values of start and end to ensure they're valid
|
|
153
185
|
// given the current viewport state.
|
|
@@ -283,3 +315,62 @@ export class RenderService extends Disposable implements IRenderService {
|
|
|
283
315
|
this._renderer.value?.clear();
|
|
284
316
|
}
|
|
285
317
|
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Buffers row refresh requests during synchronized output mode (DEC mode 2026).
|
|
321
|
+
* When the mode is disabled, the accumulated row range is flushed for rendering.
|
|
322
|
+
* A safety timeout ensures rendering occurs even if the end sequence is not received.
|
|
323
|
+
*/
|
|
324
|
+
class SynchronizedOutputHandler {
|
|
325
|
+
private _start: number = 0;
|
|
326
|
+
private _end: number = 0;
|
|
327
|
+
private _timeout: number | undefined;
|
|
328
|
+
private _isBuffering: boolean = false;
|
|
329
|
+
|
|
330
|
+
constructor(
|
|
331
|
+
private readonly _coreBrowserService: ICoreBrowserService,
|
|
332
|
+
private readonly _coreService: ICoreService,
|
|
333
|
+
private readonly _onTimeout: () => void
|
|
334
|
+
) {}
|
|
335
|
+
|
|
336
|
+
public bufferRows(start: number, end: number): void {
|
|
337
|
+
if (!this._isBuffering) {
|
|
338
|
+
this._start = start;
|
|
339
|
+
this._end = end;
|
|
340
|
+
this._isBuffering = true;
|
|
341
|
+
} else {
|
|
342
|
+
this._start = Math.min(this._start, start);
|
|
343
|
+
this._end = Math.max(this._end, end);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
if (this._timeout === undefined) {
|
|
347
|
+
this._timeout = this._coreBrowserService.window.setTimeout(() => {
|
|
348
|
+
this._timeout = undefined;
|
|
349
|
+
this._coreService.decPrivateModes.synchronizedOutput = false;
|
|
350
|
+
this._onTimeout();
|
|
351
|
+
}, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
public flush(): { start: number, end: number } | undefined {
|
|
356
|
+
if (this._timeout !== undefined) {
|
|
357
|
+
this._coreBrowserService.window.clearTimeout(this._timeout);
|
|
358
|
+
this._timeout = undefined;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (!this._isBuffering) {
|
|
362
|
+
return undefined;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const result = { start: this._start, end: this._end };
|
|
366
|
+
this._isBuffering = false;
|
|
367
|
+
return result;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
public dispose(): void {
|
|
371
|
+
if (this._timeout !== undefined) {
|
|
372
|
+
this._coreBrowserService.window.clearTimeout(this._timeout);
|
|
373
|
+
this._timeout = undefined;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
@@ -9,14 +9,14 @@ import { moveToCellSequence } from 'browser/input/MoveToCell';
|
|
|
9
9
|
import { SelectionModel } from 'browser/selection/SelectionModel';
|
|
10
10
|
import { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types';
|
|
11
11
|
import { ICoreBrowserService, IMouseService, IRenderService, ISelectionService } from 'browser/services/Services';
|
|
12
|
-
import {
|
|
13
|
-
import { Disposable, toDisposable } from 'common/Lifecycle';
|
|
12
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
14
13
|
import * as Browser from 'common/Platform';
|
|
15
14
|
import { IBufferLine, IDisposable } from 'common/Types';
|
|
16
15
|
import { getRangeLength } from 'common/buffer/BufferRange';
|
|
17
16
|
import { CellData } from 'common/buffer/CellData';
|
|
18
17
|
import { IBuffer } from 'common/buffer/Types';
|
|
19
18
|
import { IBufferService, ICoreService, IOptionsService } from 'common/services/Services';
|
|
19
|
+
import { Emitter } from 'vs/base/common/event';
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* The number of pixels the mouse needs to be above or below the viewport in
|
|
@@ -111,13 +111,13 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
111
111
|
private _oldSelectionStart: [number, number] | undefined = undefined;
|
|
112
112
|
private _oldSelectionEnd: [number, number] | undefined = undefined;
|
|
113
113
|
|
|
114
|
-
private readonly _onLinuxMouseSelection = this.
|
|
114
|
+
private readonly _onLinuxMouseSelection = this._register(new Emitter<string>());
|
|
115
115
|
public readonly onLinuxMouseSelection = this._onLinuxMouseSelection.event;
|
|
116
|
-
private readonly _onRedrawRequest = this.
|
|
116
|
+
private readonly _onRedrawRequest = this._register(new Emitter<ISelectionRedrawRequestEvent>());
|
|
117
117
|
public readonly onRequestRedraw = this._onRedrawRequest.event;
|
|
118
|
-
private readonly _onSelectionChange = this.
|
|
118
|
+
private readonly _onSelectionChange = this._register(new Emitter<void>());
|
|
119
119
|
public readonly onSelectionChange = this._onSelectionChange.event;
|
|
120
|
-
private readonly _onRequestScrollLines = this.
|
|
120
|
+
private readonly _onRequestScrollLines = this._register(new Emitter<ISelectionRequestScrollLinesEvent>());
|
|
121
121
|
public readonly onRequestScrollLines = this._onRequestScrollLines.event;
|
|
122
122
|
|
|
123
123
|
constructor(
|
|
@@ -142,16 +142,24 @@ export class SelectionService extends Disposable implements ISelectionService {
|
|
|
142
142
|
}
|
|
143
143
|
});
|
|
144
144
|
this._trimListener = this._bufferService.buffer.lines.onTrim(amount => this._handleTrim(amount));
|
|
145
|
-
this.
|
|
145
|
+
this._register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));
|
|
146
146
|
|
|
147
147
|
this.enable();
|
|
148
148
|
|
|
149
149
|
this._model = new SelectionModel(this._bufferService);
|
|
150
150
|
this._activeSelectionMode = SelectionMode.NORMAL;
|
|
151
151
|
|
|
152
|
-
this.
|
|
152
|
+
this._register(toDisposable(() => {
|
|
153
153
|
this._removeMouseDownListeners();
|
|
154
154
|
}));
|
|
155
|
+
|
|
156
|
+
// Clear selection when resizing vertically. This experience could be improved, this is the
|
|
157
|
+
// simple option to fix the buggy behavior. https://github.com/xtermjs/xterm.js/issues/5300
|
|
158
|
+
this._register(this._bufferService.onResize(e => {
|
|
159
|
+
if (e.rowsChanged) {
|
|
160
|
+
this.clearSelection();
|
|
161
|
+
}
|
|
162
|
+
}));
|
|
155
163
|
}
|
|
156
164
|
|
|
157
165
|
public reset(): void {
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { IEvent } from 'common/EventEmitter';
|
|
7
6
|
import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types';
|
|
8
7
|
import { IColorSet, ILink, ReadonlyColorSet } from 'browser/Types';
|
|
9
8
|
import { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types';
|
|
10
9
|
import { createDecorator } from 'common/services/ServiceRegistry';
|
|
11
10
|
import { AllColorIndex, IDisposable } from 'common/Types';
|
|
11
|
+
import type { Event } from 'vs/base/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: Event<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: Event<number>;
|
|
33
|
+
readonly onWindowChange: Event<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.
|
|
@@ -61,17 +61,17 @@ export const IRenderService = createDecorator<IRenderService>('RenderService');
|
|
|
61
61
|
export interface IRenderService extends IDisposable {
|
|
62
62
|
serviceBrand: undefined;
|
|
63
63
|
|
|
64
|
-
onDimensionsChange:
|
|
64
|
+
onDimensionsChange: Event<IRenderDimensions>;
|
|
65
65
|
/**
|
|
66
66
|
* Fires when buffer changes are rendered. This does not fire when only cursor
|
|
67
67
|
* or selections are rendered.
|
|
68
68
|
*/
|
|
69
|
-
onRenderedViewportChange:
|
|
69
|
+
onRenderedViewportChange: Event<{ start: number, end: number }>;
|
|
70
70
|
/**
|
|
71
71
|
* Fires on render
|
|
72
72
|
*/
|
|
73
|
-
onRender:
|
|
74
|
-
onRefreshRequest:
|
|
73
|
+
onRender: Event<{ start: number, end: number }>;
|
|
74
|
+
onRefreshRequest: Event<{ start: number, end: number }>;
|
|
75
75
|
|
|
76
76
|
dimensions: IRenderDimensions;
|
|
77
77
|
|
|
@@ -101,10 +101,10 @@ export interface ISelectionService {
|
|
|
101
101
|
readonly selectionStart: [number, number] | undefined;
|
|
102
102
|
readonly selectionEnd: [number, number] | undefined;
|
|
103
103
|
|
|
104
|
-
readonly onLinuxMouseSelection:
|
|
105
|
-
readonly onRequestRedraw:
|
|
106
|
-
readonly onRequestScrollLines:
|
|
107
|
-
readonly onSelectionChange:
|
|
104
|
+
readonly onLinuxMouseSelection: Event<string>;
|
|
105
|
+
readonly onRequestRedraw: Event<ISelectionRequestRedrawEvent>;
|
|
106
|
+
readonly onRequestScrollLines: Event<ISelectionRequestScrollLinesEvent>;
|
|
107
|
+
readonly onSelectionChange: Event<void>;
|
|
108
108
|
|
|
109
109
|
disable(): void;
|
|
110
110
|
enable(): void;
|
|
@@ -136,7 +136,7 @@ export interface IThemeService {
|
|
|
136
136
|
|
|
137
137
|
readonly colors: ReadonlyColorSet;
|
|
138
138
|
|
|
139
|
-
readonly onChangeColors:
|
|
139
|
+
readonly onChangeColors: Event<ReadonlyColorSet>;
|
|
140
140
|
|
|
141
141
|
restoreColor(slot?: AllColorIndex): void;
|
|
142
142
|
/**
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
|
|
6
6
|
import { ColorContrastCache } from 'browser/ColorContrastCache';
|
|
7
7
|
import { IThemeService } from 'browser/services/Services';
|
|
8
|
-
import { IColorContrastCache, IColorSet, ReadonlyColorSet } from 'browser/Types';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { Disposable } from 'common/Lifecycle';
|
|
8
|
+
import { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from 'browser/Types';
|
|
9
|
+
import { color, css, NULL_COLOR } from 'common/Color';
|
|
10
|
+
import { Disposable } from 'vs/base/common/lifecycle';
|
|
12
11
|
import { IOptionsService, ITheme } from 'common/services/Services';
|
|
13
12
|
import { AllColorIndex, IColor, SpecialColorIndex } from 'common/Types';
|
|
13
|
+
import { Emitter } from 'vs/base/common/event';
|
|
14
14
|
|
|
15
15
|
interface IRestoreColorSet {
|
|
16
16
|
foreground: IColor;
|
|
@@ -23,59 +23,12 @@ interface IRestoreColorSet {
|
|
|
23
23
|
const DEFAULT_FOREGROUND = css.toColor('#ffffff');
|
|
24
24
|
const DEFAULT_BACKGROUND = css.toColor('#000000');
|
|
25
25
|
const DEFAULT_CURSOR = css.toColor('#ffffff');
|
|
26
|
-
const DEFAULT_CURSOR_ACCENT =
|
|
26
|
+
const DEFAULT_CURSOR_ACCENT = DEFAULT_BACKGROUND;
|
|
27
27
|
const DEFAULT_SELECTION = {
|
|
28
28
|
css: 'rgba(255, 255, 255, 0.3)',
|
|
29
29
|
rgba: 0xFFFFFF4D
|
|
30
30
|
};
|
|
31
|
-
|
|
32
|
-
// An IIFE to generate DEFAULT_ANSI_COLORS.
|
|
33
|
-
export const DEFAULT_ANSI_COLORS = Object.freeze((() => {
|
|
34
|
-
const colors = [
|
|
35
|
-
// dark:
|
|
36
|
-
css.toColor('#2e3436'),
|
|
37
|
-
css.toColor('#cc0000'),
|
|
38
|
-
css.toColor('#4e9a06'),
|
|
39
|
-
css.toColor('#c4a000'),
|
|
40
|
-
css.toColor('#3465a4'),
|
|
41
|
-
css.toColor('#75507b'),
|
|
42
|
-
css.toColor('#06989a'),
|
|
43
|
-
css.toColor('#d3d7cf'),
|
|
44
|
-
// bright:
|
|
45
|
-
css.toColor('#555753'),
|
|
46
|
-
css.toColor('#ef2929'),
|
|
47
|
-
css.toColor('#8ae234'),
|
|
48
|
-
css.toColor('#fce94f'),
|
|
49
|
-
css.toColor('#729fcf'),
|
|
50
|
-
css.toColor('#ad7fa8'),
|
|
51
|
-
css.toColor('#34e2e2'),
|
|
52
|
-
css.toColor('#eeeeec')
|
|
53
|
-
];
|
|
54
|
-
|
|
55
|
-
// Fill in the remaining 240 ANSI colors.
|
|
56
|
-
// Generate colors (16-231)
|
|
57
|
-
const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];
|
|
58
|
-
for (let i = 0; i < 216; i++) {
|
|
59
|
-
const r = v[(i / 36) % 6 | 0];
|
|
60
|
-
const g = v[(i / 6) % 6 | 0];
|
|
61
|
-
const b = v[i % 6];
|
|
62
|
-
colors.push({
|
|
63
|
-
css: channels.toCss(r, g, b),
|
|
64
|
-
rgba: channels.toRgba(r, g, b)
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Generate greys (232-255)
|
|
69
|
-
for (let i = 0; i < 24; i++) {
|
|
70
|
-
const c = 8 + i * 10;
|
|
71
|
-
colors.push({
|
|
72
|
-
css: channels.toCss(c, c, c),
|
|
73
|
-
rgba: channels.toRgba(c, c, c)
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
return colors;
|
|
78
|
-
})());
|
|
31
|
+
const DEFAULT_OVERVIEW_RULER_BORDER = DEFAULT_FOREGROUND;
|
|
79
32
|
|
|
80
33
|
export class ThemeService extends Disposable implements IThemeService {
|
|
81
34
|
public serviceBrand: undefined;
|
|
@@ -87,7 +40,7 @@ export class ThemeService extends Disposable implements IThemeService {
|
|
|
87
40
|
|
|
88
41
|
public get colors(): ReadonlyColorSet { return this._colors; }
|
|
89
42
|
|
|
90
|
-
private readonly _onChangeColors = this.
|
|
43
|
+
private readonly _onChangeColors = this._register(new Emitter<ReadonlyColorSet>());
|
|
91
44
|
public readonly onChangeColors = this._onChangeColors.event;
|
|
92
45
|
|
|
93
46
|
constructor(
|
|
@@ -105,6 +58,10 @@ export class ThemeService extends Disposable implements IThemeService {
|
|
|
105
58
|
selectionBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),
|
|
106
59
|
selectionInactiveBackgroundTransparent: DEFAULT_SELECTION,
|
|
107
60
|
selectionInactiveBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION),
|
|
61
|
+
scrollbarSliderBackground: color.opacity(DEFAULT_FOREGROUND, 0.2),
|
|
62
|
+
scrollbarSliderHoverBackground: color.opacity(DEFAULT_FOREGROUND, 0.4),
|
|
63
|
+
scrollbarSliderActiveBackground: color.opacity(DEFAULT_FOREGROUND, 0.5),
|
|
64
|
+
overviewRulerBorder: DEFAULT_FOREGROUND,
|
|
108
65
|
ansi: DEFAULT_ANSI_COLORS.slice(),
|
|
109
66
|
contrastCache: this._contrastCache,
|
|
110
67
|
halfContrastCache: this._halfContrastCache
|
|
@@ -112,8 +69,8 @@ export class ThemeService extends Disposable implements IThemeService {
|
|
|
112
69
|
this._updateRestoreColors();
|
|
113
70
|
this._setTheme(this._optionsService.rawOptions.theme);
|
|
114
71
|
|
|
115
|
-
this.
|
|
116
|
-
this.
|
|
72
|
+
this._register(this._optionsService.onSpecificOptionChange('minimumContrastRatio', () => this._contrastCache.clear()));
|
|
73
|
+
this._register(this._optionsService.onSpecificOptionChange('theme', () => this._setTheme(this._optionsService.rawOptions.theme)));
|
|
117
74
|
}
|
|
118
75
|
|
|
119
76
|
/**
|
|
@@ -125,8 +82,8 @@ export class ThemeService extends Disposable implements IThemeService {
|
|
|
125
82
|
const colors = this._colors;
|
|
126
83
|
colors.foreground = parseColor(theme.foreground, DEFAULT_FOREGROUND);
|
|
127
84
|
colors.background = parseColor(theme.background, DEFAULT_BACKGROUND);
|
|
128
|
-
colors.cursor = parseColor(theme.cursor, DEFAULT_CURSOR);
|
|
129
|
-
colors.cursorAccent = parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT);
|
|
85
|
+
colors.cursor = color.blend(colors.background, parseColor(theme.cursor, DEFAULT_CURSOR));
|
|
86
|
+
colors.cursorAccent = color.blend(colors.background, parseColor(theme.cursorAccent, DEFAULT_CURSOR_ACCENT));
|
|
130
87
|
colors.selectionBackgroundTransparent = parseColor(theme.selectionBackground, DEFAULT_SELECTION);
|
|
131
88
|
colors.selectionBackgroundOpaque = color.blend(colors.background, colors.selectionBackgroundTransparent);
|
|
132
89
|
colors.selectionInactiveBackgroundTransparent = parseColor(theme.selectionInactiveBackground, colors.selectionBackgroundTransparent);
|
|
@@ -148,6 +105,10 @@ export class ThemeService extends Disposable implements IThemeService {
|
|
|
148
105
|
const opacity = 0.3;
|
|
149
106
|
colors.selectionInactiveBackgroundTransparent = color.opacity(colors.selectionInactiveBackgroundTransparent, opacity);
|
|
150
107
|
}
|
|
108
|
+
colors.scrollbarSliderBackground = parseColor(theme.scrollbarSliderBackground, color.opacity(colors.foreground, 0.2));
|
|
109
|
+
colors.scrollbarSliderHoverBackground = parseColor(theme.scrollbarSliderHoverBackground, color.opacity(colors.foreground, 0.4));
|
|
110
|
+
colors.scrollbarSliderActiveBackground = parseColor(theme.scrollbarSliderActiveBackground, color.opacity(colors.foreground, 0.5));
|
|
111
|
+
colors.overviewRulerBorder = parseColor(theme.overviewRulerBorder, DEFAULT_OVERVIEW_RULER_BORDER);
|
|
151
112
|
colors.ansi = DEFAULT_ANSI_COLORS.slice();
|
|
152
113
|
colors.ansi[0] = parseColor(theme.black, DEFAULT_ANSI_COLORS[0]);
|
|
153
114
|
colors.ansi[1] = parseColor(theme.red, DEFAULT_ANSI_COLORS[1]);
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { ICircularList } from 'common/Types';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { Disposable } from 'vs/base/common/lifecycle';
|
|
8
|
+
import { Emitter } from 'vs/base/common/event';
|
|
9
9
|
|
|
10
10
|
export interface IInsertEvent {
|
|
11
11
|
index: number;
|
|
@@ -26,11 +26,11 @@ export class CircularList<T> extends Disposable implements ICircularList<T> {
|
|
|
26
26
|
private _startIndex: number;
|
|
27
27
|
private _length: number;
|
|
28
28
|
|
|
29
|
-
public readonly onDeleteEmitter = this.
|
|
29
|
+
public readonly onDeleteEmitter = this._register(new Emitter<IDeleteEvent>());
|
|
30
30
|
public readonly onDelete = this.onDeleteEmitter.event;
|
|
31
|
-
public readonly onInsertEmitter = this.
|
|
31
|
+
public readonly onInsertEmitter = this._register(new Emitter<IInsertEvent>());
|
|
32
32
|
public readonly onInsert = this.onInsertEmitter.event;
|
|
33
|
-
public readonly onTrimEmitter = this.
|
|
33
|
+
public readonly onTrimEmitter = this._register(new Emitter<number>());
|
|
34
34
|
public readonly onTrim = this.onTrimEmitter.event;
|
|
35
35
|
|
|
36
36
|
constructor(
|