@xterm/xterm 5.6.0-beta.50 → 5.6.0-beta.51
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/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +16 -16
- package/lib/xterm.mjs.map +4 -4
- package/package.json +1 -1
- package/src/browser/AccessibilityManager.ts +15 -15
- package/src/browser/CoreBrowserTerminal.ts +68 -68
- package/src/browser/Linkifier.ts +14 -12
- package/src/browser/Viewport.ts +14 -14
- package/src/browser/decorations/BufferDecorationRenderer.ts +8 -8
- package/src/browser/decorations/OverviewRulerRenderer.ts +11 -11
- package/src/browser/public/Terminal.ts +4 -4
- package/src/browser/renderer/dom/DomRenderer.ts +7 -7
- package/src/browser/renderer/shared/DevicePixelObserver.ts +1 -2
- package/src/browser/services/CharSizeService.ts +5 -5
- package/src/browser/services/CoreBrowserService.ts +15 -19
- package/src/browser/services/LinkProviderService.ts +2 -2
- package/src/browser/services/RenderService.ts +19 -19
- package/src/browser/services/SelectionService.ts +7 -7
- package/src/browser/services/ThemeService.ts +4 -4
- package/src/common/CircularList.ts +4 -4
- package/src/common/CoreTerminal.ts +27 -27
- package/src/common/InputHandler.ts +16 -16
- package/src/common/buffer/BufferSet.ts +4 -4
- package/src/common/buffer/Marker.ts +2 -2
- package/src/common/input/WriteBuffer.ts +2 -2
- package/src/common/parser/EscapeSequenceParser.ts +4 -4
- package/src/common/public/BufferNamespaceApi.ts +2 -2
- package/src/common/services/BufferService.ts +4 -4
- package/src/common/services/CoreMouseService.ts +2 -2
- package/src/common/services/CoreService.ts +5 -5
- package/src/common/services/DecorationService.ts +7 -8
- package/src/common/services/LogService.ts +2 -2
- package/src/common/services/OptionsService.ts +3 -3
- package/src/browser/Lifecycle.ts +0 -33
- package/src/common/Lifecycle.ts +0 -108
package/package.json
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
import * as Strings from 'browser/LocalizableStrings';
|
|
7
7
|
import { ITerminal, IRenderDebouncer } from 'browser/Types';
|
|
8
8
|
import { TimeBasedDebouncer } from 'browser/TimeBasedDebouncer';
|
|
9
|
-
import { Disposable, toDisposable } from 'common/
|
|
9
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
10
10
|
import { ICoreBrowserService, IRenderService } from 'browser/services/Services';
|
|
11
11
|
import { IBuffer } from 'common/buffer/Types';
|
|
12
12
|
import { IInstantiationService } from 'common/services/Services';
|
|
13
|
-
import {
|
|
13
|
+
import { addDisposableListener } from 'vs/base/browser/dom';
|
|
14
14
|
|
|
15
15
|
const MAX_ROWS_TO_READ = 20;
|
|
16
16
|
|
|
@@ -82,7 +82,7 @@ export class AccessibilityManager extends Disposable {
|
|
|
82
82
|
this._liveRegion.classList.add('live-region');
|
|
83
83
|
this._liveRegion.setAttribute('aria-live', 'assertive');
|
|
84
84
|
this._accessibilityContainer.appendChild(this._liveRegion);
|
|
85
|
-
this._liveRegionDebouncer = this.
|
|
85
|
+
this._liveRegionDebouncer = this._register(new TimeBasedDebouncer(this._renderRows.bind(this)));
|
|
86
86
|
|
|
87
87
|
if (!this._terminal.element) {
|
|
88
88
|
throw new Error('Cannot enable accessibility before Terminal.open');
|
|
@@ -105,22 +105,22 @@ export class AccessibilityManager extends Disposable {
|
|
|
105
105
|
this._terminal.element.insertAdjacentElement('afterbegin', this._accessibilityContainer);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
this.
|
|
109
|
-
this.
|
|
110
|
-
this.
|
|
108
|
+
this._register(this._terminal.onResize(e => this._handleResize(e.rows)));
|
|
109
|
+
this._register(this._terminal.onRender(e => this._refreshRows(e.start, e.end)));
|
|
110
|
+
this._register(this._terminal.onScroll(() => this._refreshRows()));
|
|
111
111
|
// Line feed is an issue as the prompt won't be read out after a command is run
|
|
112
|
-
this.
|
|
113
|
-
this.
|
|
114
|
-
this.
|
|
115
|
-
this.
|
|
116
|
-
this.
|
|
117
|
-
this.
|
|
118
|
-
this.
|
|
119
|
-
this.
|
|
112
|
+
this._register(this._terminal.onA11yChar(char => this._handleChar(char)));
|
|
113
|
+
this._register(this._terminal.onLineFeed(() => this._handleChar('\n')));
|
|
114
|
+
this._register(this._terminal.onA11yTab(spaceCount => this._handleTab(spaceCount)));
|
|
115
|
+
this._register(this._terminal.onKey(e => this._handleKey(e.key)));
|
|
116
|
+
this._register(this._terminal.onBlur(() => this._clearLiveRegion()));
|
|
117
|
+
this._register(this._renderService.onDimensionsChange(() => this._refreshRowsDimensions()));
|
|
118
|
+
this._register(addDisposableListener(doc, 'selectionchange', () => this._handleSelectionChange()));
|
|
119
|
+
this._register(this._coreBrowserService.onDprChange(() => this._refreshRowsDimensions()));
|
|
120
120
|
|
|
121
121
|
this._refreshRowsDimensions();
|
|
122
122
|
this._refreshRows();
|
|
123
|
-
this.
|
|
123
|
+
this._register(toDisposable(() => {
|
|
124
124
|
if (DEBUG) {
|
|
125
125
|
this._debugRootContainer!.remove();
|
|
126
126
|
} else {
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
|
|
24
24
|
import { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker } from '@xterm/xterm';
|
|
25
25
|
import { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from 'browser/Clipboard';
|
|
26
|
-
import { addDisposableDomListener } from 'browser/Lifecycle';
|
|
27
26
|
import * as Strings from 'browser/LocalizableStrings';
|
|
28
27
|
import { OscLinkProvider } from 'browser/OscLinkProvider';
|
|
29
28
|
import { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal } from 'browser/Types';
|
|
@@ -44,7 +43,6 @@ import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, ILinkPr
|
|
|
44
43
|
import { ThemeService } from 'browser/services/ThemeService';
|
|
45
44
|
import { channels, color } from 'common/Color';
|
|
46
45
|
import { CoreTerminal } from 'common/CoreTerminal';
|
|
47
|
-
import { MutableDisposable, toDisposable } from 'common/Lifecycle';
|
|
48
46
|
import * as Browser from 'common/Platform';
|
|
49
47
|
import { ColorRequestType, CoreMouseAction, CoreMouseButton, CoreMouseEventType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from 'common/Types';
|
|
50
48
|
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
|
|
@@ -58,6 +56,8 @@ import { WindowsOptionsReportType } from '../common/InputHandler';
|
|
|
58
56
|
import { AccessibilityManager } from './AccessibilityManager';
|
|
59
57
|
import { Linkifier } from './Linkifier';
|
|
60
58
|
import { Emitter, Event } from 'vs/base/common/event';
|
|
59
|
+
import { addDisposableListener } from 'vs/base/browser/dom';
|
|
60
|
+
import { MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
61
61
|
|
|
62
62
|
export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
63
63
|
public textarea: HTMLTextAreaElement | undefined;
|
|
@@ -119,30 +119,30 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
119
119
|
private _unprocessedDeadKey: boolean = false;
|
|
120
120
|
|
|
121
121
|
private _compositionHelper: ICompositionHelper | undefined;
|
|
122
|
-
private _accessibilityManager: MutableDisposable<AccessibilityManager> = this.
|
|
122
|
+
private _accessibilityManager: MutableDisposable<AccessibilityManager> = this._register(new MutableDisposable());
|
|
123
123
|
|
|
124
|
-
private readonly _onCursorMove = this.
|
|
124
|
+
private readonly _onCursorMove = this._register(new Emitter<void>());
|
|
125
125
|
public readonly onCursorMove = this._onCursorMove.event;
|
|
126
|
-
private readonly _onKey = this.
|
|
126
|
+
private readonly _onKey = this._register(new Emitter<{ key: string, domEvent: KeyboardEvent }>());
|
|
127
127
|
public readonly onKey = this._onKey.event;
|
|
128
|
-
private readonly _onRender = this.
|
|
128
|
+
private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());
|
|
129
129
|
public readonly onRender = this._onRender.event;
|
|
130
|
-
private readonly _onSelectionChange = this.
|
|
130
|
+
private readonly _onSelectionChange = this._register(new Emitter<void>());
|
|
131
131
|
public readonly onSelectionChange = this._onSelectionChange.event;
|
|
132
|
-
private readonly _onTitleChange = this.
|
|
132
|
+
private readonly _onTitleChange = this._register(new Emitter<string>());
|
|
133
133
|
public readonly onTitleChange = this._onTitleChange.event;
|
|
134
|
-
private readonly _onBell = this.
|
|
134
|
+
private readonly _onBell = this._register(new Emitter<void>());
|
|
135
135
|
public readonly onBell = this._onBell.event;
|
|
136
136
|
|
|
137
|
-
private _onFocus = this.
|
|
137
|
+
private _onFocus = this._register(new Emitter<void>());
|
|
138
138
|
public get onFocus(): Event<void> { return this._onFocus.event; }
|
|
139
|
-
private _onBlur = this.
|
|
139
|
+
private _onBlur = this._register(new Emitter<void>());
|
|
140
140
|
public get onBlur(): Event<void> { return this._onBlur.event; }
|
|
141
|
-
private _onA11yCharEmitter = this.
|
|
141
|
+
private _onA11yCharEmitter = this._register(new Emitter<string>());
|
|
142
142
|
public get onA11yChar(): Event<string> { return this._onA11yCharEmitter.event; }
|
|
143
|
-
private _onA11yTabEmitter = this.
|
|
143
|
+
private _onA11yTabEmitter = this._register(new Emitter<number>());
|
|
144
144
|
public get onA11yTab(): Event<number> { return this._onA11yTabEmitter.event; }
|
|
145
|
-
private _onWillOpen = this.
|
|
145
|
+
private _onWillOpen = this._register(new Emitter<HTMLElement>());
|
|
146
146
|
public get onWillOpen(): Event<HTMLElement> { return this._onWillOpen.event; }
|
|
147
147
|
|
|
148
148
|
constructor(
|
|
@@ -159,21 +159,21 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
159
159
|
this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));
|
|
160
160
|
|
|
161
161
|
// Setup InputHandler listeners
|
|
162
|
-
this.
|
|
163
|
-
this.
|
|
164
|
-
this.
|
|
165
|
-
this.
|
|
166
|
-
this.
|
|
167
|
-
this.
|
|
168
|
-
this.
|
|
169
|
-
this.
|
|
170
|
-
this.
|
|
171
|
-
this.
|
|
162
|
+
this._register(this._inputHandler.onRequestBell(() => this._onBell.fire()));
|
|
163
|
+
this._register(this._inputHandler.onRequestRefreshRows((e) => this.refresh(e?.start ?? 0, e?.end ?? (this.rows - 1))));
|
|
164
|
+
this._register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));
|
|
165
|
+
this._register(this._inputHandler.onRequestReset(() => this.reset()));
|
|
166
|
+
this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));
|
|
167
|
+
this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));
|
|
168
|
+
this._register(Event.forward(this._inputHandler.onCursorMove, this._onCursorMove));
|
|
169
|
+
this._register(Event.forward(this._inputHandler.onTitleChange, this._onTitleChange));
|
|
170
|
+
this._register(Event.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));
|
|
171
|
+
this._register(Event.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));
|
|
172
172
|
|
|
173
173
|
// Setup listeners
|
|
174
|
-
this.
|
|
174
|
+
this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));
|
|
175
175
|
|
|
176
|
-
this.
|
|
176
|
+
this._register(toDisposable(() => {
|
|
177
177
|
this._customKeyEventHandler = undefined;
|
|
178
178
|
this.element?.parentNode?.removeChild(this.element);
|
|
179
179
|
}));
|
|
@@ -330,7 +330,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
330
330
|
this._bindKeys();
|
|
331
331
|
|
|
332
332
|
// Bind clipboard functionality
|
|
333
|
-
this.
|
|
333
|
+
this._register(addDisposableListener(this.element!, 'copy', (event: ClipboardEvent) => {
|
|
334
334
|
// If mouse events are active it means the selection manager is disabled and
|
|
335
335
|
// copy should be handled by the host program.
|
|
336
336
|
if (!this.hasSelection()) {
|
|
@@ -339,19 +339,19 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
339
339
|
copyHandler(event, this._selectionService!);
|
|
340
340
|
}));
|
|
341
341
|
const pasteHandlerWrapper = (event: ClipboardEvent): void => handlePasteEvent(event, this.textarea!, this.coreService, this.optionsService);
|
|
342
|
-
this.
|
|
343
|
-
this.
|
|
342
|
+
this._register(addDisposableListener(this.textarea!, 'paste', pasteHandlerWrapper));
|
|
343
|
+
this._register(addDisposableListener(this.element!, 'paste', pasteHandlerWrapper));
|
|
344
344
|
|
|
345
345
|
// Handle right click context menus
|
|
346
346
|
if (Browser.isFirefox) {
|
|
347
347
|
// Firefox doesn't appear to fire the contextmenu event on right click
|
|
348
|
-
this.
|
|
348
|
+
this._register(addDisposableListener(this.element!, 'mousedown', (event: MouseEvent) => {
|
|
349
349
|
if (event.button === 2) {
|
|
350
350
|
rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);
|
|
351
351
|
}
|
|
352
352
|
}));
|
|
353
353
|
} else {
|
|
354
|
-
this.
|
|
354
|
+
this._register(addDisposableListener(this.element!, 'contextmenu', (event: MouseEvent) => {
|
|
355
355
|
rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);
|
|
356
356
|
}));
|
|
357
357
|
}
|
|
@@ -362,7 +362,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
362
362
|
if (Browser.isLinux) {
|
|
363
363
|
// Use auxclick event over mousedown the latter doesn't seem to work. Note
|
|
364
364
|
// that the regular click event doesn't fire for the middle mouse button.
|
|
365
|
-
this.
|
|
365
|
+
this._register(addDisposableListener(this.element!, 'auxclick', (event: MouseEvent) => {
|
|
366
366
|
if (event.button === 1) {
|
|
367
367
|
moveTextAreaUnderMouseCursor(event, this.textarea!, this.screenElement!);
|
|
368
368
|
}
|
|
@@ -374,14 +374,14 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
374
374
|
* Apply key handling to the terminal
|
|
375
375
|
*/
|
|
376
376
|
private _bindKeys(): void {
|
|
377
|
-
this.
|
|
378
|
-
this.
|
|
379
|
-
this.
|
|
380
|
-
this.
|
|
381
|
-
this.
|
|
382
|
-
this.
|
|
383
|
-
this.
|
|
384
|
-
this.
|
|
377
|
+
this._register(addDisposableListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));
|
|
378
|
+
this._register(addDisposableListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));
|
|
379
|
+
this._register(addDisposableListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));
|
|
380
|
+
this._register(addDisposableListener(this.textarea!, 'compositionstart', () => this._compositionHelper!.compositionstart()));
|
|
381
|
+
this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));
|
|
382
|
+
this._register(addDisposableListener(this.textarea!, 'compositionend', () => this._compositionHelper!.compositionend()));
|
|
383
|
+
this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));
|
|
384
|
+
this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));
|
|
385
385
|
}
|
|
386
386
|
|
|
387
387
|
/**
|
|
@@ -428,7 +428,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
428
428
|
|
|
429
429
|
this.screenElement = this._document.createElement('div');
|
|
430
430
|
this.screenElement.classList.add('xterm-screen');
|
|
431
|
-
this.
|
|
431
|
+
this._register(addDisposableListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));
|
|
432
432
|
// Create the container that will hold helpers like the textarea for
|
|
433
433
|
// capturing DOM Events. Then produce the helpers.
|
|
434
434
|
this._helperContainer = this._document.createElement('div');
|
|
@@ -451,7 +451,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
451
451
|
|
|
452
452
|
// Register the core browser service before the generic textarea handlers are registered so it
|
|
453
453
|
// handles them first. Otherwise the renderers may use the wrong focus state.
|
|
454
|
-
this._coreBrowserService = this.
|
|
454
|
+
this._coreBrowserService = this._register(this._instantiationService.createInstance(CoreBrowserService,
|
|
455
455
|
this.textarea,
|
|
456
456
|
parent.ownerDocument.defaultView ?? window,
|
|
457
457
|
// Force unsafe null in node.js environment for tests
|
|
@@ -459,8 +459,8 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
459
459
|
));
|
|
460
460
|
this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);
|
|
461
461
|
|
|
462
|
-
this.
|
|
463
|
-
this.
|
|
462
|
+
this._register(addDisposableListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));
|
|
463
|
+
this._register(addDisposableListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));
|
|
464
464
|
this._helperContainer.appendChild(this.textarea);
|
|
465
465
|
|
|
466
466
|
this._charSizeService = this._instantiationService.createInstance(CharSizeService, this._document, this._helperContainer);
|
|
@@ -472,9 +472,9 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
472
472
|
this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);
|
|
473
473
|
this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);
|
|
474
474
|
|
|
475
|
-
this._renderService = this.
|
|
475
|
+
this._renderService = this._register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));
|
|
476
476
|
this._instantiationService.setService(IRenderService, this._renderService);
|
|
477
|
-
this.
|
|
477
|
+
this._register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));
|
|
478
478
|
this.onResize(e => this._renderService!.resize(e.cols, e.rows));
|
|
479
479
|
|
|
480
480
|
this._compositionView = this._document.createElement('div');
|
|
@@ -485,7 +485,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
485
485
|
this._mouseService = this._instantiationService.createInstance(MouseService);
|
|
486
486
|
this._instantiationService.setService(IMouseService, this._mouseService);
|
|
487
487
|
|
|
488
|
-
this.linkifier = this.
|
|
488
|
+
this.linkifier = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement));
|
|
489
489
|
|
|
490
490
|
// Performance: Add viewport and helper elements from the fragment
|
|
491
491
|
this.element.appendChild(fragment);
|
|
@@ -498,30 +498,30 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
498
498
|
this._renderService.setRenderer(this._createRenderer());
|
|
499
499
|
}
|
|
500
500
|
|
|
501
|
-
this.
|
|
501
|
+
this._register(this.onCursorMove(() => {
|
|
502
502
|
this._renderService!.handleCursorMove();
|
|
503
503
|
this._syncTextArea();
|
|
504
504
|
}));
|
|
505
|
-
this.
|
|
506
|
-
this.
|
|
507
|
-
this.
|
|
505
|
+
this._register(this.onResize(() => this._renderService!.handleResize(this.cols, this.rows)));
|
|
506
|
+
this._register(this.onBlur(() => this._renderService!.handleBlur()));
|
|
507
|
+
this._register(this.onFocus(() => this._renderService!.handleFocus()));
|
|
508
508
|
|
|
509
|
-
this._viewport = this.
|
|
510
|
-
this.
|
|
509
|
+
this._viewport = this._register(this._instantiationService.createInstance(Viewport, this.element, this.screenElement));
|
|
510
|
+
this._register(this._viewport.onRequestScrollLines(e => {
|
|
511
511
|
super.scrollLines(e, false);
|
|
512
512
|
this.refresh(0, this.rows - 1);
|
|
513
513
|
}));
|
|
514
514
|
|
|
515
|
-
this._selectionService = this.
|
|
515
|
+
this._selectionService = this._register(this._instantiationService.createInstance(SelectionService,
|
|
516
516
|
this.element,
|
|
517
517
|
this.screenElement,
|
|
518
518
|
this.linkifier
|
|
519
519
|
));
|
|
520
520
|
this._instantiationService.setService(ISelectionService, this._selectionService);
|
|
521
|
-
this.
|
|
522
|
-
this.
|
|
523
|
-
this.
|
|
524
|
-
this.
|
|
521
|
+
this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));
|
|
522
|
+
this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));
|
|
523
|
+
this._register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));
|
|
524
|
+
this._register(this._selectionService.onLinuxMouseSelection(text => {
|
|
525
525
|
// If there's a new selection, put it into the textarea, focus and select it
|
|
526
526
|
// in order to register it as a selection on the OS. This event is fired
|
|
527
527
|
// only on Linux to enable middle click to paste selection.
|
|
@@ -529,10 +529,10 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
529
529
|
this.textarea!.focus();
|
|
530
530
|
this.textarea!.select();
|
|
531
531
|
}));
|
|
532
|
-
this.
|
|
532
|
+
this._register(this._onScroll.event(() => this._selectionService!.refresh()));
|
|
533
533
|
|
|
534
|
-
this.
|
|
535
|
-
this.
|
|
534
|
+
this._register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));
|
|
535
|
+
this._register(addDisposableListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));
|
|
536
536
|
|
|
537
537
|
// apply mouse event classes set by escape codes before terminal was attached
|
|
538
538
|
if (this.coreMouseService.areMouseEventsActive) {
|
|
@@ -547,14 +547,14 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
547
547
|
// ensure the correct order of the dprchange event
|
|
548
548
|
this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);
|
|
549
549
|
}
|
|
550
|
-
this.
|
|
550
|
+
this._register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));
|
|
551
551
|
|
|
552
552
|
if (this.options.overviewRuler.width) {
|
|
553
|
-
this._overviewRulerRenderer = this.
|
|
553
|
+
this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));
|
|
554
554
|
}
|
|
555
555
|
this.optionsService.onSpecificOptionChange('overviewRuler', value => {
|
|
556
|
-
if (!this._overviewRulerRenderer && value
|
|
557
|
-
this._overviewRulerRenderer = this.
|
|
556
|
+
if (!this._overviewRulerRenderer && value && this._viewportElement && this.screenElement) {
|
|
557
|
+
this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));
|
|
558
558
|
}
|
|
559
559
|
});
|
|
560
560
|
// Measure the character size
|
|
@@ -707,7 +707,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
707
707
|
}
|
|
708
708
|
}
|
|
709
709
|
};
|
|
710
|
-
this.
|
|
710
|
+
this._register(this.coreMouseService.onProtocolChange(events => {
|
|
711
711
|
// apply global changes on events
|
|
712
712
|
if (events) {
|
|
713
713
|
if (this.optionsService.rawOptions.logLevel === 'debug') {
|
|
@@ -759,7 +759,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
759
759
|
/**
|
|
760
760
|
* "Always on" event listeners.
|
|
761
761
|
*/
|
|
762
|
-
this.
|
|
762
|
+
this._register(addDisposableListener(el, 'mousedown', (ev: MouseEvent) => {
|
|
763
763
|
ev.preventDefault();
|
|
764
764
|
this.focus();
|
|
765
765
|
|
|
@@ -786,7 +786,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
|
|
|
786
786
|
return this.cancel(ev);
|
|
787
787
|
}));
|
|
788
788
|
|
|
789
|
-
this.
|
|
789
|
+
this._register(addDisposableListener(el, 'wheel', (ev: WheelEvent) => {
|
|
790
790
|
// do nothing, if app side handles wheel itself
|
|
791
791
|
if (requestedEvents.wheel) return;
|
|
792
792
|
|
package/src/browser/Linkifier.ts
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* @license MIT
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { addDisposableDomListener } from 'browser/Lifecycle';
|
|
7
6
|
import { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from 'browser/Types';
|
|
8
|
-
import { Disposable,
|
|
7
|
+
import { Disposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
|
9
8
|
import { IDisposable } from 'common/Types';
|
|
10
9
|
import { IBufferService } from 'common/services/Services';
|
|
11
10
|
import { ILinkProviderService, IMouseService, IRenderService } from './services/Services';
|
|
12
11
|
import { Emitter } from 'vs/base/common/event';
|
|
12
|
+
import { addDisposableListener } from 'vs/base/browser/dom';
|
|
13
13
|
|
|
14
14
|
export class Linkifier extends Disposable implements ILinkifier2 {
|
|
15
15
|
public get currentLink(): ILinkWithState | undefined { return this._currentLink; }
|
|
@@ -23,9 +23,9 @@ export class Linkifier extends Disposable implements ILinkifier2 {
|
|
|
23
23
|
private _activeProviderReplies: Map<Number, ILinkWithState[] | undefined> | undefined;
|
|
24
24
|
private _activeLine: number = -1;
|
|
25
25
|
|
|
26
|
-
private readonly _onShowLinkUnderline = this.
|
|
26
|
+
private readonly _onShowLinkUnderline = this._register(new Emitter<ILinkifierEvent>());
|
|
27
27
|
public readonly onShowLinkUnderline = this._onShowLinkUnderline.event;
|
|
28
|
-
private readonly _onHideLinkUnderline = this.
|
|
28
|
+
private readonly _onHideLinkUnderline = this._register(new Emitter<ILinkifierEvent>());
|
|
29
29
|
public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;
|
|
30
30
|
|
|
31
31
|
constructor(
|
|
@@ -36,24 +36,25 @@ export class Linkifier extends Disposable implements ILinkifier2 {
|
|
|
36
36
|
@ILinkProviderService private readonly _linkProviderService: ILinkProviderService
|
|
37
37
|
) {
|
|
38
38
|
super();
|
|
39
|
-
this.
|
|
40
|
-
|
|
39
|
+
this._register(toDisposable(() => {
|
|
40
|
+
dispose(this._linkCacheDisposables);
|
|
41
|
+
this._linkCacheDisposables.length = 0;
|
|
41
42
|
this._lastMouseEvent = undefined;
|
|
42
43
|
// Clear out link providers as they could easily cause an embedder memory leak
|
|
43
44
|
this._activeProviderReplies?.clear();
|
|
44
45
|
}));
|
|
45
46
|
// Listen to resize to catch the case where it's resized and the cursor is out of the viewport.
|
|
46
|
-
this.
|
|
47
|
+
this._register(this._bufferService.onResize(() => {
|
|
47
48
|
this._clearCurrentLink();
|
|
48
49
|
this._wasResized = true;
|
|
49
50
|
}));
|
|
50
|
-
this.
|
|
51
|
+
this._register(addDisposableListener(this._element, 'mouseleave', () => {
|
|
51
52
|
this._isMouseOut = true;
|
|
52
53
|
this._clearCurrentLink();
|
|
53
54
|
}));
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
56
|
-
this.
|
|
55
|
+
this._register(addDisposableListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));
|
|
56
|
+
this._register(addDisposableListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));
|
|
57
|
+
this._register(addDisposableListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));
|
|
57
58
|
}
|
|
58
59
|
|
|
59
60
|
private _handleMouseMove(event: MouseEvent): void {
|
|
@@ -240,7 +241,8 @@ export class Linkifier extends Disposable implements ILinkifier2 {
|
|
|
240
241
|
if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) {
|
|
241
242
|
this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent);
|
|
242
243
|
this._currentLink = undefined;
|
|
243
|
-
|
|
244
|
+
dispose(this._linkCacheDisposables);
|
|
245
|
+
this._linkCacheDisposables.length = 0;
|
|
244
246
|
}
|
|
245
247
|
}
|
|
246
248
|
|
package/src/browser/Viewport.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
|
|
7
7
|
import { ViewportConstants } from 'browser/shared/Constants';
|
|
8
|
-
import { Disposable, toDisposable } from 'common/
|
|
8
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
9
9
|
import { IBufferService, ICoreMouseService, IOptionsService } from 'common/services/Services';
|
|
10
10
|
import { CoreMouseEventType } from 'common/Types';
|
|
11
11
|
import { scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
|
@@ -16,7 +16,7 @@ import { Scrollable, ScrollbarVisibility, type ScrollEvent } from 'vs/base/commo
|
|
|
16
16
|
|
|
17
17
|
export class Viewport extends Disposable {
|
|
18
18
|
|
|
19
|
-
protected _onRequestScrollLines = this.
|
|
19
|
+
protected _onRequestScrollLines = this._register(new Emitter<number>());
|
|
20
20
|
public readonly onRequestScrollLines = this._onRequestScrollLines.event;
|
|
21
21
|
|
|
22
22
|
private _scrollableElement: SmoothScrollableElement;
|
|
@@ -40,46 +40,46 @@ export class Viewport extends Disposable {
|
|
|
40
40
|
) {
|
|
41
41
|
super();
|
|
42
42
|
|
|
43
|
-
const scrollable = this.
|
|
43
|
+
const scrollable = this._register(new Scrollable({
|
|
44
44
|
forceIntegerValues: false,
|
|
45
45
|
smoothScrollDuration: this._optionsService.rawOptions.smoothScrollDuration,
|
|
46
46
|
// This is used over `IRenderService.addRefreshCallback` since it can be canceled
|
|
47
47
|
scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(coreBrowserService.window, cb)
|
|
48
48
|
}));
|
|
49
|
-
this.
|
|
49
|
+
this._register(this._optionsService.onSpecificOptionChange('smoothScrollDuration', () => {
|
|
50
50
|
scrollable.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration);
|
|
51
51
|
}));
|
|
52
52
|
|
|
53
|
-
this._scrollableElement = this.
|
|
53
|
+
this._scrollableElement = this._register(new SmoothScrollableElement(screenElement, {
|
|
54
54
|
vertical: ScrollbarVisibility.Auto,
|
|
55
55
|
horizontal: ScrollbarVisibility.Hidden,
|
|
56
56
|
useShadows: false,
|
|
57
57
|
mouseWheelSmoothScroll: true,
|
|
58
58
|
...this._getChangeOptions()
|
|
59
59
|
}, scrollable));
|
|
60
|
-
this.
|
|
60
|
+
this._register(this._optionsService.onMultipleOptionChange([
|
|
61
61
|
'scrollSensitivity',
|
|
62
62
|
'fastScrollSensitivity',
|
|
63
63
|
'overviewRuler'
|
|
64
64
|
], () => this._scrollableElement.updateOptions(this._getChangeOptions())));
|
|
65
65
|
// Don't handle mouse wheel if wheel events are supported by the current mouse prototcol
|
|
66
|
-
this.
|
|
66
|
+
this._register(coreMouseService.onProtocolChange(type => {
|
|
67
67
|
this._scrollableElement.updateOptions({
|
|
68
68
|
handleMouseWheel: !(type & CoreMouseEventType.WHEEL)
|
|
69
69
|
});
|
|
70
70
|
}));
|
|
71
71
|
|
|
72
72
|
this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });
|
|
73
|
-
this.
|
|
73
|
+
this._register(Event.runAndSubscribe(themeService.onChangeColors, () => {
|
|
74
74
|
this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;
|
|
75
75
|
}));
|
|
76
76
|
element.appendChild(this._scrollableElement.getDomNode());
|
|
77
|
-
this.
|
|
77
|
+
this._register(toDisposable(() => this._scrollableElement.getDomNode().remove()));
|
|
78
78
|
|
|
79
79
|
this._styleElement = coreBrowserService.window.document.createElement('style');
|
|
80
80
|
screenElement.appendChild(this._styleElement);
|
|
81
|
-
this.
|
|
82
|
-
this.
|
|
81
|
+
this._register(toDisposable(() => this._styleElement.remove()));
|
|
82
|
+
this._register(Event.runAndSubscribe(themeService.onChangeColors, () => {
|
|
83
83
|
this._styleElement.textContent = [
|
|
84
84
|
`.xterm .xterm-scrollable-element > .scrollbar > .slider {`,
|
|
85
85
|
` background: ${themeService.colors.scrollbarSliderBackground.css};`,
|
|
@@ -93,10 +93,10 @@ export class Viewport extends Disposable {
|
|
|
93
93
|
].join('\n');
|
|
94
94
|
}));
|
|
95
95
|
|
|
96
|
-
this.
|
|
97
|
-
this.
|
|
96
|
+
this._register(this._bufferService.onResize(() => this._queueSync()));
|
|
97
|
+
this._register(this._bufferService.onScroll(() => this._sync()));
|
|
98
98
|
|
|
99
|
-
this.
|
|
99
|
+
this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
public scrollLines(disp: number): void {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
6
|
import { ICoreBrowserService, IRenderService } from 'browser/services/Services';
|
|
7
|
-
import { Disposable, toDisposable } from 'common/
|
|
7
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
8
8
|
import { IBufferService, IDecorationService, IInternalDecoration } from 'common/services/Services';
|
|
9
9
|
|
|
10
10
|
export class BufferDecorationRenderer extends Disposable {
|
|
@@ -28,18 +28,18 @@ export class BufferDecorationRenderer extends Disposable {
|
|
|
28
28
|
this._container.classList.add('xterm-decoration-container');
|
|
29
29
|
this._screenElement.appendChild(this._container);
|
|
30
30
|
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
31
|
+
this._register(this._renderService.onRenderedViewportChange(() => this._doRefreshDecorations()));
|
|
32
|
+
this._register(this._renderService.onDimensionsChange(() => {
|
|
33
33
|
this._dimensionsChanged = true;
|
|
34
34
|
this._queueRefresh();
|
|
35
35
|
}));
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
36
|
+
this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh()));
|
|
37
|
+
this._register(this._bufferService.buffers.onBufferActivate(() => {
|
|
38
38
|
this._altBufferIsActive = this._bufferService.buffer === this._bufferService.buffers.alt;
|
|
39
39
|
}));
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
this.
|
|
40
|
+
this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh()));
|
|
41
|
+
this._register(this._decorationService.onDecorationRemoved(decoration => this._removeDecoration(decoration)));
|
|
42
|
+
this._register(toDisposable(() => {
|
|
43
43
|
this._container.remove();
|
|
44
44
|
this._decorationElements.clear();
|
|
45
45
|
}));
|