From 9df996cb3db67f89392a54206237dcc565579f15 Mon Sep 17 00:00:00 2001 From: Svante Boberg Date: Sat, 23 Jul 2022 13:21:13 +0200 Subject: [PATCH 1/4] Dispose events https://github.com/microsoft/vscode/issues/155232 The events that is setup for needs to be disposed for js to be able to garbage collect the terminals. --- src/browser/Linkifier.ts | 6 ++++++ src/browser/Linkifier2.ts | 7 +++++++ src/browser/Terminal.ts | 4 ++++ src/browser/Types.d.ts | 2 ++ 4 files changed, 19 insertions(+) diff --git a/src/browser/Linkifier.ts b/src/browser/Linkifier.ts index b17d66a8..25f07104 100644 --- a/src/browser/Linkifier.ts +++ b/src/browser/Linkifier.ts @@ -53,6 +53,12 @@ export class Linkifier implements ILinkifier { }; } + public dispose(): void { + this._onShowLinkUnderline.dispose(); + this._onHideLinkUnderline.dispose(); + this._onLinkTooltip.dispose(); + } + /** * Attaches the linkifier to the DOM, enabling linkification. * @param mouseZoneManager The mouse zone manager to register link zones with. diff --git a/src/browser/Linkifier2.ts b/src/browser/Linkifier2.ts index dae9acfa..8d7cbee6 100644 --- a/src/browser/Linkifier2.ts +++ b/src/browser/Linkifier2.ts @@ -38,6 +38,13 @@ export class Linkifier2 extends Disposable implements ILinkifier2 { this.register(getDisposeArrayDisposable(this._linkCacheDisposables)); } + public dispose(): void { + super.dispose(); + this._onShowLinkUnderline.dispose(); + this._onHideLinkUnderline.dispose(); + this._lastMouseEvent = undefined; + } + public registerLinkProvider(linkProvider: ILinkProvider): IDisposable { this._linkProviders.push(linkProvider); return { diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index bd82325d..732c7d49 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -247,8 +247,12 @@ export class Terminal extends CoreTerminal implements ITerminal { super.dispose(); this._renderService?.dispose(); this._customKeyEventHandler = undefined; + this._overviewRulerRenderer?.dispose(); + this._overviewRulerRenderer = undefined; this.write = () => { }; this.element?.parentNode?.removeChild(this.element); + this.linkifier.dispose(); + this.linkifier2.dispose(); } protected _setup(): void { diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index 41992a8b..8408b331 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -201,6 +201,7 @@ export interface ILinkifier { linkifyRows(start: number, end: number): void; registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number; deregisterLinkMatcher(matcherId: number): boolean; + dispose(): void; } interface ILinkState { @@ -219,6 +220,7 @@ export interface ILinkifier2 { attachToDom(element: HTMLElement, mouseService: IMouseService, renderService: IRenderService): void; registerLinkProvider(linkProvider: ILinkProvider): IDisposable; + dispose(): void; } export interface ILinkMatcherOptions { From c895f67fd8d21861f49be1df198437935b8c2831 Mon Sep 17 00:00:00 2001 From: Svante Boberg Date: Wed, 27 Jul 2022 00:00:41 +0200 Subject: [PATCH 2/4] Add missing webgl cursor blink disposal Same disposal code as the non-webgl cursor blink layer --- .../src/renderLayer/CursorRenderLayer.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts index c80b4c56..f7dcef28 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts @@ -54,6 +54,14 @@ export class CursorRenderLayer extends BaseRenderLayer { this.onOptionsChanged(terminal); } + public override dispose(): void { + if (this._cursorBlinkStateManager) { + this._cursorBlinkStateManager.dispose(); + this._cursorBlinkStateManager = undefined; + } + super.dispose(); + } + public resize(terminal: Terminal, dim: IRenderDimensions): void { super.resize(terminal, dim); // Resizing the canvas discards the contents of the canvas so clear state From 078b83fcaf9abbf309ef17515d1f12eb59deddc2 Mon Sep 17 00:00:00 2001 From: Svante Boberg Date: Wed, 27 Jul 2022 14:24:42 +0200 Subject: [PATCH 3/4] Use disposal registration --- .../src/renderLayer/CursorRenderLayer.ts | 6 ++---- src/browser/Linkifier.ts | 16 ++++++---------- src/browser/Terminal.ts | 10 +++------- src/browser/Types.d.ts | 6 ++---- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts b/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts index f7dcef28..fd686cc7 100644 --- a/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts +++ b/addons/xterm-addon-webgl/src/renderLayer/CursorRenderLayer.ts @@ -55,10 +55,8 @@ export class CursorRenderLayer extends BaseRenderLayer { } public override dispose(): void { - if (this._cursorBlinkStateManager) { - this._cursorBlinkStateManager.dispose(); - this._cursorBlinkStateManager = undefined; - } + this._cursorBlinkStateManager?.dispose(); + this._cursorBlinkStateManager = undefined; super.dispose(); } diff --git a/src/browser/Linkifier.ts b/src/browser/Linkifier.ts index 25f07104..b9e3c4ca 100644 --- a/src/browser/Linkifier.ts +++ b/src/browser/Linkifier.ts @@ -6,6 +6,7 @@ import { ILinkifierEvent, ILinkMatcher, LinkMatcherHandler, ILinkMatcherOptions, ILinkifier, IMouseZoneManager, IMouseZone, IRegisteredLinkMatcher } from 'browser/Types'; import { IBufferStringIteratorResult } from 'common/buffer/Types'; import { EventEmitter, IEvent } from 'common/EventEmitter'; +import { Disposable } from 'common/Lifecycle'; import { ILogService, IBufferService, IOptionsService, IUnicodeService } from 'common/services/Services'; /** @@ -18,7 +19,7 @@ const OVERSCAN_CHAR_LIMIT = 2000; /** * The Linkifier applies links to rows shortly after they have been refreshed. */ -export class Linkifier implements ILinkifier { +export class Linkifier extends Disposable implements ILinkifier { /** * The time to wait after a row is changed before it is linkified. This prevents * the costly operation of searching every row multiple times, potentially a @@ -35,11 +36,11 @@ export class Linkifier implements ILinkifier { private _nextLinkMatcherId = 0; private _rowsToLinkify: { start: number | undefined, end: number | undefined }; - private _onShowLinkUnderline = new EventEmitter(); + private _onShowLinkUnderline = this.register(new EventEmitter()); public get onShowLinkUnderline(): IEvent { return this._onShowLinkUnderline.event; } - private _onHideLinkUnderline = new EventEmitter(); + private _onHideLinkUnderline = this.register(new EventEmitter()); public get onHideLinkUnderline(): IEvent { return this._onHideLinkUnderline.event; } - private _onLinkTooltip = new EventEmitter(); + private _onLinkTooltip = this.register(new EventEmitter()); public get onLinkTooltip(): IEvent { return this._onLinkTooltip.event; } constructor( @@ -47,18 +48,13 @@ export class Linkifier implements ILinkifier { @ILogService private readonly _logService: ILogService, @IUnicodeService private readonly _unicodeService: IUnicodeService ) { + super(); this._rowsToLinkify = { start: undefined, end: undefined }; } - public dispose(): void { - this._onShowLinkUnderline.dispose(); - this._onHideLinkUnderline.dispose(); - this._onLinkTooltip.dispose(); - } - /** * Attaches the linkifier to the DOM, enabling linkification. * @param mouseZoneManager The mouse zone manager to register link zones with. diff --git a/src/browser/Terminal.ts b/src/browser/Terminal.ts index 732c7d49..8f881177 100644 --- a/src/browser/Terminal.ts +++ b/src/browser/Terminal.ts @@ -168,7 +168,7 @@ export class Terminal extends CoreTerminal implements ITerminal { this._setup(); - this.linkifier = this._instantiationService.createInstance(Linkifier); + this.linkifier = this.register(this._instantiationService.createInstance(Linkifier)); this.linkifier2 = this.register(this._instantiationService.createInstance(Linkifier2)); this._decorationService = this._instantiationService.createInstance(DecorationService); this._instantiationService.setService(IDecorationService, this._decorationService); @@ -247,12 +247,8 @@ export class Terminal extends CoreTerminal implements ITerminal { super.dispose(); this._renderService?.dispose(); this._customKeyEventHandler = undefined; - this._overviewRulerRenderer?.dispose(); - this._overviewRulerRenderer = undefined; this.write = () => { }; this.element?.parentNode?.removeChild(this.element); - this.linkifier.dispose(); - this.linkifier2.dispose(); } protected _setup(): void { @@ -612,11 +608,11 @@ export class Terminal extends CoreTerminal implements ITerminal { } if (this.options.overviewRulerWidth) { - this._overviewRulerRenderer = this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement); + this._overviewRulerRenderer = this.register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement)); } this.optionsService.onOptionChange(() => { if (!this._overviewRulerRenderer && this.options.overviewRulerWidth && this._viewportElement && this.screenElement) { - this._overviewRulerRenderer = this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement); + this._overviewRulerRenderer = this.register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement)); } }); // Measure the character size diff --git a/src/browser/Types.d.ts b/src/browser/Types.d.ts index 8408b331..db19e0e0 100644 --- a/src/browser/Types.d.ts +++ b/src/browser/Types.d.ts @@ -192,7 +192,7 @@ export interface ILinkifierEvent { fg: number | undefined; } -export interface ILinkifier { +export interface ILinkifier extends IDisposable { onShowLinkUnderline: IEvent; onHideLinkUnderline: IEvent; onLinkTooltip: IEvent; @@ -201,7 +201,6 @@ export interface ILinkifier { linkifyRows(start: number, end: number): void; registerLinkMatcher(regex: RegExp, handler: LinkMatcherHandler, options?: ILinkMatcherOptions): number; deregisterLinkMatcher(matcherId: number): boolean; - dispose(): void; } interface ILinkState { @@ -213,14 +212,13 @@ export interface ILinkWithState { state?: ILinkState; } -export interface ILinkifier2 { +export interface ILinkifier2 extends IDisposable { onShowLinkUnderline: IEvent; onHideLinkUnderline: IEvent; readonly currentLink: ILinkWithState | undefined; attachToDom(element: HTMLElement, mouseService: IMouseService, renderService: IRenderService): void; registerLinkProvider(linkProvider: ILinkProvider): IDisposable; - dispose(): void; } export interface ILinkMatcherOptions { From 52dc6a456c692b0fd23538a81750927b1be653f5 Mon Sep 17 00:00:00 2001 From: Svante Boberg Date: Wed, 27 Jul 2022 14:34:00 +0200 Subject: [PATCH 4/4] Remove redundant disposal --- src/browser/Linkifier2.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/browser/Linkifier2.ts b/src/browser/Linkifier2.ts index 8d7cbee6..9c978949 100644 --- a/src/browser/Linkifier2.ts +++ b/src/browser/Linkifier2.ts @@ -40,8 +40,6 @@ export class Linkifier2 extends Disposable implements ILinkifier2 { public dispose(): void { super.dispose(); - this._onShowLinkUnderline.dispose(); - this._onHideLinkUnderline.dispose(); this._lastMouseEvent = undefined; }