@wendongfly/zihi 1.1.0 → 1.1.2

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 (157) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/lib/xterm/README.md +27 -14
  3. package/dist/lib/xterm/css/xterm.css +81 -5
  4. package/dist/lib/xterm/lib/xterm.js +1 -1
  5. package/dist/lib/xterm/lib/xterm.js.map +1 -1
  6. package/dist/lib/xterm/lib/xterm.mjs +53 -0
  7. package/dist/lib/xterm/lib/xterm.mjs.map +7 -0
  8. package/dist/lib/xterm/package.json +49 -38
  9. package/dist/lib/xterm/src/browser/AccessibilityManager.ts +185 -50
  10. package/dist/lib/xterm/src/browser/CoreBrowserTerminal.ts +1339 -0
  11. package/dist/lib/xterm/src/browser/Linkifier.ts +403 -0
  12. package/dist/lib/xterm/src/browser/LocalizableStrings.ts +15 -4
  13. package/dist/lib/xterm/src/browser/OscLinkProvider.ts +2 -1
  14. package/dist/lib/xterm/src/browser/RenderDebouncer.ts +6 -5
  15. package/dist/lib/xterm/src/browser/TimeBasedDebouncer.ts +2 -2
  16. package/dist/lib/xterm/src/browser/Types.ts +226 -0
  17. package/dist/lib/xterm/src/browser/Viewport.ts +148 -357
  18. package/dist/lib/xterm/src/browser/decorations/BufferDecorationRenderer.ts +17 -12
  19. package/dist/lib/xterm/src/browser/decorations/OverviewRulerRenderer.ts +47 -52
  20. package/dist/lib/xterm/src/browser/input/CompositionHelper.ts +5 -3
  21. package/dist/lib/xterm/src/browser/input/MoveToCell.ts +3 -1
  22. package/dist/lib/xterm/src/browser/public/Terminal.ts +39 -24
  23. package/dist/lib/xterm/src/browser/renderer/dom/DomRenderer.ts +76 -40
  24. package/dist/lib/xterm/src/browser/renderer/dom/DomRendererRowFactory.ts +47 -23
  25. package/dist/lib/xterm/src/browser/renderer/dom/WidthCache.ts +19 -9
  26. package/dist/lib/xterm/src/browser/renderer/shared/Constants.ts +0 -8
  27. package/dist/lib/xterm/src/browser/renderer/shared/RendererUtils.ts +38 -1
  28. package/dist/lib/xterm/src/browser/renderer/shared/SelectionRenderModel.ts +6 -4
  29. package/dist/lib/xterm/src/browser/renderer/shared/Types.ts +84 -0
  30. package/dist/lib/xterm/src/browser/selection/Types.ts +15 -0
  31. package/dist/lib/xterm/src/browser/services/CharSizeService.ts +57 -32
  32. package/dist/lib/xterm/src/browser/services/CoreBrowserService.ts +108 -4
  33. package/dist/lib/xterm/src/browser/services/LinkProviderService.ts +28 -0
  34. package/dist/lib/xterm/src/browser/services/RenderService.ts +132 -40
  35. package/dist/lib/xterm/src/browser/services/SelectionService.ts +19 -9
  36. package/dist/lib/xterm/src/browser/services/Services.ts +36 -16
  37. package/dist/lib/xterm/src/browser/services/ThemeService.ts +19 -58
  38. package/dist/lib/xterm/src/browser/shared/Constants.ts +8 -0
  39. package/dist/lib/xterm/src/common/CircularList.ts +5 -5
  40. package/dist/lib/xterm/src/common/Color.ts +34 -14
  41. package/dist/lib/xterm/src/common/CoreTerminal.ts +40 -41
  42. package/dist/lib/xterm/src/common/InputHandler.ts +177 -125
  43. package/dist/lib/xterm/src/common/Platform.ts +2 -1
  44. package/dist/lib/xterm/src/common/SortedList.ts +86 -10
  45. package/dist/lib/xterm/src/common/TaskQueue.ts +7 -7
  46. package/dist/lib/xterm/src/common/Types.ts +552 -0
  47. package/dist/lib/xterm/src/common/buffer/AttributeData.ts +15 -0
  48. package/dist/lib/xterm/src/common/buffer/Buffer.ts +15 -7
  49. package/dist/lib/xterm/src/common/buffer/BufferLine.ts +53 -22
  50. package/dist/lib/xterm/src/common/buffer/BufferRange.ts +1 -1
  51. package/dist/lib/xterm/src/common/buffer/BufferReflow.ts +9 -6
  52. package/dist/lib/xterm/src/common/buffer/BufferSet.ts +5 -5
  53. package/dist/lib/xterm/src/common/buffer/Constants.ts +10 -2
  54. package/dist/lib/xterm/src/common/buffer/Marker.ts +4 -4
  55. package/dist/lib/xterm/src/common/buffer/Types.ts +52 -0
  56. package/dist/lib/xterm/src/common/input/Keyboard.ts +2 -27
  57. package/dist/lib/xterm/src/common/input/UnicodeV6.ts +18 -5
  58. package/dist/lib/xterm/src/common/input/WriteBuffer.ts +9 -8
  59. package/dist/lib/xterm/src/common/parser/EscapeSequenceParser.ts +13 -13
  60. package/dist/lib/xterm/src/common/parser/Types.ts +275 -0
  61. package/dist/lib/xterm/src/common/public/AddonManager.ts +1 -1
  62. package/dist/lib/xterm/src/common/public/BufferApiView.ts +1 -1
  63. package/dist/lib/xterm/src/common/public/BufferLineApiView.ts +1 -1
  64. package/dist/lib/xterm/src/common/public/BufferNamespaceApi.ts +4 -4
  65. package/dist/lib/xterm/src/common/public/ParserApi.ts +1 -1
  66. package/dist/lib/xterm/src/common/public/UnicodeApi.ts +1 -1
  67. package/dist/lib/xterm/src/common/services/BufferService.ts +14 -11
  68. package/dist/lib/xterm/src/common/services/CoreMouseService.ts +53 -6
  69. package/dist/lib/xterm/src/common/services/CoreService.ts +13 -8
  70. package/dist/lib/xterm/src/common/services/DecorationService.ts +11 -11
  71. package/dist/lib/xterm/src/common/services/InstantiationService.ts +1 -1
  72. package/dist/lib/xterm/src/common/services/LogService.ts +2 -2
  73. package/dist/lib/xterm/src/common/services/OptionsService.ts +16 -5
  74. package/dist/lib/xterm/src/common/services/ServiceRegistry.ts +1 -1
  75. package/dist/lib/xterm/src/common/services/Services.ts +73 -19
  76. package/dist/lib/xterm/src/common/services/UnicodeService.ts +30 -5
  77. package/dist/lib/xterm/src/vs/base/browser/browser.ts +141 -0
  78. package/dist/lib/xterm/src/vs/base/browser/canIUse.ts +49 -0
  79. package/dist/lib/xterm/src/vs/base/browser/dom.ts +2369 -0
  80. package/dist/lib/xterm/src/vs/base/browser/fastDomNode.ts +316 -0
  81. package/dist/lib/xterm/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
  82. package/dist/lib/xterm/src/vs/base/browser/iframe.ts +135 -0
  83. package/dist/lib/xterm/src/vs/base/browser/keyboardEvent.ts +213 -0
  84. package/dist/lib/xterm/src/vs/base/browser/mouseEvent.ts +229 -0
  85. package/dist/lib/xterm/src/vs/base/browser/touch.ts +372 -0
  86. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
  87. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
  88. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
  89. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
  90. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
  91. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
  92. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
  93. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
  94. package/dist/lib/xterm/src/vs/base/browser/ui/widget.ts +57 -0
  95. package/dist/lib/xterm/src/vs/base/browser/window.ts +14 -0
  96. package/dist/lib/xterm/src/vs/base/common/arrays.ts +887 -0
  97. package/dist/lib/xterm/src/vs/base/common/arraysFind.ts +202 -0
  98. package/dist/lib/xterm/src/vs/base/common/assert.ts +71 -0
  99. package/dist/lib/xterm/src/vs/base/common/async.ts +1992 -0
  100. package/dist/lib/xterm/src/vs/base/common/cancellation.ts +148 -0
  101. package/dist/lib/xterm/src/vs/base/common/charCode.ts +450 -0
  102. package/dist/lib/xterm/src/vs/base/common/collections.ts +140 -0
  103. package/dist/lib/xterm/src/vs/base/common/decorators.ts +130 -0
  104. package/dist/lib/xterm/src/vs/base/common/equals.ts +146 -0
  105. package/dist/lib/xterm/src/vs/base/common/errors.ts +303 -0
  106. package/dist/lib/xterm/src/vs/base/common/event.ts +1778 -0
  107. package/dist/lib/xterm/src/vs/base/common/functional.ts +32 -0
  108. package/dist/lib/xterm/src/vs/base/common/hash.ts +316 -0
  109. package/dist/lib/xterm/src/vs/base/common/iterator.ts +159 -0
  110. package/dist/lib/xterm/src/vs/base/common/keyCodes.ts +526 -0
  111. package/dist/lib/xterm/src/vs/base/common/keybindings.ts +284 -0
  112. package/dist/lib/xterm/src/vs/base/common/lazy.ts +47 -0
  113. package/dist/lib/xterm/src/vs/base/common/lifecycle.ts +801 -0
  114. package/dist/lib/xterm/src/vs/base/common/linkedList.ts +142 -0
  115. package/dist/lib/xterm/src/vs/base/common/map.ts +202 -0
  116. package/dist/lib/xterm/src/vs/base/common/numbers.ts +98 -0
  117. package/dist/lib/xterm/src/vs/base/common/observable.ts +76 -0
  118. package/dist/lib/xterm/src/vs/base/common/observableInternal/api.ts +31 -0
  119. package/dist/lib/xterm/src/vs/base/common/observableInternal/autorun.ts +281 -0
  120. package/dist/lib/xterm/src/vs/base/common/observableInternal/base.ts +489 -0
  121. package/dist/lib/xterm/src/vs/base/common/observableInternal/debugName.ts +145 -0
  122. package/dist/lib/xterm/src/vs/base/common/observableInternal/derived.ts +428 -0
  123. package/dist/lib/xterm/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
  124. package/dist/lib/xterm/src/vs/base/common/observableInternal/logging.ts +328 -0
  125. package/dist/lib/xterm/src/vs/base/common/observableInternal/promise.ts +209 -0
  126. package/dist/lib/xterm/src/vs/base/common/observableInternal/utils.ts +610 -0
  127. package/dist/lib/xterm/src/vs/base/common/platform.ts +281 -0
  128. package/dist/lib/xterm/src/vs/base/common/scrollable.ts +522 -0
  129. package/dist/lib/xterm/src/vs/base/common/sequence.ts +34 -0
  130. package/dist/lib/xterm/src/vs/base/common/stopwatch.ts +43 -0
  131. package/dist/lib/xterm/src/vs/base/common/strings.ts +557 -0
  132. package/dist/lib/xterm/src/vs/base/common/symbols.ts +9 -0
  133. package/dist/lib/xterm/src/vs/base/common/uint.ts +59 -0
  134. package/dist/lib/xterm/src/vs/patches/nls.ts +90 -0
  135. package/dist/lib/xterm/src/vs/typings/base-common.d.ts +20 -0
  136. package/dist/lib/xterm/src/vs/typings/require.d.ts +42 -0
  137. package/dist/lib/xterm/src/vs/typings/vscode-globals-nls.d.ts +36 -0
  138. package/dist/lib/xterm/src/vs/typings/vscode-globals-product.d.ts +33 -0
  139. package/dist/lib/xterm/typings/xterm.d.ts +156 -43
  140. package/dist/lib/xterm-fit/README.md +5 -5
  141. package/dist/lib/xterm-fit/lib/addon-fit.js +2 -0
  142. package/dist/lib/xterm-fit/lib/addon-fit.js.map +1 -0
  143. package/dist/lib/xterm-fit/lib/addon-fit.mjs +18 -0
  144. package/dist/lib/xterm-fit/lib/addon-fit.mjs.map +7 -0
  145. package/dist/lib/xterm-fit/package.json +9 -9
  146. package/dist/lib/xterm-fit/src/FitAddon.ts +7 -4
  147. package/dist/lib/xterm-fit/typings/addon-fit.d.ts +55 -0
  148. package/dist/lib/xterm-links/README.md +5 -5
  149. package/dist/lib/xterm-links/lib/addon-web-links.js +2 -0
  150. package/dist/lib/xterm-links/lib/addon-web-links.js.map +1 -0
  151. package/dist/lib/xterm-links/lib/addon-web-links.mjs +18 -0
  152. package/dist/lib/xterm-links/lib/addon-web-links.mjs.map +7 -0
  153. package/dist/lib/xterm-links/package.json +9 -9
  154. package/dist/lib/xterm-links/src/WebLinkProvider.ts +16 -15
  155. package/dist/lib/xterm-links/src/WebLinksAddon.ts +4 -3
  156. package/dist/lib/xterm-links/typings/addon-web-links.d.ts +57 -0
  157. package/package.json +5 -6
@@ -4,19 +4,46 @@
4
4
  */
5
5
 
6
6
  import { ICoreBrowserService } from './Services';
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';
7
10
 
8
- export class CoreBrowserService implements ICoreBrowserService {
11
+ export class CoreBrowserService extends Disposable implements ICoreBrowserService {
9
12
  public serviceBrand: undefined;
10
13
 
11
14
  private _isFocused = false;
12
15
  private _cachedIsFocused: boolean | undefined = undefined;
16
+ private _screenDprMonitor = this._register(new ScreenDprMonitor(this._window));
17
+
18
+ private readonly _onDprChange = this._register(new Emitter<number>());
19
+ public readonly onDprChange = this._onDprChange.event;
20
+ private readonly _onWindowChange = this._register(new Emitter<Window & typeof globalThis>());
21
+ public readonly onWindowChange = this._onWindowChange.event;
13
22
 
14
23
  constructor(
15
24
  private _textarea: HTMLTextAreaElement,
16
- public readonly window: Window & typeof globalThis
25
+ private _window: Window & typeof globalThis,
26
+ public readonly mainDocument: Document
17
27
  ) {
18
- this._textarea.addEventListener('focus', () => this._isFocused = true);
19
- this._textarea.addEventListener('blur', () => this._isFocused = false);
28
+ super();
29
+
30
+ // Monitor device pixel ratio
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));
36
+ }
37
+
38
+ public get window(): Window & typeof globalThis {
39
+ return this._window;
40
+ }
41
+
42
+ public set window(value: Window & typeof globalThis) {
43
+ if (this._window !== value) {
44
+ this._window = value;
45
+ this._onWindowChange.fire(this._window);
46
+ }
20
47
  }
21
48
 
22
49
  public get dpr(): number {
@@ -31,3 +58,80 @@ export class CoreBrowserService implements ICoreBrowserService {
31
58
  return this._cachedIsFocused;
32
59
  }
33
60
  }
61
+
62
+
63
+ /**
64
+ * The screen device pixel ratio monitor allows listening for when the
65
+ * window.devicePixelRatio value changes. This is done not with polling but with
66
+ * the use of window.matchMedia to watch media queries. When the event fires,
67
+ * the listener will be reattached using a different media query to ensure that
68
+ * any further changes will _register.
69
+ *
70
+ * The listener should fire on both window zoom changes and switching to a
71
+ * monitor with a different DPI.
72
+ */
73
+ class ScreenDprMonitor extends Disposable {
74
+ private _currentDevicePixelRatio: number;
75
+ private _outerListener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | undefined;
76
+ private _resolutionMediaMatchList: MediaQueryList | undefined;
77
+ private _windowResizeListener = this._register(new MutableDisposable());
78
+
79
+ private readonly _onDprChange = this._register(new Emitter<number>());
80
+ public readonly onDprChange = this._onDprChange.event;
81
+
82
+ constructor(private _parentWindow: Window) {
83
+ super();
84
+
85
+ // Initialize listener and dpr value
86
+ this._outerListener = () => this._setDprAndFireIfDiffers();
87
+ this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;
88
+ this._updateDpr();
89
+
90
+ // Monitor active window resize
91
+ this._setWindowResizeListener();
92
+
93
+ // Setup additional disposables
94
+ this._register(toDisposable(() => this.clearListener()));
95
+ }
96
+
97
+
98
+ public setWindow(parentWindow: Window): void {
99
+ this._parentWindow = parentWindow;
100
+ this._setWindowResizeListener();
101
+ this._setDprAndFireIfDiffers();
102
+ }
103
+
104
+ private _setWindowResizeListener(): void {
105
+ this._windowResizeListener.value = addDisposableListener(this._parentWindow, 'resize', () => this._setDprAndFireIfDiffers());
106
+ }
107
+
108
+ private _setDprAndFireIfDiffers(): void {
109
+ if (this._parentWindow.devicePixelRatio !== this._currentDevicePixelRatio) {
110
+ this._onDprChange.fire(this._parentWindow.devicePixelRatio);
111
+ }
112
+ this._updateDpr();
113
+ }
114
+
115
+ private _updateDpr(): void {
116
+ if (!this._outerListener) {
117
+ return;
118
+ }
119
+
120
+ // Clear listeners for old DPR
121
+ this._resolutionMediaMatchList?.removeListener(this._outerListener);
122
+
123
+ // Add listeners for new DPR
124
+ this._currentDevicePixelRatio = this._parentWindow.devicePixelRatio;
125
+ this._resolutionMediaMatchList = this._parentWindow.matchMedia(`screen and (resolution: ${this._parentWindow.devicePixelRatio}dppx)`);
126
+ this._resolutionMediaMatchList.addListener(this._outerListener);
127
+ }
128
+
129
+ public clearListener(): void {
130
+ if (!this._resolutionMediaMatchList || !this._outerListener) {
131
+ return;
132
+ }
133
+ this._resolutionMediaMatchList.removeListener(this._outerListener);
134
+ this._resolutionMediaMatchList = undefined;
135
+ this._outerListener = undefined;
136
+ }
137
+ }
@@ -0,0 +1,28 @@
1
+ import { ILinkProvider, ILinkProviderService } from 'browser/services/Services';
2
+ import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
3
+ import { IDisposable } from 'common/Types';
4
+
5
+ export class LinkProviderService extends Disposable implements ILinkProviderService {
6
+ declare public serviceBrand: undefined;
7
+
8
+ public readonly linkProviders: ILinkProvider[] = [];
9
+
10
+ constructor() {
11
+ super();
12
+ this._register(toDisposable(() => this.linkProviders.length = 0));
13
+ }
14
+
15
+ public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
16
+ this.linkProviders.push(linkProvider);
17
+ return {
18
+ dispose: () => {
19
+ // Remove the link provider from the list
20
+ const providerIndex = this.linkProviders.indexOf(linkProvider);
21
+
22
+ if (providerIndex !== -1) {
23
+ this.linkProviders.splice(providerIndex, 1);
24
+ }
25
+ }
26
+ };
27
+ }
28
+ }
@@ -3,16 +3,14 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { addDisposableDomListener } from 'browser/Lifecycle';
7
6
  import { RenderDebouncer } from 'browser/RenderDebouncer';
8
- import { ScreenDprMonitor } from 'browser/ScreenDprMonitor';
9
7
  import { IRenderDebouncerWithCallback } from 'browser/Types';
10
8
  import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types';
11
9
  import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
12
- import { EventEmitter } from 'common/EventEmitter';
13
- import { Disposable, MutableDisposable } from 'common/Lifecycle';
10
+ import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
14
11
  import { DebouncedIdleTask } from 'common/TaskQueue';
15
- 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';
16
14
 
17
15
  interface ISelectionState {
18
16
  start: [number, number] | undefined;
@@ -20,13 +18,17 @@ interface ISelectionState {
20
18
  columnSelectMode: boolean;
21
19
  }
22
20
 
21
+ const enum Constants {
22
+ SYNCHRONIZED_OUTPUT_TIMEOUT_MS = 1000
23
+ }
24
+
23
25
  export class RenderService extends Disposable implements IRenderService {
24
26
  public serviceBrand: undefined;
25
27
 
26
- private _renderer: MutableDisposable<IRenderer> = this.register(new MutableDisposable());
28
+ private _renderer: MutableDisposable<IRenderer> = this._register(new MutableDisposable());
27
29
  private _renderDebouncer: IRenderDebouncerWithCallback;
28
- private _screenDprMonitor: ScreenDprMonitor;
29
30
  private _pausedResizeTask = new DebouncedIdleTask();
31
+ private _observerDisposable = this._register(new MutableDisposable());
30
32
 
31
33
  private _isPaused: boolean = false;
32
34
  private _needsFullRefresh: boolean = false;
@@ -34,19 +36,20 @@ export class RenderService extends Disposable implements IRenderService {
34
36
  private _needsSelectionRefresh: boolean = false;
35
37
  private _canvasWidth: number = 0;
36
38
  private _canvasHeight: number = 0;
39
+ private _syncOutputHandler: SynchronizedOutputHandler;
37
40
  private _selectionState: ISelectionState = {
38
41
  start: undefined,
39
42
  end: undefined,
40
43
  columnSelectMode: false
41
44
  };
42
45
 
43
- private readonly _onDimensionsChange = this.register(new EventEmitter<IRenderDimensions>());
44
- public readonly onDimensionsChange = this._onDimensionsChange.event;
45
- private readonly _onRenderedViewportChange = this.register(new EventEmitter<{ start: number, end: number }>());
46
+ private readonly _onDimensionsChange = this._register(new Emitter<IRenderDimensions>());
47
+ public readonly onDimensionsChange = this._onDimensionsChange.event;
48
+ private readonly _onRenderedViewportChange = this._register(new Emitter<{ start: number, end: number }>());
46
49
  public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;
47
- private readonly _onRender = this.register(new EventEmitter<{ start: number, end: number }>());
50
+ private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());
48
51
  public readonly onRender = this._onRender.event;
49
- private readonly _onRefreshRequest = this.register(new EventEmitter<{ start: number, end: number }>());
52
+ private readonly _onRefreshRequest = this._register(new Emitter<{ start: number, end: number }>());
50
53
  public readonly onRefreshRequest = this._onRefreshRequest.event;
51
54
 
52
55
  public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }
@@ -54,35 +57,41 @@ export class RenderService extends Disposable implements IRenderService {
54
57
  constructor(
55
58
  private _rowCount: number,
56
59
  screenElement: HTMLElement,
57
- @IOptionsService optionsService: IOptionsService,
60
+ @IOptionsService private readonly _optionsService: IOptionsService,
58
61
  @ICharSizeService private readonly _charSizeService: ICharSizeService,
62
+ @ICoreService private readonly _coreService: ICoreService,
59
63
  @IDecorationService decorationService: IDecorationService,
60
64
  @IBufferService bufferService: IBufferService,
61
- @ICoreBrowserService coreBrowserService: ICoreBrowserService,
65
+ @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,
62
66
  @IThemeService themeService: IThemeService
63
67
  ) {
64
68
  super();
65
69
 
66
- this._renderDebouncer = new RenderDebouncer(coreBrowserService.window, (start, end) => this._renderRows(start, end));
67
- this.register(this._renderDebouncer);
70
+ this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end), this._coreBrowserService);
71
+ this._register(this._renderDebouncer);
72
+
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._screenDprMonitor = new ScreenDprMonitor(coreBrowserService.window);
70
- this._screenDprMonitor.setListener(() => this.handleDevicePixelRatioChange());
71
- this.register(this._screenDprMonitor);
80
+ this._register(this._coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));
72
81
 
73
- this.register(bufferService.onResize(() => this._fullRefresh()));
74
- this.register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));
75
- this.register(optionsService.onOptionChange(() => this._handleOptionsChanged()));
76
- this.register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));
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()));
77
86
 
78
87
  // Do a full refresh whenever any decoration is added or removed. This may not actually result
79
88
  // in changes but since decorations should be used sparingly or added/removed all in the same
80
89
  // frame this should have minimal performance impact.
81
- this.register(decorationService.onDecorationRegistered(() => this._fullRefresh()));
82
- this.register(decorationService.onDecorationRemoved(() => this._fullRefresh()));
90
+ this._register(decorationService.onDecorationRegistered(() => this._fullRefresh()));
91
+ this._register(decorationService.onDecorationRemoved(() => this._fullRefresh()));
83
92
 
84
93
  // Clear the renderer when the a change that could affect glyphs occurs
85
- this.register(optionsService.onMultipleOptionChange([
94
+ this._register(this._optionsService.onMultipleOptionChange([
86
95
  'customGlyphs',
87
96
  'drawBoldTextInBrightColors',
88
97
  'letterSpacing',
@@ -91,7 +100,8 @@ export class RenderService extends Disposable implements IRenderService {
91
100
  'fontSize',
92
101
  'fontWeight',
93
102
  'fontWeightBold',
94
- 'minimumContrastRatio'
103
+ 'minimumContrastRatio',
104
+ 'rescaleOverlappingGlyphs'
95
105
  ], () => {
96
106
  this.clear();
97
107
  this.handleResize(bufferService.cols, bufferService.rows);
@@ -99,23 +109,24 @@ export class RenderService extends Disposable implements IRenderService {
99
109
  }));
100
110
 
101
111
  // Refresh the cursor line when the cursor changes
102
- this.register(optionsService.onMultipleOptionChange([
112
+ this._register(this._optionsService.onMultipleOptionChange([
103
113
  'cursorBlink',
104
114
  'cursorStyle'
105
115
  ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, true)));
106
116
 
107
- // dprchange should handle this case, we need this as well for browsers that don't support the
108
- // matchMedia query.
109
- this.register(addDisposableDomListener(coreBrowserService.window, 'resize', () => this.handleDevicePixelRatioChange()));
117
+ this._register(themeService.onChangeColors(() => this._fullRefresh()));
110
118
 
111
- this.register(themeService.onChangeColors(() => this._fullRefresh()));
119
+ this._registerIntersectionObserver(this._coreBrowserService.window, screenElement);
120
+ this._register(this._coreBrowserService.onWindowChange((w) => this._registerIntersectionObserver(w, screenElement)));
121
+ }
112
122
 
123
+ private _registerIntersectionObserver(w: Window & typeof globalThis, screenElement: HTMLElement): void {
113
124
  // Detect whether IntersectionObserver is detected and enable renderer pause
114
125
  // and resume based on terminal visibility if so
115
- if ('IntersectionObserver' in coreBrowserService.window) {
116
- const observer = new coreBrowserService.window.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });
126
+ if ('IntersectionObserver' in w) {
127
+ const observer = new w.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });
117
128
  observer.observe(screenElement);
118
- this.register({ dispose: () => observer.disconnect() });
129
+ this._observerDisposable.value = toDisposable(() => observer.disconnect());
119
130
  }
120
131
  }
121
132
 
@@ -139,6 +150,18 @@ export class RenderService extends Disposable implements IRenderService {
139
150
  this._needsFullRefresh = true;
140
151
  return;
141
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
+
142
165
  if (!isRedrawOnly) {
143
166
  this._isNextRenderRedrawOnly = false;
144
167
  }
@@ -150,6 +173,13 @@ export class RenderService extends Disposable implements IRenderService {
150
173
  return;
151
174
  }
152
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
+
153
183
  // Since this is debounced, a resize event could have happened between the time a refresh was
154
184
  // requested and when this triggers. Clamp the values of start and end to ensure they're valid
155
185
  // given the current viewport state.
@@ -203,11 +233,14 @@ export class RenderService extends Disposable implements IRenderService {
203
233
 
204
234
  public setRenderer(renderer: IRenderer): void {
205
235
  this._renderer.value = renderer;
206
- this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
236
+ // If the value was not set, the terminal is being disposed so ignore it
237
+ if (this._renderer.value) {
238
+ this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
207
239
 
208
- // Force a refresh
209
- this._needsSelectionRefresh = true;
210
- this._fullRefresh();
240
+ // Force a refresh
241
+ this._needsSelectionRefresh = true;
242
+ this._fullRefresh();
243
+ }
211
244
  }
212
245
 
213
246
  public addRefreshCallback(callback: FrameRequestCallback): number {
@@ -247,7 +280,7 @@ export class RenderService extends Disposable implements IRenderService {
247
280
  return;
248
281
  }
249
282
  if (this._isPaused) {
250
- this._pausedResizeTask.set(() => this._renderer.value!.handleResize(cols, rows));
283
+ this._pausedResizeTask.set(() => this._renderer.value?.handleResize(cols, rows));
251
284
  } else {
252
285
  this._renderer.value.handleResize(cols, rows);
253
286
  }
@@ -282,3 +315,62 @@ export class RenderService extends Disposable implements IRenderService {
282
315
  this._renderer.value?.clear();
283
316
  }
284
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 { EventEmitter } from 'common/EventEmitter';
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.register(new EventEmitter<string>());
114
+ private readonly _onLinuxMouseSelection = this._register(new Emitter<string>());
115
115
  public readonly onLinuxMouseSelection = this._onLinuxMouseSelection.event;
116
- private readonly _onRedrawRequest = this.register(new EventEmitter<ISelectionRedrawRequestEvent>());
116
+ private readonly _onRedrawRequest = this._register(new Emitter<ISelectionRedrawRequestEvent>());
117
117
  public readonly onRequestRedraw = this._onRedrawRequest.event;
118
- private readonly _onSelectionChange = this.register(new EventEmitter<void>());
118
+ private readonly _onSelectionChange = this._register(new Emitter<void>());
119
119
  public readonly onSelectionChange = this._onSelectionChange.event;
120
- private readonly _onRequestScrollLines = this.register(new EventEmitter<ISelectionRequestScrollLinesEvent>());
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.register(this._bufferService.buffers.onBufferActivate(e => this._handleBufferActivate(e)));
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.register(toDisposable(() => {
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 {
@@ -644,7 +652,9 @@ export class SelectionService extends Disposable implements ISelectionService {
644
652
  if (this._model.selectionEnd[1] < buffer.lines.length) {
645
653
  const line = buffer.lines.get(this._model.selectionEnd[1]);
646
654
  if (line && line.hasWidth(this._model.selectionEnd[0]) === 0) {
647
- this._model.selectionEnd[0]++;
655
+ if (this._model.selectionEnd[0] < this._bufferService.cols) {
656
+ this._model.selectionEnd[0]++;
657
+ }
648
658
  }
649
659
  }
650
660
 
@@ -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
- import { IColorSet, ReadonlyColorSet } from 'browser/Types';
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: IEvent<void>;
21
+ readonly onCharSizeChange: Event<void>;
22
22
 
23
23
  measure(): void;
24
24
  }
@@ -28,12 +28,21 @@ export interface ICoreBrowserService {
28
28
  serviceBrand: undefined;
29
29
 
30
30
  readonly isFocused: boolean;
31
+
32
+ readonly onDprChange: Event<number>;
33
+ readonly onWindowChange: Event<Window & typeof globalThis>;
34
+
31
35
  /**
32
- * Parent window that the terminal is rendered into. DOM and rendering APIs
33
- * (e.g. requestAnimationFrame) should be invoked in the context of this
34
- * window.
36
+ * Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.
37
+ * requestAnimationFrame) should be invoked in the context of this window. This should be set when
38
+ * the window hosting the xterm.js instance changes.
35
39
  */
36
- readonly window: Window & typeof globalThis;
40
+ window: Window & typeof globalThis;
41
+ /**
42
+ * The document of the primary window to be used to create elements when working with multiple
43
+ * windows. This is defined by the documentOverride setting.
44
+ */
45
+ readonly mainDocument: Document;
37
46
  /**
38
47
  * Helper for getting the devicePixelRatio of the parent window.
39
48
  */
@@ -52,17 +61,17 @@ export const IRenderService = createDecorator<IRenderService>('RenderService');
52
61
  export interface IRenderService extends IDisposable {
53
62
  serviceBrand: undefined;
54
63
 
55
- onDimensionsChange: IEvent<IRenderDimensions>;
64
+ onDimensionsChange: Event<IRenderDimensions>;
56
65
  /**
57
66
  * Fires when buffer changes are rendered. This does not fire when only cursor
58
67
  * or selections are rendered.
59
68
  */
60
- onRenderedViewportChange: IEvent<{ start: number, end: number }>;
69
+ onRenderedViewportChange: Event<{ start: number, end: number }>;
61
70
  /**
62
71
  * Fires on render
63
72
  */
64
- onRender: IEvent<{ start: number, end: number }>;
65
- onRefreshRequest: IEvent<{ start: number, end: number }>;
73
+ onRender: Event<{ start: number, end: number }>;
74
+ onRefreshRequest: Event<{ start: number, end: number }>;
66
75
 
67
76
  dimensions: IRenderDimensions;
68
77
 
@@ -92,10 +101,10 @@ export interface ISelectionService {
92
101
  readonly selectionStart: [number, number] | undefined;
93
102
  readonly selectionEnd: [number, number] | undefined;
94
103
 
95
- readonly onLinuxMouseSelection: IEvent<string>;
96
- readonly onRequestRedraw: IEvent<ISelectionRequestRedrawEvent>;
97
- readonly onRequestScrollLines: IEvent<ISelectionRequestScrollLinesEvent>;
98
- readonly onSelectionChange: IEvent<void>;
104
+ readonly onLinuxMouseSelection: Event<string>;
105
+ readonly onRequestRedraw: Event<ISelectionRequestRedrawEvent>;
106
+ readonly onRequestScrollLines: Event<ISelectionRequestScrollLinesEvent>;
107
+ readonly onSelectionChange: Event<void>;
99
108
 
100
109
  disable(): void;
101
110
  enable(): void;
@@ -127,7 +136,7 @@ export interface IThemeService {
127
136
 
128
137
  readonly colors: ReadonlyColorSet;
129
138
 
130
- readonly onChangeColors: IEvent<ReadonlyColorSet>;
139
+ readonly onChangeColors: Event<ReadonlyColorSet>;
131
140
 
132
141
  restoreColor(slot?: AllColorIndex): void;
133
142
  /**
@@ -136,3 +145,14 @@ export interface IThemeService {
136
145
  */
137
146
  modifyColors(callback: (colors: IColorSet) => void): void;
138
147
  }
148
+
149
+
150
+ export const ILinkProviderService = createDecorator<ILinkProviderService>('LinkProviderService');
151
+ export interface ILinkProviderService extends IDisposable {
152
+ serviceBrand: undefined;
153
+ readonly linkProviders: ReadonlyArray<ILinkProvider>;
154
+ registerLinkProvider(linkProvider: ILinkProvider): IDisposable;
155
+ }
156
+ export interface ILinkProvider {
157
+ provideLinks(y: number, callback: (links: ILink[] | undefined) => void): void;
158
+ }