@xterm/addon-webgl 0.19.0-beta.8 → 0.19.0-beta.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@xterm/addon-webgl",
3
- "version": "0.19.0-beta.8",
3
+ "version": "0.19.0-beta.81",
4
4
  "author": {
5
5
  "name": "The xterm.js authors",
6
6
  "url": "https://xtermjs.org/"
7
7
  },
8
8
  "main": "lib/addon-webgl.js",
9
+ "module": "lib/addon-webgl.mjs",
9
10
  "types": "typings/addon-webgl.d.ts",
10
11
  "repository": "https://github.com/xtermjs/xterm.js/tree/master/addons/addon-webgl",
11
12
  "license": "MIT",
@@ -20,9 +21,10 @@
20
21
  "prepackage": "npm run build",
21
22
  "package": "../../node_modules/.bin/webpack",
22
23
  "prepublishOnly": "npm run package",
23
- "start-server-only": "node ../../demo/start-server-only"
24
+ "start": "node ../../demo/start"
24
25
  },
25
26
  "peerDependencies": {
26
- "@xterm/xterm": "^5.0.0"
27
- }
27
+ "@xterm/xterm": "^5.6.0-beta.81"
28
+ },
29
+ "commit": "cc788312620ba33466c44ec7035c0f75c7894b0d"
28
30
  }
@@ -7,7 +7,7 @@ import { allowRescaling, throwIfFalsy } from 'browser/renderer/shared/RendererUt
7
7
  import { TextureAtlas } from 'browser/renderer/shared/TextureAtlas';
8
8
  import { IRasterizedGlyph, IRenderDimensions, ITextureAtlas } from 'browser/renderer/shared/Types';
9
9
  import { NULL_CELL_CODE } from 'common/buffer/Constants';
10
- import { Disposable, toDisposable } from 'common/Lifecycle';
10
+ import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
11
11
  import { Terminal } from '@xterm/xterm';
12
12
  import { IRenderModel, IWebGL2RenderingContext, IWebGLVertexArrayObject } from './Types';
13
13
  import { createProgram, GLTexture, PROJECTION_MATRIX } from './WebglUtils';
@@ -127,7 +127,7 @@ export class GlyphRenderer extends Disposable {
127
127
  }
128
128
 
129
129
  this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, createFragmentShaderSource(TextureAtlas.maxAtlasPages)));
130
- this.register(toDisposable(() => gl.deleteProgram(this._program)));
130
+ this._register(toDisposable(() => gl.deleteProgram(this._program)));
131
131
 
132
132
  // Uniform locations
133
133
  this._projectionLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_projection'));
@@ -141,7 +141,7 @@ export class GlyphRenderer extends Disposable {
141
141
  // Setup a_unitquad, this defines the 4 vertices of a rectangle
142
142
  const unitQuadVertices = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
143
143
  const unitQuadVerticesBuffer = gl.createBuffer();
144
- this.register(toDisposable(() => gl.deleteBuffer(unitQuadVerticesBuffer)));
144
+ this._register(toDisposable(() => gl.deleteBuffer(unitQuadVerticesBuffer)));
145
145
  gl.bindBuffer(gl.ARRAY_BUFFER, unitQuadVerticesBuffer);
146
146
  gl.bufferData(gl.ARRAY_BUFFER, unitQuadVertices, gl.STATIC_DRAW);
147
147
  gl.enableVertexAttribArray(VertexAttribLocations.UNIT_QUAD);
@@ -152,13 +152,13 @@ export class GlyphRenderer extends Disposable {
152
152
  // triangle strip
153
153
  const unitQuadElementIndices = new Uint8Array([0, 1, 2, 3]);
154
154
  const elementIndicesBuffer = gl.createBuffer();
155
- this.register(toDisposable(() => gl.deleteBuffer(elementIndicesBuffer)));
155
+ this._register(toDisposable(() => gl.deleteBuffer(elementIndicesBuffer)));
156
156
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementIndicesBuffer);
157
157
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, unitQuadElementIndices, gl.STATIC_DRAW);
158
158
 
159
159
  // Setup attributes
160
160
  this._attributesBuffer = throwIfFalsy(gl.createBuffer());
161
- this.register(toDisposable(() => gl.deleteBuffer(this._attributesBuffer)));
161
+ this._register(toDisposable(() => gl.deleteBuffer(this._attributesBuffer)));
162
162
  gl.bindBuffer(gl.ARRAY_BUFFER, this._attributesBuffer);
163
163
  gl.enableVertexAttribArray(VertexAttribLocations.OFFSET);
164
164
  gl.vertexAttribPointer(VertexAttribLocations.OFFSET, 2, gl.FLOAT, false, BYTES_PER_CELL, 0);
@@ -193,7 +193,7 @@ export class GlyphRenderer extends Disposable {
193
193
  this._atlasTextures = [];
194
194
  for (let i = 0; i < TextureAtlas.maxAtlasPages; i++) {
195
195
  const glTexture = new GLTexture(throwIfFalsy(gl.createTexture()));
196
- this.register(toDisposable(() => gl.deleteTexture(glTexture.texture)));
196
+ this._register(toDisposable(() => gl.deleteTexture(glTexture.texture)));
197
197
  gl.activeTexture(gl.TEXTURE0 + i);
198
198
  gl.bindTexture(gl.TEXTURE_2D, glTexture.texture);
199
199
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
@@ -8,7 +8,7 @@ import { IRenderDimensions } from 'browser/renderer/shared/Types';
8
8
  import { IThemeService } from 'browser/services/Services';
9
9
  import { ReadonlyColorSet } from 'browser/Types';
10
10
  import { Attributes, FgFlags } from 'common/buffer/Constants';
11
- import { Disposable, toDisposable } from 'common/Lifecycle';
11
+ import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
12
12
  import { IColor } from 'common/Types';
13
13
  import { Terminal } from '@xterm/xterm';
14
14
  import { RENDER_MODEL_BG_OFFSET, RENDER_MODEL_FG_OFFSET, RENDER_MODEL_INDICIES_PER_CELL } from './RenderModel';
@@ -96,7 +96,7 @@ export class RectangleRenderer extends Disposable {
96
96
  const gl = this._gl;
97
97
 
98
98
  this._program = throwIfFalsy(createProgram(gl, vertexShaderSource, fragmentShaderSource));
99
- this.register(toDisposable(() => gl.deleteProgram(this._program)));
99
+ this._register(toDisposable(() => gl.deleteProgram(this._program)));
100
100
 
101
101
  // Uniform locations
102
102
  this._projectionLocation = throwIfFalsy(gl.getUniformLocation(this._program, 'u_projection'));
@@ -108,7 +108,7 @@ export class RectangleRenderer extends Disposable {
108
108
  // Setup a_unitquad, this defines the 4 vertices of a rectangle
109
109
  const unitQuadVertices = new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]);
110
110
  const unitQuadVerticesBuffer = gl.createBuffer();
111
- this.register(toDisposable(() => gl.deleteBuffer(unitQuadVerticesBuffer)));
111
+ this._register(toDisposable(() => gl.deleteBuffer(unitQuadVerticesBuffer)));
112
112
  gl.bindBuffer(gl.ARRAY_BUFFER, unitQuadVerticesBuffer);
113
113
  gl.bufferData(gl.ARRAY_BUFFER, unitQuadVertices, gl.STATIC_DRAW);
114
114
  gl.enableVertexAttribArray(VertexAttribLocations.UNIT_QUAD);
@@ -119,13 +119,13 @@ export class RectangleRenderer extends Disposable {
119
119
  // triangle strip
120
120
  const unitQuadElementIndices = new Uint8Array([0, 1, 2, 3]);
121
121
  const elementIndicesBuffer = gl.createBuffer();
122
- this.register(toDisposable(() => gl.deleteBuffer(elementIndicesBuffer)));
122
+ this._register(toDisposable(() => gl.deleteBuffer(elementIndicesBuffer)));
123
123
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elementIndicesBuffer);
124
124
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, unitQuadElementIndices, gl.STATIC_DRAW);
125
125
 
126
126
  // Setup attributes
127
127
  this._attributesBuffer = throwIfFalsy(gl.createBuffer());
128
- this.register(toDisposable(() => gl.deleteBuffer(this._attributesBuffer)));
128
+ this._register(toDisposable(() => gl.deleteBuffer(this._attributesBuffer)));
129
129
  gl.bindBuffer(gl.ARRAY_BUFFER, this._attributesBuffer);
130
130
  gl.enableVertexAttribArray(VertexAttribLocations.POSITION);
131
131
  gl.vertexAttribPointer(VertexAttribLocations.POSITION, 2, gl.FLOAT, false, BYTES_PER_RECTANGLE, 0);
@@ -138,7 +138,7 @@ export class RectangleRenderer extends Disposable {
138
138
  gl.vertexAttribDivisor(VertexAttribLocations.COLOR, 1);
139
139
 
140
140
  this._updateCachedColors(_themeService.colors);
141
- this.register(this._themeService.onChangeColors(e => {
141
+ this._register(this._themeService.onChangeColors(e => {
142
142
  this._updateCachedColors(e);
143
143
  this._updateViewportRectangle();
144
144
  }));
package/src/WebglAddon.ts CHANGED
@@ -7,25 +7,25 @@ import type { ITerminalAddon, Terminal } from '@xterm/xterm';
7
7
  import type { WebglAddon as IWebglApi } from '@xterm/addon-webgl';
8
8
  import { ICharacterJoinerService, ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
9
9
  import { ITerminal } from 'browser/Types';
10
- import { EventEmitter, forwardEvent } from 'common/EventEmitter';
11
- import { Disposable, toDisposable } from 'common/Lifecycle';
10
+ import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
12
11
  import { getSafariVersion, isSafari } from 'common/Platform';
13
12
  import { ICoreService, IDecorationService, ILogService, IOptionsService } from 'common/services/Services';
14
13
  import { IWebGL2RenderingContext } from './Types';
15
14
  import { WebglRenderer } from './WebglRenderer';
16
15
  import { setTraceLogger } from 'common/services/LogService';
16
+ import { Emitter, Event } from 'vs/base/common/event';
17
17
 
18
18
  export class WebglAddon extends Disposable implements ITerminalAddon , IWebglApi {
19
19
  private _terminal?: Terminal;
20
20
  private _renderer?: WebglRenderer;
21
21
 
22
- private readonly _onChangeTextureAtlas = this.register(new EventEmitter<HTMLCanvasElement>());
22
+ private readonly _onChangeTextureAtlas = this._register(new Emitter<HTMLCanvasElement>());
23
23
  public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event;
24
- private readonly _onAddTextureAtlasCanvas = this.register(new EventEmitter<HTMLCanvasElement>());
24
+ private readonly _onAddTextureAtlasCanvas = this._register(new Emitter<HTMLCanvasElement>());
25
25
  public readonly onAddTextureAtlasCanvas = this._onAddTextureAtlasCanvas.event;
26
- private readonly _onRemoveTextureAtlasCanvas = this.register(new EventEmitter<HTMLCanvasElement>());
26
+ private readonly _onRemoveTextureAtlasCanvas = this._register(new Emitter<HTMLCanvasElement>());
27
27
  public readonly onRemoveTextureAtlasCanvas = this._onRemoveTextureAtlasCanvas.event;
28
- private readonly _onContextLoss = this.register(new EventEmitter<void>());
28
+ private readonly _onContextLoss = this._register(new Emitter<void>());
29
29
  public readonly onContextLoss = this._onContextLoss.event;
30
30
 
31
31
  constructor(
@@ -49,7 +49,7 @@ export class WebglAddon extends Disposable implements ITerminalAddon , IWebglApi
49
49
  public activate(terminal: Terminal): void {
50
50
  const core = (terminal as any)._core as ITerminal;
51
51
  if (!terminal.element) {
52
- this.register(core.onWillOpen(() => this.activate(terminal)));
52
+ this._register(core.onWillOpen(() => this.activate(terminal)));
53
53
  return;
54
54
  }
55
55
 
@@ -70,7 +70,7 @@ export class WebglAddon extends Disposable implements ITerminalAddon , IWebglApi
70
70
  // bundled separately to the core module
71
71
  setTraceLogger(logService);
72
72
 
73
- this._renderer = this.register(new WebglRenderer(
73
+ this._renderer = this._register(new WebglRenderer(
74
74
  terminal,
75
75
  characterJoinerService,
76
76
  charSizeService,
@@ -81,13 +81,16 @@ export class WebglAddon extends Disposable implements ITerminalAddon , IWebglApi
81
81
  themeService,
82
82
  this._preserveDrawingBuffer
83
83
  ));
84
- this.register(forwardEvent(this._renderer.onContextLoss, this._onContextLoss));
85
- this.register(forwardEvent(this._renderer.onChangeTextureAtlas, this._onChangeTextureAtlas));
86
- this.register(forwardEvent(this._renderer.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas));
87
- this.register(forwardEvent(this._renderer.onRemoveTextureAtlasCanvas, this._onRemoveTextureAtlasCanvas));
84
+ this._register(Event.forward(this._renderer.onContextLoss, this._onContextLoss));
85
+ this._register(Event.forward(this._renderer.onChangeTextureAtlas, this._onChangeTextureAtlas));
86
+ this._register(Event.forward(this._renderer.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas));
87
+ this._register(Event.forward(this._renderer.onRemoveTextureAtlasCanvas, this._onRemoveTextureAtlasCanvas));
88
88
  renderService.setRenderer(this._renderer);
89
89
 
90
- this.register(toDisposable(() => {
90
+ this._register(toDisposable(() => {
91
+ if ((this._terminal as any)._core._store._isDisposed) {
92
+ return;
93
+ }
91
94
  const renderService: IRenderService = (this._terminal as any)._core._renderService;
92
95
  renderService.setRenderer((this._terminal as any)._core._createRenderer());
93
96
  renderService.handleResize(terminal.cols, terminal.rows);
@@ -3,7 +3,6 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { addDisposableDomListener } from 'browser/Lifecycle';
7
6
  import { ITerminal } from 'browser/Types';
8
7
  import { CellColorResolver } from 'browser/renderer/shared/CellColorResolver';
9
8
  import { acquireTextureAtlas, removeTerminalFromCache } from 'browser/renderer/shared/CharAtlasCache';
@@ -12,8 +11,6 @@ import { observeDevicePixelDimensions } from 'browser/renderer/shared/DevicePixe
12
11
  import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
13
12
  import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ITextureAtlas } from 'browser/renderer/shared/Types';
14
13
  import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
15
- import { EventEmitter, forwardEvent } from 'common/EventEmitter';
16
- import { Disposable, MutableDisposable, getDisposeArrayDisposable, toDisposable } from 'common/Lifecycle';
17
14
  import { CharData, IBufferLine, ICellData } from 'common/Types';
18
15
  import { AttributeData } from 'common/buffer/AttributeData';
19
16
  import { CellData } from 'common/buffer/CellData';
@@ -26,14 +23,17 @@ import { COMBINED_CHAR_BIT_MASK, RENDER_MODEL_BG_OFFSET, RENDER_MODEL_EXT_OFFSET
26
23
  import { IWebGL2RenderingContext } from './Types';
27
24
  import { LinkRenderLayer } from './renderLayer/LinkRenderLayer';
28
25
  import { IRenderLayer } from './renderLayer/Types';
26
+ import { Emitter, Event } from 'vs/base/common/event';
27
+ import { addDisposableListener } from 'vs/base/browser/dom';
28
+ import { combinedDisposable, Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
29
29
 
30
30
  export class WebglRenderer extends Disposable implements IRenderer {
31
31
  private _renderLayers: IRenderLayer[];
32
32
  private _cursorBlinkStateManager: MutableDisposable<CursorBlinkStateManager> = new MutableDisposable();
33
- private _charAtlasDisposable = this.register(new MutableDisposable());
33
+ private _charAtlasDisposable = this._register(new MutableDisposable());
34
34
  private _charAtlas: ITextureAtlas | undefined;
35
35
  private _devicePixelRatio: number;
36
- private _observerDisposable = this.register(new MutableDisposable());
36
+ private _observerDisposable = this._register(new MutableDisposable());
37
37
 
38
38
  private _model: RenderModel = new RenderModel();
39
39
  private _workCell: ICellData = new CellData();
@@ -42,8 +42,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
42
42
 
43
43
  private _canvas: HTMLCanvasElement;
44
44
  private _gl: IWebGL2RenderingContext;
45
- private _rectangleRenderer: MutableDisposable<RectangleRenderer> = this.register(new MutableDisposable());
46
- private _glyphRenderer: MutableDisposable<GlyphRenderer> = this.register(new MutableDisposable());
45
+ private _rectangleRenderer: MutableDisposable<RectangleRenderer> = this._register(new MutableDisposable());
46
+ private _glyphRenderer: MutableDisposable<GlyphRenderer> = this._register(new MutableDisposable());
47
47
 
48
48
  public readonly dimensions: IRenderDimensions;
49
49
 
@@ -51,15 +51,15 @@ export class WebglRenderer extends Disposable implements IRenderer {
51
51
  private _isAttached: boolean;
52
52
  private _contextRestorationTimeout: number | undefined;
53
53
 
54
- private readonly _onChangeTextureAtlas = this.register(new EventEmitter<HTMLCanvasElement>());
54
+ private readonly _onChangeTextureAtlas = this._register(new Emitter<HTMLCanvasElement>());
55
55
  public readonly onChangeTextureAtlas = this._onChangeTextureAtlas.event;
56
- private readonly _onAddTextureAtlasCanvas = this.register(new EventEmitter<HTMLCanvasElement>());
56
+ private readonly _onAddTextureAtlasCanvas = this._register(new Emitter<HTMLCanvasElement>());
57
57
  public readonly onAddTextureAtlasCanvas = this._onAddTextureAtlasCanvas.event;
58
- private readonly _onRemoveTextureAtlasCanvas = this.register(new EventEmitter<HTMLCanvasElement>());
58
+ private readonly _onRemoveTextureAtlasCanvas = this._register(new Emitter<HTMLCanvasElement>());
59
59
  public readonly onRemoveTextureAtlasCanvas = this._onRemoveTextureAtlasCanvas.event;
60
- private readonly _onRequestRedraw = this.register(new EventEmitter<IRequestRedrawEvent>());
60
+ private readonly _onRequestRedraw = this._register(new Emitter<IRequestRedrawEvent>());
61
61
  public readonly onRequestRedraw = this._onRequestRedraw.event;
62
- private readonly _onContextLoss = this.register(new EventEmitter<void>());
62
+ private readonly _onContextLoss = this._register(new Emitter<void>());
63
63
  public readonly onContextLoss = this._onContextLoss.event;
64
64
 
65
65
  constructor(
@@ -75,7 +75,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
75
75
  ) {
76
76
  super();
77
77
 
78
- this.register(this._themeService.onChangeColors(() => this._handleColorChange()));
78
+ this._register(this._themeService.onChangeColors(() => this._handleColorChange()));
79
79
 
80
80
  this._cellColorResolver = new CellColorResolver(this._terminal, this._optionsService, this._model.selection, this._decorationService, this._coreBrowserService, this._themeService);
81
81
 
@@ -88,7 +88,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
88
88
  this._devicePixelRatio = this._coreBrowserService.dpr;
89
89
  this._updateDimensions();
90
90
  this._updateCursorBlink();
91
- this.register(_optionsService.onOptionChange(() => this._handleOptionsChanged()));
91
+ this._register(_optionsService.onOptionChange(() => this._handleOptionsChanged()));
92
92
 
93
93
  this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');
94
94
 
@@ -102,7 +102,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
102
102
  throw new Error('WebGL2 not supported ' + this._gl);
103
103
  }
104
104
 
105
- this.register(addDisposableDomListener(this._canvas, 'webglcontextlost', (e) => {
105
+ this._register(addDisposableListener(this._canvas, 'webglcontextlost', (e) => {
106
106
  console.log('webglcontextlost event received');
107
107
  // Prevent the default behavior in order to enable WebGL context restoration.
108
108
  e.preventDefault();
@@ -114,7 +114,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
114
114
  this._onContextLoss.fire(e);
115
115
  }, 3000 /* ms */);
116
116
  }));
117
- this.register(addDisposableDomListener(this._canvas, 'webglcontextrestored', (e) => {
117
+ this._register(addDisposableListener(this._canvas, 'webglcontextrestored', (e) => {
118
118
  console.warn('webglcontextrestored event received');
119
119
  clearTimeout(this._contextRestorationTimeout);
120
120
  this._contextRestorationTimeout = undefined;
@@ -126,7 +126,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
126
126
  }));
127
127
 
128
128
  this._observerDisposable.value = observeDevicePixelDimensions(this._canvas, this._coreBrowserService.window, (w, h) => this._setCanvasDevicePixelDimensions(w, h));
129
- this.register(this._coreBrowserService.onWindowChange(w => {
129
+ this._register(this._coreBrowserService.onWindowChange(w => {
130
130
  this._observerDisposable.value = observeDevicePixelDimensions(this._canvas, w, (w, h) => this._setCanvasDevicePixelDimensions(w, h));
131
131
  }));
132
132
 
@@ -136,7 +136,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
136
136
 
137
137
  this._isAttached = this._coreBrowserService.window.document.body.contains(this._core.screenElement!);
138
138
 
139
- this.register(toDisposable(() => {
139
+ this._register(toDisposable(() => {
140
140
  for (const l of this._renderLayers) {
141
141
  l.dispose();
142
142
  }
@@ -276,10 +276,10 @@ export class WebglRenderer extends Disposable implements IRenderer {
276
276
  );
277
277
  if (this._charAtlas !== atlas) {
278
278
  this._onChangeTextureAtlas.fire(atlas.pages[0].canvas);
279
- this._charAtlasDisposable.value = getDisposeArrayDisposable([
280
- forwardEvent(atlas.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas),
281
- forwardEvent(atlas.onRemoveTextureAtlasCanvas, this._onRemoveTextureAtlasCanvas)
282
- ]);
279
+ this._charAtlasDisposable.value = combinedDisposable(
280
+ Event.forward(atlas.onAddTextureAtlasCanvas, this._onAddTextureAtlasCanvas),
281
+ Event.forward(atlas.onRemoveTextureAtlasCanvas, this._onRemoveTextureAtlasCanvas)
282
+ );
283
283
  }
284
284
  this._charAtlas = atlas;
285
285
  this._charAtlas.warmUp();
@@ -314,14 +314,6 @@ export class WebglRenderer extends Disposable implements IRenderer {
314
314
  this._updateCursorBlink();
315
315
  }
316
316
 
317
- public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {
318
- return -1;
319
- }
320
-
321
- public deregisterCharacterJoiner(joinerId: number): boolean {
322
- return false;
323
- }
324
-
325
317
  public renderRows(start: number, end: number): void {
326
318
  if (!this._isAttached) {
327
319
  if (this._coreBrowserService.window.document.body.contains(this._core.screenElement!) && this._charSizeService.width && this._charSizeService.height) {
@@ -362,7 +354,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
362
354
  }
363
355
 
364
356
  private _updateCursorBlink(): void {
365
- if (this._terminal.options.cursorBlink) {
357
+ if (this._coreService.decPrivateModes.cursorBlink ?? this._terminal.options.cursorBlink) {
366
358
  this._cursorBlinkStateManager.value = new CursorBlinkStateManager(() => {
367
359
  this._requestRedrawCursor();
368
360
  }, this._coreBrowserService);
@@ -385,8 +377,11 @@ export class WebglRenderer extends Disposable implements IRenderer {
385
377
  let line: IBufferLine;
386
378
  let joinedRanges: [number, number][];
387
379
  let isJoined: boolean;
380
+ let skipJoinedCheckUntilX: number = 0;
381
+ let isValidJoinRange: boolean = true;
388
382
  let lastCharX: number;
389
383
  let range: [number, number];
384
+ let isCursorRow: boolean;
390
385
  let chars: string;
391
386
  let code: number;
392
387
  let width: number;
@@ -395,6 +390,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
395
390
  let j: number;
396
391
  start = clamp(start, terminal.rows - 1, 0);
397
392
  end = clamp(end, terminal.rows - 1, 0);
393
+ const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? terminal.options.cursorStyle ?? 'block';
398
394
 
399
395
  const cursorY = this._terminal.buffer.active.baseY + this._terminal.buffer.active.cursorY;
400
396
  const viewportRelativeCursorY = cursorY - terminal.buffer.ydisp;
@@ -412,6 +408,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
412
408
  row = y + terminal.buffer.ydisp;
413
409
  line = terminal.buffer.lines.get(row)!;
414
410
  this._model.lineLengths[y] = 0;
411
+ isCursorRow = cursorY === row;
412
+ skipJoinedCheckUntilX = 0;
415
413
  joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
416
414
  for (x = 0; x < terminal.cols; x++) {
417
415
  lastBg = this._cellColorResolver.result.bg;
@@ -423,25 +421,43 @@ export class WebglRenderer extends Disposable implements IRenderer {
423
421
 
424
422
  // If true, indicates that the current character(s) to draw were joined.
425
423
  isJoined = false;
424
+
425
+ // Indicates whether this cell is part of a joined range that should be ignored as it cannot
426
+ // be rendered entirely, like the selection state differs across the range.
427
+ isValidJoinRange = (x >= skipJoinedCheckUntilX);
428
+
426
429
  lastCharX = x;
427
430
 
428
431
  // Process any joined character ranges as needed. Because of how the
429
432
  // ranges are produced, we know that they are valid for the characters
430
433
  // and attributes of our input.
431
- if (joinedRanges.length > 0 && x === joinedRanges[0][0]) {
432
- isJoined = true;
434
+ if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {
433
435
  range = joinedRanges.shift()!;
434
436
 
435
- // We already know the exact start and end column of the joined range,
436
- // so we get the string and width representing it directly.
437
- cell = new JoinedCellData(
438
- cell,
439
- line!.translateToString(true, range[0], range[1]),
440
- range[1] - range[0]
441
- );
442
-
443
- // Skip over the cells occupied by this range in the loop
444
- lastCharX = range[1] - 1;
437
+ // If the ligature's selection state is not consistent, don't join it. This helps the
438
+ // selection render correctly regardless whether they should be joined.
439
+ const firstSelectionState = this._model.selection.isCellSelected(this._terminal, range[0], row);
440
+ for (i = range[0] + 1; i < range[1]; i++) {
441
+ isValidJoinRange &&= (firstSelectionState === this._model.selection.isCellSelected(this._terminal, i, row));
442
+ }
443
+ // Similarly, if the cursor is in the ligature, don't join it.
444
+ isValidJoinRange &&= !isCursorRow || cursorX < range[0] || cursorX >= range[1];
445
+ if (!isValidJoinRange) {
446
+ skipJoinedCheckUntilX = range[1];
447
+ } else {
448
+ isJoined = true;
449
+
450
+ // We already know the exact start and end column of the joined range,
451
+ // so we get the string and width representing it directly.
452
+ cell = new JoinedCellData(
453
+ cell,
454
+ line!.translateToString(true, range[0], range[1]),
455
+ range[1] - range[0]
456
+ );
457
+
458
+ // Skip over the cells occupied by this range in the loop
459
+ lastCharX = range[1] - 1;
460
+ }
445
461
  }
446
462
 
447
463
  chars = cell.getChars();
@@ -458,8 +474,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
458
474
  x: cursorX,
459
475
  y: viewportRelativeCursorY,
460
476
  width: cell.getWidth(),
461
- style: this._coreBrowserService.isFocused ?
462
- (terminal.options.cursorStyle || 'block') : terminal.options.cursorInactiveStyle,
477
+ style: this._coreBrowserService.isFocused ? cursorStyle : terminal.options.cursorInactiveStyle,
463
478
  cursorWidth: terminal.options.cursorWidth,
464
479
  dpr: this._devicePixelRatio
465
480
  };
@@ -467,9 +482,10 @@ export class WebglRenderer extends Disposable implements IRenderer {
467
482
  }
468
483
  if (x >= cursorX && x <= lastCursorX &&
469
484
  ((this._coreBrowserService.isFocused &&
470
- (terminal.options.cursorStyle || 'block') === 'block') ||
485
+ cursorStyle === 'block') ||
471
486
  (this._coreBrowserService.isFocused === false &&
472
- terminal.options.cursorInactiveStyle === 'block'))) {
487
+ terminal.options.cursorInactiveStyle === 'block'))
488
+ ) {
473
489
  this._cellColorResolver.result.fg =
474
490
  Attributes.CM_RGB | (this._themeService.colors.cursorAccent.rgba >> 8 & Attributes.RGB_MASK);
475
491
  this._cellColorResolver.result.bg =
@@ -510,14 +526,17 @@ export class WebglRenderer extends Disposable implements IRenderer {
510
526
  cell = this._workCell;
511
527
 
512
528
  // Null out non-first cells
513
- for (x++; x < lastCharX; x++) {
529
+ for (x++; x <= lastCharX; x++) {
514
530
  j = ((y * terminal.cols) + x) * RENDER_MODEL_INDICIES_PER_CELL;
515
531
  this._glyphRenderer.value!.updateCell(x, y, NULL_CELL_CODE, 0, 0, 0, NULL_CELL_CHAR, 0, 0);
516
532
  this._model.cells[j] = NULL_CELL_CODE;
533
+ // Don't re-resolve the cell color since multi-colored ligature backgrounds are not
534
+ // supported
517
535
  this._model.cells[j + RENDER_MODEL_BG_OFFSET] = this._cellColorResolver.result.bg;
518
536
  this._model.cells[j + RENDER_MODEL_FG_OFFSET] = this._cellColorResolver.result.fg;
519
537
  this._model.cells[j + RENDER_MODEL_EXT_OFFSET] = this._cellColorResolver.result.ext;
520
538
  }
539
+ x--; // Go back to the previous update cell for next iteration
521
540
  }
522
541
  }
523
542
  }
@@ -9,7 +9,7 @@ import { TEXT_BASELINE } from 'browser/renderer/shared/Constants';
9
9
  import { throwIfFalsy } from 'browser/renderer/shared/RendererUtils';
10
10
  import { IRenderDimensions, ITextureAtlas } from 'browser/renderer/shared/Types';
11
11
  import { ICoreBrowserService, IThemeService } from 'browser/services/Services';
12
- import { Disposable, toDisposable } from 'common/Lifecycle';
12
+ import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
13
13
  import { CellData } from 'common/buffer/CellData';
14
14
  import { IOptionsService } from 'common/services/Services';
15
15
  import { Terminal } from '@xterm/xterm';
@@ -43,11 +43,11 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
43
43
  this._canvas.style.zIndex = zIndex.toString();
44
44
  this._initCanvas();
45
45
  this._container.appendChild(this._canvas);
46
- this.register(this._themeService.onChangeColors(e => {
46
+ this._register(this._themeService.onChangeColors(e => {
47
47
  this._refreshCharAtlas(terminal, e);
48
48
  this.reset(terminal);
49
49
  }));
50
- this.register(toDisposable(() => {
50
+ this._register(toDisposable(() => {
51
51
  this._canvas.remove();
52
52
  }));
53
53
  }
@@ -26,8 +26,8 @@ export class LinkRenderLayer extends BaseRenderLayer {
26
26
  ) {
27
27
  super(terminal, container, 'link', zIndex, true, coreBrowserService, optionsService, themeService);
28
28
 
29
- this.register(linkifier2.onShowLinkUnderline(e => this._handleShowLinkUnderline(e)));
30
- this.register(linkifier2.onHideLinkUnderline(e => this._handleHideLinkUnderline(e)));
29
+ this._register(linkifier2.onShowLinkUnderline(e => this._handleShowLinkUnderline(e)));
30
+ this._register(linkifier2.onHideLinkUnderline(e => this._handleHideLinkUnderline(e)));
31
31
  }
32
32
 
33
33
  public resize(terminal: Terminal, dim: IRenderDimensions): void {
@@ -7,7 +7,7 @@ import { Terminal, ITerminalAddon, IEvent } from '@xterm/xterm';
7
7
 
8
8
  declare module '@xterm/addon-webgl' {
9
9
  /**
10
- * An xterm.js addon that provides search functionality.
10
+ * An xterm.js addon that provides hardware-accelerated rendering functionality via WebGL.
11
11
  */
12
12
  export class WebglAddon implements ITerminalAddon {
13
13
  public textureAtlas?: HTMLCanvasElement;
@@ -27,6 +27,11 @@ declare module '@xterm/addon-webgl' {
27
27
  */
28
28
  public readonly onAddTextureAtlasCanvas: IEvent<HTMLCanvasElement>;
29
29
 
30
+ /**
31
+ * An event that is fired when the a page is removed from the texture atlas.
32
+ */
33
+ public readonly onRemoveTextureAtlasCanvas: IEvent<HTMLCanvasElement>;
34
+
30
35
  constructor(preserveDrawingBuffer?: boolean);
31
36
 
32
37
  /**
File without changes