@xterm/xterm 6.1.0-beta.21 → 6.1.0-beta.210

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.
Files changed (158) hide show
  1. package/README.md +61 -38
  2. package/css/xterm.css +29 -22
  3. package/lib/xterm.js +1 -1
  4. package/lib/xterm.js.map +1 -1
  5. package/lib/xterm.mjs +8 -34
  6. package/lib/xterm.mjs.map +4 -4
  7. package/package.json +24 -13
  8. package/src/browser/AccessibilityManager.ts +6 -3
  9. package/src/browser/Clipboard.ts +6 -3
  10. package/src/browser/CoreBrowserTerminal.ts +147 -318
  11. package/src/browser/Dom.ts +178 -0
  12. package/src/browser/Linkifier.ts +11 -11
  13. package/src/browser/OscLinkProvider.ts +3 -1
  14. package/src/browser/RenderDebouncer.ts +2 -2
  15. package/src/browser/TimeBasedDebouncer.ts +2 -2
  16. package/src/browser/Types.ts +12 -11
  17. package/src/browser/Viewport.ts +55 -20
  18. package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
  19. package/src/browser/decorations/OverviewRulerRenderer.ts +33 -17
  20. package/src/browser/input/CompositionHelper.ts +44 -8
  21. package/src/browser/public/Terminal.ts +25 -28
  22. package/src/browser/renderer/dom/DomRenderer.ts +205 -41
  23. package/src/browser/renderer/dom/DomRendererRowFactory.ts +19 -13
  24. package/src/browser/renderer/dom/WidthCache.ts +54 -52
  25. package/src/browser/renderer/shared/Constants.ts +7 -0
  26. package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
  27. package/src/browser/renderer/shared/Types.ts +8 -2
  28. package/src/browser/scrollable/abstractScrollbar.ts +300 -0
  29. package/src/browser/scrollable/fastDomNode.ts +126 -0
  30. package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
  31. package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
  32. package/src/browser/scrollable/mouseEvent.ts +292 -0
  33. package/src/browser/scrollable/scrollable.ts +486 -0
  34. package/src/browser/scrollable/scrollableElement.ts +579 -0
  35. package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
  36. package/src/browser/scrollable/scrollbarArrow.ts +110 -0
  37. package/src/browser/scrollable/scrollbarState.ts +246 -0
  38. package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
  39. package/src/browser/scrollable/touch.ts +485 -0
  40. package/src/browser/scrollable/verticalScrollbar.ts +143 -0
  41. package/src/browser/scrollable/widget.ts +23 -0
  42. package/src/browser/services/CharSizeService.ts +2 -2
  43. package/src/browser/services/CoreBrowserService.ts +7 -5
  44. package/src/browser/services/KeyboardService.ts +67 -0
  45. package/src/browser/services/LinkProviderService.ts +1 -1
  46. package/src/browser/services/MouseCoordsService.ts +47 -0
  47. package/src/browser/services/MouseService.ts +518 -25
  48. package/src/browser/services/RenderService.ts +22 -15
  49. package/src/browser/services/SelectionService.ts +16 -8
  50. package/src/browser/services/Services.ts +40 -17
  51. package/src/browser/services/ThemeService.ts +2 -2
  52. package/src/common/Async.ts +105 -0
  53. package/src/common/CircularList.ts +2 -2
  54. package/src/common/Color.ts +8 -0
  55. package/src/common/CoreTerminal.ts +28 -18
  56. package/src/common/Event.ts +118 -0
  57. package/src/common/InputHandler.ts +263 -43
  58. package/src/common/Lifecycle.ts +113 -0
  59. package/src/common/Platform.ts +13 -3
  60. package/src/common/SortedList.ts +7 -3
  61. package/src/common/TaskQueue.ts +14 -5
  62. package/src/common/Types.ts +35 -15
  63. package/src/common/Version.ts +9 -0
  64. package/src/common/buffer/Buffer.ts +20 -14
  65. package/src/common/buffer/BufferLine.ts +4 -5
  66. package/src/common/buffer/BufferSet.ts +7 -6
  67. package/src/common/buffer/CellData.ts +57 -0
  68. package/src/common/buffer/Marker.ts +2 -2
  69. package/src/common/buffer/Types.ts +6 -2
  70. package/src/common/data/EscapeSequences.ts +71 -70
  71. package/src/common/input/Keyboard.ts +14 -7
  72. package/src/common/input/KittyKeyboard.ts +519 -0
  73. package/src/common/input/Win32InputMode.ts +297 -0
  74. package/src/common/input/WriteBuffer.ts +34 -2
  75. package/src/common/input/XParseColor.ts +2 -2
  76. package/src/common/parser/ApcParser.ts +245 -0
  77. package/src/common/parser/Constants.ts +22 -4
  78. package/src/common/parser/DcsParser.ts +5 -5
  79. package/src/common/parser/EscapeSequenceParser.ts +167 -57
  80. package/src/common/parser/OscParser.ts +5 -5
  81. package/src/common/parser/Params.ts +13 -0
  82. package/src/common/parser/Types.ts +36 -2
  83. package/src/common/public/BufferLineApiView.ts +2 -2
  84. package/src/common/public/BufferNamespaceApi.ts +2 -2
  85. package/src/common/public/ParserApi.ts +3 -0
  86. package/src/common/services/BufferService.ts +8 -5
  87. package/src/common/services/CharsetService.ts +4 -0
  88. package/src/common/services/CoreService.ts +18 -4
  89. package/src/common/services/DecorationService.ts +24 -8
  90. package/src/common/services/LogService.ts +1 -31
  91. package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +21 -132
  92. package/src/common/services/OptionsService.ts +13 -4
  93. package/src/common/services/Services.ts +47 -40
  94. package/src/common/services/UnicodeService.ts +1 -1
  95. package/typings/xterm.d.ts +316 -32
  96. package/src/common/TypedArrayUtils.ts +0 -17
  97. package/src/vs/base/browser/browser.ts +0 -141
  98. package/src/vs/base/browser/canIUse.ts +0 -49
  99. package/src/vs/base/browser/dom.ts +0 -2369
  100. package/src/vs/base/browser/fastDomNode.ts +0 -316
  101. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  102. package/src/vs/base/browser/iframe.ts +0 -135
  103. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  104. package/src/vs/base/browser/mouseEvent.ts +0 -229
  105. package/src/vs/base/browser/touch.ts +0 -372
  106. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  107. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  108. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  109. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  110. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  111. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  112. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  113. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  114. package/src/vs/base/browser/ui/widget.ts +0 -57
  115. package/src/vs/base/browser/window.ts +0 -14
  116. package/src/vs/base/common/arrays.ts +0 -887
  117. package/src/vs/base/common/arraysFind.ts +0 -202
  118. package/src/vs/base/common/assert.ts +0 -71
  119. package/src/vs/base/common/async.ts +0 -1992
  120. package/src/vs/base/common/cancellation.ts +0 -148
  121. package/src/vs/base/common/charCode.ts +0 -450
  122. package/src/vs/base/common/collections.ts +0 -140
  123. package/src/vs/base/common/decorators.ts +0 -130
  124. package/src/vs/base/common/equals.ts +0 -146
  125. package/src/vs/base/common/errors.ts +0 -303
  126. package/src/vs/base/common/event.ts +0 -1778
  127. package/src/vs/base/common/functional.ts +0 -32
  128. package/src/vs/base/common/hash.ts +0 -316
  129. package/src/vs/base/common/iterator.ts +0 -159
  130. package/src/vs/base/common/keyCodes.ts +0 -526
  131. package/src/vs/base/common/keybindings.ts +0 -284
  132. package/src/vs/base/common/lazy.ts +0 -47
  133. package/src/vs/base/common/lifecycle.ts +0 -801
  134. package/src/vs/base/common/linkedList.ts +0 -142
  135. package/src/vs/base/common/map.ts +0 -202
  136. package/src/vs/base/common/numbers.ts +0 -98
  137. package/src/vs/base/common/observable.ts +0 -76
  138. package/src/vs/base/common/observableInternal/api.ts +0 -31
  139. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  140. package/src/vs/base/common/observableInternal/base.ts +0 -489
  141. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  142. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  143. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  144. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  145. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  146. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  147. package/src/vs/base/common/platform.ts +0 -281
  148. package/src/vs/base/common/scrollable.ts +0 -522
  149. package/src/vs/base/common/sequence.ts +0 -34
  150. package/src/vs/base/common/stopwatch.ts +0 -43
  151. package/src/vs/base/common/strings.ts +0 -557
  152. package/src/vs/base/common/symbols.ts +0 -9
  153. package/src/vs/base/common/uint.ts +0 -59
  154. package/src/vs/patches/nls.ts +0 -90
  155. package/src/vs/typings/base-common.d.ts +0 -20
  156. package/src/vs/typings/require.d.ts +0 -42
  157. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  158. 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 'vs/base/common/lifecycle';
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 'vs/base/common/event';
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,7 +27,7 @@ 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 = new DebouncedIdleTask();
30
+ private _pausedResizeTask: DebouncedIdleTask;
31
31
  private _observerDisposable = this._register(new MutableDisposable());
32
32
 
33
33
  private _isPaused: boolean = false;
@@ -58,6 +58,7 @@ export class RenderService extends Disposable implements IRenderService {
58
58
  private _rowCount: number,
59
59
  screenElement: HTMLElement,
60
60
  @IOptionsService private readonly _optionsService: IOptionsService,
61
+ @ILogService private readonly _logService: ILogService,
61
62
  @ICharSizeService private readonly _charSizeService: ICharSizeService,
62
63
  @ICoreService private readonly _coreService: ICoreService,
63
64
  @IDecorationService decorationService: IDecorationService,
@@ -67,6 +68,8 @@ export class RenderService extends Disposable implements IRenderService {
67
68
  ) {
68
69
  super();
69
70
 
71
+ this._pausedResizeTask = this._register(new DebouncedIdleTask(this._logService));
72
+
70
73
  this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);
71
74
  this._register(this._renderDebouncer);
72
75
 
@@ -111,7 +114,7 @@ export class RenderService extends Disposable implements IRenderService {
111
114
  this._register(this._optionsService.onMultipleOptionChange([
112
115
  'cursorBlink',
113
116
  'cursorStyle'
114
- ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, true)));
117
+ ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, undefined, true)));
115
118
 
116
119
  this._register(themeService.onChangeColors(() => this._fullRefresh()));
117
120
 
@@ -131,6 +134,7 @@ export class RenderService extends Disposable implements IRenderService {
131
134
 
132
135
  private _handleIntersectionChange(entry: IntersectionObserverEntry): void {
133
136
  this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;
137
+ this._renderer.value?.handleViewportVisibilityChange?.(!this._isPaused);
134
138
 
135
139
  // Terminal was hidden on open
136
140
  if (!this._isPaused && !this._charSizeService.hasValidSize) {
@@ -144,7 +148,7 @@ export class RenderService extends Disposable implements IRenderService {
144
148
  }
145
149
  }
146
150
 
147
- public refreshRows(start: number, end: number, isRedrawOnly: boolean = false): void {
151
+ public refreshRows(start: number, end: number, sync: boolean = false, isRedrawOnly: boolean = false): void {
148
152
  if (this._isPaused) {
149
153
  this._needsFullRefresh = true;
150
154
  return;
@@ -164,7 +168,12 @@ export class RenderService extends Disposable implements IRenderService {
164
168
  if (!isRedrawOnly) {
165
169
  this._isNextRenderRedrawOnly = false;
166
170
  }
167
- this._renderDebouncer.refresh(start, end, this._rowCount);
171
+
172
+ if (sync) {
173
+ this._renderRows(start, end);
174
+ } else {
175
+ this._renderDebouncer.refresh(start, end, this._rowCount);
176
+ }
168
177
  }
169
178
 
170
179
  private _renderRows(start: number, end: number): void {
@@ -234,7 +243,7 @@ export class RenderService extends Disposable implements IRenderService {
234
243
  this._renderer.value = renderer;
235
244
  // If the value was not set, the terminal is being disposed so ignore it
236
245
  if (this._renderer.value) {
237
- this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
246
+ this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, e.sync, true));
238
247
 
239
248
  // Force a refresh
240
249
  this._needsSelectionRefresh = true;
@@ -342,13 +351,11 @@ class SynchronizedOutputHandler {
342
351
  this._end = Math.max(this._end, end);
343
352
  }
344
353
 
345
- if (this._timeout === undefined) {
346
- this._timeout = this._coreBrowserService.window.setTimeout(() => {
347
- this._timeout = undefined;
348
- this._coreService.decPrivateModes.synchronizedOutput = false;
349
- this._onTimeout();
350
- }, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);
351
- }
354
+ this._timeout ??= this._coreBrowserService.window.setTimeout(() => {
355
+ this._timeout = undefined;
356
+ this._coreService.decPrivateModes.synchronizedOutput = false;
357
+ this._onTimeout();
358
+ }, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);
352
359
  }
353
360
 
354
361
  public flush(): { start: number, end: number } | undefined {
@@ -8,15 +8,15 @@ 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, IMouseService, IRenderService, ISelectionService } from 'browser/services/Services';
12
- import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
11
+ import { ICoreBrowserService, IMouseCoordsService, IRenderService, ISelectionService } from 'browser/services/Services';
12
+ import { Disposable, 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 'vs/base/common/event';
19
+ import { Emitter } from 'common/Event';
20
20
 
21
21
  /**
22
22
  * The number of pixels the mouse needs to be above or below the viewport in
@@ -126,7 +126,7 @@ export class SelectionService extends Disposable implements ISelectionService {
126
126
  private readonly _linkifier: ILinkifier2,
127
127
  @IBufferService private readonly _bufferService: IBufferService,
128
128
  @ICoreService private readonly _coreService: ICoreService,
129
- @IMouseService private readonly _mouseService: IMouseService,
129
+ @IMouseCoordsService private readonly _mouseCoordsService: IMouseCoordsService,
130
130
  @IOptionsService private readonly _optionsService: IOptionsService,
131
131
  @IRenderService private readonly _renderService: IRenderService,
132
132
  @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService
@@ -395,7 +395,7 @@ export class SelectionService extends Disposable implements ISelectionService {
395
395
  * @param event The mouse event.
396
396
  */
397
397
  private _getMouseBufferCoords(event: MouseEvent): [number, number] | undefined {
398
- const coords = this._mouseService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);
398
+ const coords = this._mouseCoordsService.getCoords(event, this._screenElement, this._bufferService.cols, this._bufferService.rows, true);
399
399
  if (!coords) {
400
400
  return undefined;
401
401
  }
@@ -532,6 +532,9 @@ export class SelectionService extends Disposable implements ISelectionService {
532
532
  * @param event The mouse event.
533
533
  */
534
534
  private _handleSingleClick(event: MouseEvent): void {
535
+ // Track if there was a selection before clearing
536
+ const hadSelection = this.hasSelection;
537
+
535
538
  this._model.selectionStartLength = 0;
536
539
  this._model.isSelectAllActive = false;
537
540
  this._activeSelectionMode = this.shouldColumnSelect(event) ? SelectionMode.COLUMN : SelectionMode.NORMAL;
@@ -543,6 +546,11 @@ export class SelectionService extends Disposable implements ISelectionService {
543
546
  }
544
547
  this._model.selectionEnd = undefined;
545
548
 
549
+ // Fire selection change event if a selection was cleared
550
+ if (hadSelection) {
551
+ this._fireOnSelectionChange(this._model.finalSelectionStart, this._model.finalSelectionEnd, false);
552
+ }
553
+
546
554
  // Ensure the line exists
547
555
  const line = this._bufferService.buffer.lines.get(this._model.selectionStart[1]);
548
556
  if (!line) {
@@ -707,7 +715,7 @@ export class SelectionService extends Disposable implements ISelectionService {
707
715
 
708
716
  if (this.selectionText.length <= 1 && timeElapsed < ALT_CLICK_MOVE_CURSOR_TIME && event.altKey && this._optionsService.rawOptions.altClickMovesCursor) {
709
717
  if (this._bufferService.buffer.ybase === this._bufferService.buffer.ydisp) {
710
- const coordinates = this._mouseService.getCoords(
718
+ const coordinates = this._mouseCoordsService.getCoords(
711
719
  event,
712
720
  this._element,
713
721
  this._bufferService.cols,
@@ -1013,7 +1021,7 @@ export class SelectionService extends Disposable implements ISelectionService {
1013
1021
  * word logic.
1014
1022
  * @param cell The cell to check.
1015
1023
  */
1016
- private _isCharWordSeparator(cell: CellData): boolean {
1024
+ private _isCharWordSeparator(cell: ICellData): boolean {
1017
1025
  // Zero width characters are never separators as they are always to the
1018
1026
  // right of wide characters
1019
1027
  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 { Event } from 'vs/base/common/event';
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: Event<void>;
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: Event<number>;
33
- readonly onWindowChange: Event<Window & typeof globalThis>;
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 IMouseService = createDecorator<IMouseService>('MouseService');
53
- export interface IMouseService {
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: Event<IRenderDimensions>;
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: Event<{ start: number, end: number }>;
83
+ onRenderedViewportChange: IEvent<{ start: number, end: number }>;
70
84
  /**
71
85
  * Fires on render
72
86
  */
73
- onRender: Event<{ start: number, end: number }>;
74
- onRefreshRequest: Event<{ start: number, end: number }>;
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: Event<string>;
105
- readonly onRequestRedraw: Event<ISelectionRequestRedrawEvent>;
106
- readonly onRequestScrollLines: Event<ISelectionRequestScrollLinesEvent>;
107
- readonly onSelectionChange: Event<void>;
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: Event<ReadonlyColorSet>;
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 'vs/base/common/lifecycle';
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 'vs/base/common/event';
13
+ import { Emitter } from 'common/Event';
14
14
 
15
15
  interface IRestoreColorSet {
16
16
  foreground: IColor;
@@ -0,0 +1,105 @@
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
+ export class IntervalTimer implements IDisposable {
77
+ private _disposable: IDisposable | undefined;
78
+ private _isDisposed = false;
79
+
80
+ public cancel(): void {
81
+ this._disposable?.dispose();
82
+ this._disposable = undefined;
83
+ }
84
+
85
+ public cancelAndSet(runner: () => void, interval: number, context: Window | typeof globalThis = globalThis): void {
86
+ if (this._isDisposed) {
87
+ throw new Error('Calling cancelAndSet on a disposed IntervalTimer');
88
+ }
89
+ this.cancel();
90
+ const handle = context.setInterval(() => {
91
+ runner();
92
+ }, interval);
93
+ this._disposable = {
94
+ dispose: () => {
95
+ context.clearInterval(handle as any);
96
+ this._disposable = undefined;
97
+ }
98
+ };
99
+ }
100
+
101
+ public dispose(): void {
102
+ this.cancel();
103
+ this._isDisposed = true;
104
+ }
105
+ }
@@ -4,8 +4,8 @@
4
4
  */
5
5
 
6
6
  import { ICircularList } from 'common/Types';
7
- import { Disposable } from 'vs/base/common/lifecycle';
8
- import { Emitter } from 'vs/base/common/event';
7
+ import { Disposable } from 'common/Lifecycle';
8
+ import { Emitter } from 'common/Event';
9
9
 
10
10
  export interface IInsertEvent {
11
11
  index: number;
@@ -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');
@@ -21,14 +21,14 @@
21
21
  * http://linux.die.net/man/7/urxvt
22
22
  */
23
23
 
24
- import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, LogLevelEnum, ITerminalOptions, IOscLinkService } from 'common/services/Services';
24
+ import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, IMouseStateService, IUnicodeService, LogLevelEnum, ITerminalOptions, IOscLinkService } from 'common/services/Services';
25
25
  import { InstantiationService } from 'common/services/InstantiationService';
26
26
  import { LogService } from 'common/services/LogService';
27
27
  import { BufferService, MINIMUM_COLS, MINIMUM_ROWS } from 'common/services/BufferService';
28
28
  import { OptionsService } from 'common/services/OptionsService';
29
29
  import { IDisposable, IAttributeData, ICoreTerminal, IScrollEvent } from 'common/Types';
30
30
  import { CoreService } from 'common/services/CoreService';
31
- import { CoreMouseService } from 'common/services/CoreMouseService';
31
+ import { MouseStateService } from 'common/services/MouseStateService';
32
32
  import { UnicodeService } from 'common/services/UnicodeService';
33
33
  import { CharsetService } from 'common/services/CharsetService';
34
34
  import { updateWindowsModeWrappedState } from 'common/WindowsMode';
@@ -37,8 +37,8 @@ import { IBufferSet } from 'common/buffer/Types';
37
37
  import { InputHandler } from 'common/InputHandler';
38
38
  import { WriteBuffer } from 'common/input/WriteBuffer';
39
39
  import { OscLinkService } from 'common/services/OscLinkService';
40
- import { Emitter, Event } from 'vs/base/common/event';
41
- import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
40
+ import { Emitter, EventUtils, type IEvent } from 'common/Event';
41
+ import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
42
42
 
43
43
  // Only trigger this warning a single time per session
44
44
  let hasWriteSyncWarnHappened = false;
@@ -50,7 +50,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
50
50
  protected readonly _charsetService: ICharsetService;
51
51
  protected readonly _oscLinkService: IOscLinkService;
52
52
 
53
- public readonly coreMouseService: ICoreMouseService;
53
+ public readonly mouseStateService: IMouseStateService;
54
54
  public readonly coreService: ICoreService;
55
55
  public readonly unicodeService: IUnicodeService;
56
56
  public readonly optionsService: IOptionsService;
@@ -65,6 +65,8 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
65
65
  public readonly onData = this._onData.event;
66
66
  protected _onLineFeed = this._register(new Emitter<void>());
67
67
  public readonly onLineFeed = this._onLineFeed.event;
68
+ protected readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());
69
+ public readonly onRender = this._onRender.event;
68
70
  private readonly _onResize = this._register(new Emitter<{ cols: number, rows: number }>());
69
71
  public readonly onResize = this._onResize.event;
70
72
  protected readonly _onWriteParsed = this._register(new Emitter<void>());
@@ -76,7 +78,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
76
78
  */
77
79
  protected _onScrollApi?: Emitter<number>;
78
80
  protected _onScroll = this._register(new Emitter<IScrollEvent>());
79
- public get onScroll(): Event<number> {
81
+ public get onScroll(): IEvent<number> {
80
82
  if (!this._onScrollApi) {
81
83
  this._onScrollApi = this._register(new Emitter<number>());
82
84
  this._onScroll.event(ev => {
@@ -105,14 +107,14 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
105
107
  this._instantiationService = new InstantiationService();
106
108
  this.optionsService = this._register(new OptionsService(options));
107
109
  this._instantiationService.setService(IOptionsService, this.optionsService);
108
- this._bufferService = this._register(this._instantiationService.createInstance(BufferService));
109
- this._instantiationService.setService(IBufferService, this._bufferService);
110
110
  this._logService = this._register(this._instantiationService.createInstance(LogService));
111
111
  this._instantiationService.setService(ILogService, this._logService);
112
+ this._bufferService = this._register(this._instantiationService.createInstance(BufferService));
113
+ this._instantiationService.setService(IBufferService, this._bufferService);
112
114
  this.coreService = this._register(this._instantiationService.createInstance(CoreService));
113
115
  this._instantiationService.setService(ICoreService, this.coreService);
114
- this.coreMouseService = this._register(this._instantiationService.createInstance(CoreMouseService));
115
- this._instantiationService.setService(ICoreMouseService, this.coreMouseService);
116
+ this.mouseStateService = this._register(this._instantiationService.createInstance(MouseStateService));
117
+ this._instantiationService.setService(IMouseStateService, this.mouseStateService);
116
118
  this.unicodeService = this._register(this._instantiationService.createInstance(UnicodeService));
117
119
  this._instantiationService.setService(IUnicodeService, this.unicodeService);
118
120
  this._charsetService = this._instantiationService.createInstance(CharsetService);
@@ -122,14 +124,13 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
122
124
 
123
125
 
124
126
  // Register input handler and handle/forward events
125
- this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.coreMouseService, this.unicodeService));
126
- this._register(Event.forward(this._inputHandler.onLineFeed, this._onLineFeed));
127
- this._register(this._inputHandler);
127
+ this._inputHandler = this._register(new InputHandler(this._bufferService, this._charsetService, this.coreService, this._logService, this.optionsService, this._oscLinkService, this.mouseStateService, this.unicodeService));
128
+ this._register(EventUtils.forward(this._inputHandler.onLineFeed, this._onLineFeed));
128
129
 
129
130
  // Setup listeners
130
- this._register(Event.forward(this._bufferService.onResize, this._onResize));
131
- this._register(Event.forward(this.coreService.onData, this._onData));
132
- this._register(Event.forward(this.coreService.onBinary, this._onBinary));
131
+ this._register(EventUtils.forward(this._bufferService.onResize, this._onResize));
132
+ this._register(EventUtils.forward(this.coreService.onData, this._onData));
133
+ this._register(EventUtils.forward(this.coreService.onBinary, this._onBinary));
133
134
  this._register(this.coreService.onRequestScrollToBottom(() => this.scrollToBottom(true)));
134
135
  this._register(this.coreService.onUserInput(() => this._writeBuffer.handleUserInput()));
135
136
  this._register(this.optionsService.onMultipleOptionChange(['windowsPty'], () => this._handleWindowsPtyOptionChange()));
@@ -139,7 +140,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
139
140
  }));
140
141
  // Setup WriteBuffer
141
142
  this._writeBuffer = this._register(new WriteBuffer((data, promiseResult) => this._inputHandler.parse(data, promiseResult)));
142
- this._register(Event.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));
143
+ this._register(EventUtils.forward(this._writeBuffer.onWriteParsed, this._onWriteParsed));
143
144
  }
144
145
 
145
146
  public write(data: string | Uint8Array, callback?: () => void): void {
@@ -175,6 +176,10 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
175
176
  x = Math.max(x, MINIMUM_COLS);
176
177
  y = Math.max(y, MINIMUM_ROWS);
177
178
 
179
+ // Flush pending writes before resize to avoid race conditions where async
180
+ // writes are processed with incorrect dimensions
181
+ this._writeBuffer.flushSync();
182
+
178
183
  this._bufferService.resize(x, y);
179
184
  }
180
185
 
@@ -237,6 +242,11 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
237
242
  return this._inputHandler.registerOscHandler(ident, callback);
238
243
  }
239
244
 
245
+ /** Add handler for APC escape sequence. See xterm.d.ts for details. */
246
+ public registerApcHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
247
+ return this._inputHandler.registerApcHandler(ident, callback);
248
+ }
249
+
240
250
  protected _setup(): void {
241
251
  this._handleWindowsPtyOptionChange();
242
252
  }
@@ -246,7 +256,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
246
256
  this._bufferService.reset();
247
257
  this._charsetService.reset();
248
258
  this.coreService.reset();
249
- this.coreMouseService.reset();
259
+ this.mouseStateService.reset();
250
260
  }
251
261
 
252
262