@xterm/xterm 6.1.0-beta.28 → 6.1.0-beta.281

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 (181) hide show
  1. package/README.md +62 -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 +56 -45
  8. package/src/browser/AccessibilityManager.ts +18 -13
  9. package/src/browser/Clipboard.ts +8 -5
  10. package/src/browser/ColorContrastCache.ts +3 -3
  11. package/src/browser/CoreBrowserTerminal.ts +179 -348
  12. package/src/browser/Dom.ts +178 -0
  13. package/src/browser/Linkifier.ts +14 -14
  14. package/src/browser/OscLinkProvider.ts +86 -18
  15. package/src/browser/RenderDebouncer.ts +7 -9
  16. package/src/browser/TimeBasedDebouncer.ts +12 -5
  17. package/src/browser/Types.ts +16 -14
  18. package/src/browser/Viewport.ts +58 -23
  19. package/src/browser/decorations/BufferDecorationRenderer.ts +3 -3
  20. package/src/browser/decorations/ColorZoneStore.ts +1 -1
  21. package/src/browser/decorations/OverviewRulerRenderer.ts +36 -20
  22. package/src/browser/input/CompositionHelper.ts +47 -11
  23. package/src/browser/input/Mouse.ts +5 -9
  24. package/src/browser/input/MoveToCell.ts +3 -3
  25. package/src/browser/public/Terminal.ts +33 -36
  26. package/src/browser/renderer/dom/DomRenderer.ts +265 -89
  27. package/src/browser/renderer/dom/DomRendererRowFactory.ts +34 -27
  28. package/src/browser/renderer/dom/WidthCache.ts +57 -55
  29. package/src/browser/renderer/shared/Constants.ts +7 -0
  30. package/src/browser/renderer/shared/RendererUtils.ts +1 -1
  31. package/src/browser/renderer/shared/SelectionRenderModel.ts +2 -2
  32. package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
  33. package/src/browser/renderer/shared/Types.ts +10 -4
  34. package/src/browser/scrollable/abstractScrollbar.ts +300 -0
  35. package/src/browser/scrollable/fastDomNode.ts +126 -0
  36. package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
  37. package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
  38. package/src/browser/scrollable/mouseEvent.ts +292 -0
  39. package/src/browser/scrollable/scrollable.ts +486 -0
  40. package/src/browser/scrollable/scrollableElement.ts +581 -0
  41. package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
  42. package/src/browser/scrollable/scrollbarArrow.ts +110 -0
  43. package/src/browser/scrollable/scrollbarState.ts +246 -0
  44. package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
  45. package/src/browser/scrollable/touch.ts +485 -0
  46. package/src/browser/scrollable/verticalScrollbar.ts +143 -0
  47. package/src/browser/scrollable/widget.ts +23 -0
  48. package/src/browser/selection/SelectionModel.ts +1 -1
  49. package/src/browser/services/CharSizeService.ts +4 -4
  50. package/src/browser/services/CharacterJoinerService.ts +13 -11
  51. package/src/browser/services/CoreBrowserService.ts +7 -5
  52. package/src/browser/services/KeyboardService.ts +67 -0
  53. package/src/browser/services/LinkProviderService.ts +3 -3
  54. package/src/browser/services/MouseCoordsService.ts +47 -0
  55. package/src/browser/services/MouseService.ts +619 -23
  56. package/src/browser/services/RenderService.ts +33 -21
  57. package/src/browser/services/SelectionService.ts +72 -54
  58. package/src/browser/services/Services.ts +44 -21
  59. package/src/browser/services/ThemeService.ts +9 -9
  60. package/src/common/Async.ts +141 -0
  61. package/src/common/CircularList.ts +24 -3
  62. package/src/common/Color.ts +13 -5
  63. package/src/common/CoreTerminal.ts +61 -35
  64. package/src/common/Event.ts +118 -0
  65. package/src/common/InputHandler.ts +286 -105
  66. package/src/common/Lifecycle.ts +113 -0
  67. package/src/common/Platform.ts +15 -5
  68. package/src/common/SortedList.ts +8 -4
  69. package/src/common/StringBuilder.ts +67 -0
  70. package/src/common/TaskQueue.ts +17 -8
  71. package/src/common/Types.ts +68 -206
  72. package/src/common/Version.ts +1 -1
  73. package/src/common/WindowsMode.ts +2 -2
  74. package/src/common/buffer/AttributeData.ts +3 -2
  75. package/src/common/buffer/Buffer.ts +47 -32
  76. package/src/common/buffer/BufferLine.ts +175 -100
  77. package/src/common/buffer/BufferLineStringCache.ts +69 -0
  78. package/src/common/buffer/BufferReflow.ts +7 -4
  79. package/src/common/buffer/BufferSet.ts +13 -9
  80. package/src/common/buffer/CellData.ts +61 -4
  81. package/src/common/buffer/Constants.ts +13 -13
  82. package/src/common/buffer/Marker.ts +4 -4
  83. package/src/common/buffer/Types.ts +153 -3
  84. package/src/common/data/Charsets.ts +4 -7
  85. package/src/common/data/EscapeSequences.ts +71 -70
  86. package/src/common/input/Keyboard.ts +17 -10
  87. package/src/common/input/KittyKeyboard.ts +526 -0
  88. package/src/common/input/TextDecoder.ts +3 -3
  89. package/src/common/input/UnicodeV6.ts +3 -2
  90. package/src/common/input/Win32InputMode.ts +297 -0
  91. package/src/common/input/WriteBuffer.ts +108 -39
  92. package/src/common/input/XParseColor.ts +2 -2
  93. package/src/common/parser/ApcParser.ts +196 -0
  94. package/src/common/parser/Constants.ts +14 -4
  95. package/src/common/parser/DcsParser.ts +15 -16
  96. package/src/common/parser/EscapeSequenceParser.ts +214 -72
  97. package/src/common/parser/OscParser.ts +14 -15
  98. package/src/common/parser/Params.ts +31 -12
  99. package/src/common/parser/Types.ts +40 -30
  100. package/src/common/public/BufferApiView.ts +3 -3
  101. package/src/common/public/BufferLineApiView.ts +4 -4
  102. package/src/common/public/BufferNamespaceApi.ts +5 -5
  103. package/src/common/public/ParserApi.ts +5 -2
  104. package/src/common/public/UnicodeApi.ts +1 -1
  105. package/src/common/services/BufferService.ts +17 -13
  106. package/src/common/services/CharsetService.ts +6 -2
  107. package/src/common/services/CoreService.ts +23 -10
  108. package/src/common/services/DecorationService.ts +260 -15
  109. package/src/common/services/InstantiationService.ts +2 -2
  110. package/src/common/services/LogService.ts +2 -32
  111. package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +22 -133
  112. package/src/common/services/OptionsService.ts +17 -7
  113. package/src/common/services/OscLinkService.ts +3 -2
  114. package/src/common/services/ServiceRegistry.ts +14 -8
  115. package/src/common/services/Services.ts +54 -50
  116. package/src/common/services/UnicodeService.ts +6 -11
  117. package/typings/xterm.d.ts +329 -34
  118. package/src/common/Clone.ts +0 -23
  119. package/src/common/TypedArrayUtils.ts +0 -17
  120. package/src/vs/base/browser/browser.ts +0 -141
  121. package/src/vs/base/browser/canIUse.ts +0 -49
  122. package/src/vs/base/browser/dom.ts +0 -2369
  123. package/src/vs/base/browser/fastDomNode.ts +0 -316
  124. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  125. package/src/vs/base/browser/iframe.ts +0 -135
  126. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  127. package/src/vs/base/browser/mouseEvent.ts +0 -229
  128. package/src/vs/base/browser/touch.ts +0 -372
  129. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  130. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  131. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  132. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  133. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  134. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  135. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  136. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  137. package/src/vs/base/browser/ui/widget.ts +0 -57
  138. package/src/vs/base/browser/window.ts +0 -14
  139. package/src/vs/base/common/arrays.ts +0 -887
  140. package/src/vs/base/common/arraysFind.ts +0 -202
  141. package/src/vs/base/common/assert.ts +0 -71
  142. package/src/vs/base/common/async.ts +0 -1992
  143. package/src/vs/base/common/cancellation.ts +0 -148
  144. package/src/vs/base/common/charCode.ts +0 -450
  145. package/src/vs/base/common/collections.ts +0 -140
  146. package/src/vs/base/common/decorators.ts +0 -130
  147. package/src/vs/base/common/equals.ts +0 -146
  148. package/src/vs/base/common/errors.ts +0 -303
  149. package/src/vs/base/common/event.ts +0 -1778
  150. package/src/vs/base/common/functional.ts +0 -32
  151. package/src/vs/base/common/hash.ts +0 -316
  152. package/src/vs/base/common/iterator.ts +0 -159
  153. package/src/vs/base/common/keyCodes.ts +0 -526
  154. package/src/vs/base/common/keybindings.ts +0 -284
  155. package/src/vs/base/common/lazy.ts +0 -47
  156. package/src/vs/base/common/lifecycle.ts +0 -801
  157. package/src/vs/base/common/linkedList.ts +0 -142
  158. package/src/vs/base/common/map.ts +0 -202
  159. package/src/vs/base/common/numbers.ts +0 -98
  160. package/src/vs/base/common/observable.ts +0 -76
  161. package/src/vs/base/common/observableInternal/api.ts +0 -31
  162. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  163. package/src/vs/base/common/observableInternal/base.ts +0 -489
  164. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  165. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  166. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  167. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  168. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  169. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  170. package/src/vs/base/common/platform.ts +0 -281
  171. package/src/vs/base/common/scrollable.ts +0 -522
  172. package/src/vs/base/common/sequence.ts +0 -34
  173. package/src/vs/base/common/stopwatch.ts +0 -43
  174. package/src/vs/base/common/strings.ts +0 -557
  175. package/src/vs/base/common/symbols.ts +0 -9
  176. package/src/vs/base/common/uint.ts +0 -59
  177. package/src/vs/patches/nls.ts +0 -90
  178. package/src/vs/typings/base-common.d.ts +0 -20
  179. package/src/vs/typings/require.d.ts +0 -42
  180. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  181. package/src/vs/typings/vscode-globals-product.d.ts +0 -33
@@ -3,18 +3,19 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IBufferLine, ICellData, IColor } from 'common/Types';
7
- import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
8
- import { WHITESPACE_CELL_CHAR, Attributes } from 'common/buffer/Constants';
9
- import { CellData } from 'common/buffer/CellData';
10
- import { ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
11
- import { channels, color } from 'common/Color';
12
- import { ICharacterJoinerService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
13
- import { JoinedCellData } from 'browser/services/CharacterJoinerService';
14
- import { treatGlyphAsBackgroundColor } from 'browser/renderer/shared/RendererUtils';
15
- import { AttributeData } from 'common/buffer/AttributeData';
16
- import { WidthCache } from 'browser/renderer/dom/WidthCache';
17
- import { IColorContrastCache } from 'browser/Types';
6
+ import { IColor } from '../../../common/Types';
7
+ import { IBufferLine, ICellData } from '../../../common/buffer/Types';
8
+ import { INVERTED_DEFAULT_COLOR } from '../shared/Constants';
9
+ import { WHITESPACE_CELL_CHAR, Attributes } from '../../../common/buffer/Constants';
10
+ import { CellData } from '../../../common/buffer/CellData';
11
+ import { ICoreService, IDecorationService, IOptionsService } from '../../../common/services/Services';
12
+ import { channels, color } from '../../../common/Color';
13
+ import { ICharacterJoinerService, ICoreBrowserService, IThemeService } from '../../services/Services';
14
+ import { JoinedCellData } from '../../services/CharacterJoinerService';
15
+ import { treatGlyphAsBackgroundColor } from '../shared/RendererUtils';
16
+ import { AttributeData } from '../../../common/buffer/AttributeData';
17
+ import { WidthCache } from './WidthCache';
18
+ import { IColorContrastCache } from '../../Types';
18
19
 
19
20
 
20
21
  export const enum RowCss {
@@ -24,6 +25,7 @@ export const enum RowCss {
24
25
  UNDERLINE_CLASS = 'xterm-underline',
25
26
  OVERLINE_CLASS = 'xterm-overline',
26
27
  STRIKETHROUGH_CLASS = 'xterm-strikethrough',
28
+ BLINK_HIDDEN_CLASS = 'xterm-blink-hidden',
27
29
  CURSOR_CLASS = 'xterm-cursor',
28
30
  CURSOR_BLINK_CLASS = 'xterm-cursor-blink',
29
31
  CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block',
@@ -66,13 +68,18 @@ export class DomRendererRowFactory {
66
68
  cursorInactiveStyle: string | undefined,
67
69
  cursorX: number,
68
70
  cursorBlink: boolean,
71
+ blinkOn: boolean,
69
72
  cellWidth: number,
70
73
  widthCache: WidthCache,
71
74
  linkStart: number,
72
- linkEnd: number
75
+ linkEnd: number,
76
+ rowInfo?: { hasBlinkingCells: boolean }
73
77
  ): HTMLSpanElement[] {
74
78
 
75
79
  const elements: HTMLSpanElement[] = [];
80
+ if (rowInfo) {
81
+ rowInfo.hasBlinkingCells = false;
82
+ }
76
83
  const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
77
84
  const colors = this._themeService.colors;
78
85
 
@@ -84,14 +91,14 @@ export class DomRendererRowFactory {
84
91
  let charElement: HTMLSpanElement | undefined;
85
92
  let cellAmount = 0;
86
93
  let text = '';
87
- let i = 0;
94
+ let i;
88
95
  let oldBg = 0;
89
96
  let oldFg = 0;
90
97
  let oldExt = 0;
91
98
  let oldLinkHover: number | boolean = false;
92
99
  let oldSpacing = 0;
93
100
  let oldIsInSelection: boolean = false;
94
- let spacing = 0;
101
+ let spacing;
95
102
  let skipJoinedCheckUntilX = 0;
96
103
  const classes: string[] = [];
97
104
 
@@ -118,7 +125,7 @@ export class DomRendererRowFactory {
118
125
  // Process any joined character ranges as needed. Because of how the
119
126
  // ranges are produced, we know that they are valid for the characters
120
127
  // and attributes of our input.
121
- let cell = this._workCell;
128
+ let cell: ICellData = this._workCell;
122
129
  if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {
123
130
  const range = joinedRanges.shift()!;
124
131
  // If the ligature's selection state is not consistent, don't join it. This helps the
@@ -153,6 +160,13 @@ export class DomRendererRowFactory {
153
160
  const isInSelection = this._isCellInSelection(x, row);
154
161
  const isCursorCell = isCursorRow && x === cursorX;
155
162
  const isLinkHover = hasHover && x >= linkStart && x <= linkEnd;
163
+ if (rowInfo && cell.isBlink()) {
164
+ rowInfo.hasBlinkingCells = true;
165
+ }
166
+ const isBlinkHidden = !blinkOn && cell.isBlink();
167
+ if (isBlinkHidden) {
168
+ classes.push(RowCss.BLINK_HIDDEN_CLASS);
169
+ }
156
170
 
157
171
  let isDecorated = false;
158
172
  this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {
@@ -397,7 +411,7 @@ export class DomRendererRowFactory {
397
411
  break;
398
412
  case Attributes.CM_RGB:
399
413
  resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);
400
- this._addStyle(charElement, `background-color:#${padStart((bg >>> 0).toString(16), '0', 6)}`);
414
+ this._addStyle(charElement, `background-color:#${(bg >>> 0).toString(16).padStart(6, '0')}`);
401
415
  break;
402
416
  case Attributes.CM_DEFAULT:
403
417
  default:
@@ -434,7 +448,7 @@ export class DomRendererRowFactory {
434
448
  (fg ) & 0xFF
435
449
  );
436
450
  if (!this._applyMinimumContrast(charElement, resolvedBg, color, cell, bgOverride, fgOverride)) {
437
- this._addStyle(charElement, `color:#${padStart(fg.toString(16), '0', 6)}`);
451
+ this._addStyle(charElement, `color:#${fg.toString(16).padStart(6, '0')}`);
438
452
  }
439
453
  break;
440
454
  case Attributes.CM_DEFAULT:
@@ -494,8 +508,8 @@ export class DomRendererRowFactory {
494
508
  // Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from
495
509
  // non-dim cells
496
510
  const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);
497
- adjustedColor = color.ensureContrastRatio(bgOverride || bg, fgOverride || fg, ratio);
498
- cache.setColor((bgOverride || bg).rgba, (fgOverride || fg).rgba, adjustedColor ?? null);
511
+ adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);
512
+ cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);
499
513
  }
500
514
 
501
515
  if (adjustedColor) {
@@ -537,10 +551,3 @@ export class DomRendererRowFactory {
537
551
  (start[1] < end[1] && y === start[1] && x >= start[0]);
538
552
  }
539
553
  }
540
-
541
- function padStart(text: string, padChar: string, length: number): string {
542
- while (text.length < length) {
543
- text = padChar + text;
544
- }
545
- return text;
546
- }
@@ -3,8 +3,9 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IDisposable } from 'common/Types';
7
- import { FontWeight } from 'common/services/Services';
6
+ import { throwIfFalsy } from '../shared/RendererUtils';
7
+ import { IDisposable } from '../../../common/Types';
8
+ import { FontWeight } from '../../../common/services/Services';
8
9
 
9
10
 
10
11
  export const enum WidthCacheSettings {
@@ -24,6 +25,10 @@ const enum FontVariant {
24
25
  BOLD_ITALIC = 3
25
26
  }
26
27
 
28
+ export interface IWidthCacheFontVariantCanvas {
29
+ setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void;
30
+ measure(c: string): number;
31
+ }
27
32
 
28
33
  export class WidthCache implements IDisposable {
29
34
  // flat cache for regular variant up to CacheSettings.FLAT_SIZE
@@ -42,50 +47,24 @@ export class WidthCache implements IDisposable {
42
47
  private _fontSize = 0;
43
48
  private _weight: FontWeight = 'normal';
44
49
  private _weightBold: FontWeight = 'bold';
45
- private _container: HTMLDivElement;
46
- private _measureElements: HTMLSpanElement[] = [];
47
-
48
- constructor(_document: Document, _helperContainer: HTMLElement) {
49
- this._container = _document.createElement('div');
50
- this._container.classList.add('xterm-width-cache-measure-container');
51
- this._container.setAttribute('aria-hidden', 'true');
52
- // SP should stack in spans
53
- this._container.style.whiteSpace = 'pre';
54
- // avoid undercuts in non-monospace fonts from kerning
55
- this._container.style.fontKerning = 'none';
56
-
57
- const regular = _document.createElement('span');
58
- regular.classList.add('xterm-char-measure-element');
59
-
60
- const bold = _document.createElement('span');
61
- bold.classList.add('xterm-char-measure-element');
62
- bold.style.fontWeight = 'bold';
63
-
64
- const italic = _document.createElement('span');
65
- italic.classList.add('xterm-char-measure-element');
66
- italic.style.fontStyle = 'italic';
67
-
68
- const boldItalic = _document.createElement('span');
69
- boldItalic.classList.add('xterm-char-measure-element');
70
- boldItalic.style.fontWeight = 'bold';
71
- boldItalic.style.fontStyle = 'italic';
72
-
73
- // NOTE: must be in order of FontVariant
74
- this._measureElements = [regular, bold, italic, boldItalic];
75
- this._container.appendChild(regular);
76
- this._container.appendChild(bold);
77
- this._container.appendChild(italic);
78
- this._container.appendChild(boldItalic);
79
-
80
- _helperContainer.appendChild(this._container);
50
+ private _canvasElements: IWidthCacheFontVariantCanvas[] = [];
51
+
52
+ constructor(
53
+ canvasFactory: () => IWidthCacheFontVariantCanvas = () => new WidthCacheFontVariantCanvas()
54
+ ) {
55
+ this._canvasElements = [
56
+ canvasFactory(),
57
+ canvasFactory(),
58
+ canvasFactory(),
59
+ canvasFactory()
60
+ ];
81
61
 
82
62
  this.clear();
83
63
  }
84
64
 
85
65
  public dispose(): void {
86
- this._container.remove(); // remove elements from DOM
87
- this._measureElements.length = 0; // release element refs
88
- this._holey = undefined; // free cache memory via GC
66
+ this._canvasElements.length = 0;
67
+ this._holey = undefined; // free cache memory via GC
89
68
  }
90
69
 
91
70
  /**
@@ -104,10 +83,11 @@ export class WidthCache implements IDisposable {
104
83
  */
105
84
  public setFont(font: string, fontSize: number, weight: FontWeight, weightBold: FontWeight): void {
106
85
  // skip if nothing changed
107
- if (font === this._font
108
- && fontSize === this._fontSize
109
- && weight === this._weight
110
- && weightBold === this._weightBold
86
+ if (
87
+ font === this._font &&
88
+ fontSize === this._fontSize &&
89
+ weight === this._weight &&
90
+ weightBold === this._weightBold
111
91
  ) {
112
92
  return;
113
93
  }
@@ -117,12 +97,10 @@ export class WidthCache implements IDisposable {
117
97
  this._weight = weight;
118
98
  this._weightBold = weightBold;
119
99
 
120
- this._container.style.fontFamily = this._font;
121
- this._container.style.fontSize = `${this._fontSize}px`;
122
- this._measureElements[FontVariant.REGULAR].style.fontWeight = `${weight}`;
123
- this._measureElements[FontVariant.BOLD].style.fontWeight = `${weightBold}`;
124
- this._measureElements[FontVariant.ITALIC].style.fontWeight = `${weight}`;
125
- this._measureElements[FontVariant.BOLD_ITALIC].style.fontWeight = `${weightBold}`;
100
+ this._canvasElements[FontVariant.REGULAR].setFont(font, fontSize, weight, false);
101
+ this._canvasElements[FontVariant.BOLD].setFont(font, fontSize, weightBold, false);
102
+ this._canvasElements[FontVariant.ITALIC].setFont(font, fontSize, weight, true);
103
+ this._canvasElements[FontVariant.BOLD_ITALIC].setFont(font, fontSize, weightBold, true);
126
104
 
127
105
  this.clear();
128
106
  }
@@ -132,7 +110,7 @@ export class WidthCache implements IDisposable {
132
110
  * `variant` denotes the font variant to be used.
133
111
  */
134
112
  public get(c: string, bold: boolean | number, italic: boolean | number): number {
135
- let cp = 0;
113
+ let cp: number;
136
114
  if (!bold && !italic && c.length === 1 && (cp = c.charCodeAt(0)) < WidthCacheSettings.FLAT_SIZE) {
137
115
  if (this._flat[cp] !== WidthCacheSettings.FLAT_UNSET) {
138
116
  return this._flat[cp];
@@ -160,8 +138,32 @@ export class WidthCache implements IDisposable {
160
138
  }
161
139
 
162
140
  protected _measure(c: string, variant: FontVariant): number {
163
- const el = this._measureElements[variant];
164
- el.textContent = c.repeat(WidthCacheSettings.REPEAT);
165
- return el.offsetWidth / WidthCacheSettings.REPEAT;
141
+ return this._canvasElements[variant].measure(c);
142
+ }
143
+ }
144
+
145
+ class WidthCacheFontVariantCanvas implements IWidthCacheFontVariantCanvas {
146
+ private _canvas: OffscreenCanvas | HTMLCanvasElement;
147
+ private _ctx: OffscreenCanvasRenderingContext2D | CanvasRenderingContext2D;
148
+
149
+ constructor() {
150
+ if (typeof OffscreenCanvas !== 'undefined') {
151
+ this._canvas = new OffscreenCanvas(1, 1);
152
+ this._ctx = throwIfFalsy(this._canvas.getContext('2d'));
153
+ } else {
154
+ this._canvas = document.createElement('canvas');
155
+ this._canvas.width = 1;
156
+ this._canvas.height = 1;
157
+ this._ctx = throwIfFalsy(this._canvas.getContext('2d'));
158
+ }
159
+ }
160
+
161
+ public setFont(fontFamily: string, fontSize: number, fontWeight: FontWeight, italic: boolean): void {
162
+ const fontStyle = italic ? 'italic' : '';
163
+ this._ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`.trim();
164
+ }
165
+
166
+ public measure(c: string): number {
167
+ return this._ctx.measureText(c).width;
166
168
  }
167
169
  }
@@ -4,3 +4,10 @@
4
4
  */
5
5
 
6
6
  export const INVERTED_DEFAULT_COLOR = 257;
7
+
8
+ export const enum RendererConstants {
9
+ /**
10
+ * The idle time after which cursor blinking stops.
11
+ */
12
+ CURSOR_BLINK_IDLE_TIMEOUT = 5 * 60 * 1000
13
+ }
@@ -3,7 +3,7 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { IDimensions, IRenderDimensions } from 'browser/renderer/shared/Types';
6
+ import { IDimensions, IRenderDimensions } from './Types';
7
7
 
8
8
  export function throwIfFalsy<T>(value: T | undefined | null): T {
9
9
  if (!value) {
@@ -3,8 +3,8 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { ITerminal } from 'browser/Types';
7
- import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
6
+ import { ITerminal } from '../../Types';
7
+ import { ISelectionRenderModel } from './Types';
8
8
  import { Terminal } from '@xterm/xterm';
9
9
 
10
10
  class SelectionRenderModel implements ISelectionRenderModel {
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Copyright (c) 2026 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { ICoreBrowserService } from '../../services/Services';
7
+ import { Disposable, toDisposable } from '../../../common/Lifecycle';
8
+ import { IOptionsService } from '../../../common/services/Services';
9
+
10
+ export class TextBlinkStateManager extends Disposable {
11
+ private _intervalDuration: number = 0;
12
+ private _interval: number | undefined;
13
+ private _blinkOn: boolean = true;
14
+ private _needsBlinkInViewport: boolean = false;
15
+ private _isViewportVisible: boolean = true;
16
+
17
+ constructor(
18
+ private readonly _renderCallback: () => void,
19
+ private readonly _coreBrowserService: ICoreBrowserService,
20
+ private readonly _optionsService: IOptionsService
21
+ ) {
22
+ super();
23
+ this._register(this._optionsService.onSpecificOptionChange('blinkIntervalDuration', duration => {
24
+ this.setIntervalDuration(duration);
25
+ }));
26
+ this.setIntervalDuration(this._optionsService.rawOptions.blinkIntervalDuration);
27
+ this._register(toDisposable(() => this._clearInterval()));
28
+ }
29
+
30
+ public get isBlinkOn(): boolean {
31
+ return this._blinkOn;
32
+ }
33
+
34
+ public get isEnabled(): boolean {
35
+ return this._intervalDuration > 0;
36
+ }
37
+
38
+ public setNeedsBlinkInViewport(needsBlinkInViewport: boolean): void {
39
+ if (this._needsBlinkInViewport === needsBlinkInViewport) {
40
+ return;
41
+ }
42
+
43
+ this._needsBlinkInViewport = needsBlinkInViewport;
44
+ this._updateIntervalState();
45
+ }
46
+
47
+ public setViewportVisible(isVisible: boolean): void {
48
+ if (this._isViewportVisible === isVisible) {
49
+ return;
50
+ }
51
+
52
+ this._isViewportVisible = isVisible;
53
+ this._updateIntervalState();
54
+ }
55
+
56
+ public setIntervalDuration(duration: number): void {
57
+ if (duration === this._intervalDuration) {
58
+ return;
59
+ }
60
+
61
+ this._intervalDuration = duration;
62
+ this._clearInterval();
63
+ this._updateIntervalState();
64
+ }
65
+
66
+ private _updateIntervalState(): void {
67
+ const shouldBlink = this._intervalDuration > 0 && this._needsBlinkInViewport && this._isViewportVisible;
68
+ if (shouldBlink) {
69
+ if (this._interval !== undefined) {
70
+ return;
71
+ }
72
+ const wasBlinkOn = this._blinkOn;
73
+ this._blinkOn = true;
74
+ this._interval = this._coreBrowserService.window.setInterval(() => {
75
+ this._blinkOn = !this._blinkOn;
76
+ this._renderCallback();
77
+ }, this._intervalDuration);
78
+ if (!wasBlinkOn) {
79
+ this._renderCallback();
80
+ }
81
+ return;
82
+ }
83
+
84
+ this._clearInterval();
85
+ if (!this._blinkOn) {
86
+ this._blinkOn = true;
87
+ this._renderCallback();
88
+ }
89
+ }
90
+
91
+ private _clearInterval(): void {
92
+ if (this._interval !== undefined) {
93
+ this._coreBrowserService.window.clearInterval(this._interval);
94
+ this._interval = undefined;
95
+ }
96
+ }
97
+ }
@@ -4,9 +4,9 @@
4
4
  */
5
5
 
6
6
  import { Terminal } from '@xterm/xterm';
7
- import { ITerminal } from 'browser/Types';
8
- import { IDisposable } from 'common/Types';
9
- import type { Event } from 'vs/base/common/event';
7
+ import { ITerminal } from '../../Types';
8
+ import { IDisposable } from '../../../common/Types';
9
+ import type { IEvent } from '../../../common/Event';
10
10
 
11
11
  export interface IDimensions {
12
12
  width: number;
@@ -39,6 +39,11 @@ export interface IRenderDimensions {
39
39
  export interface IRequestRedrawEvent {
40
40
  start: number;
41
41
  end: number;
42
+ /**
43
+ * Whether the redraw should happen synchronously. This is used to avoid
44
+ * flicker when the canvas is resized.
45
+ */
46
+ sync?: boolean;
42
47
  }
43
48
 
44
49
  /**
@@ -52,7 +57,7 @@ export interface IRenderer extends IDisposable {
52
57
  * Fires when the renderer is requesting to be redrawn on the next animation
53
58
  * frame but is _not_ a result of content changing (eg. selection changes).
54
59
  */
55
- readonly onRequestRedraw: Event<IRequestRedrawEvent>;
60
+ readonly onRequestRedraw: IEvent<IRequestRedrawEvent>;
56
61
 
57
62
  dispose(): void;
58
63
  handleDevicePixelRatioChange(): void;
@@ -60,6 +65,7 @@ export interface IRenderer extends IDisposable {
60
65
  handleCharSizeChanged(): void;
61
66
  handleBlur(): void;
62
67
  handleFocus(): void;
68
+ handleViewportVisibilityChange?(isVisible: boolean): void;
63
69
  handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void;
64
70
  handleCursorMove(): void;
65
71
  clear(): void;