Merge branch 'master' into 5626

This commit is contained in:
Daniel Imms
2026-01-31 09:12:15 -08:00
committed by GitHub
99 changed files with 2340 additions and 1366 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
import * as Strings from 'browser/LocalizableStrings';
import { ITerminal, IRenderDebouncer } from 'browser/Types';
import { TimeBasedDebouncer } from 'browser/TimeBasedDebouncer';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { ICoreBrowserService, IRenderService } from 'browser/services/Services';
import { IBuffer } from 'common/buffer/Types';
import { IInstantiationService } from 'common/services/Services';
+18 -18
View File
@@ -48,16 +48,16 @@ import * as Browser from 'common/Platform';
import { ColorRequestType, CoreMouseAction, CoreMouseButton, CoreMouseEventType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from 'common/Types';
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
import { IBuffer } from 'common/buffer/Types';
import { C0, C1_ESCAPED } from 'common/data/EscapeSequences';
import { C0, C1ESCAPED } from 'common/data/EscapeSequences';
import { toRgbString } from 'common/input/XParseColor';
import { DecorationService } from 'common/services/DecorationService';
import { IDecorationService } from 'common/services/Services';
import { WindowsOptionsReportType } from '../common/InputHandler';
import { AccessibilityManager } from './AccessibilityManager';
import { Linkifier } from './Linkifier';
import { Emitter, Event } from 'vs/base/common/event';
import { Emitter, EventUtils, type IEvent } from 'common/Event';
import { addDisposableListener } from 'vs/base/browser/dom';
import { MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { MutableDisposable, toDisposable } from 'common/Lifecycle';
export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
public textarea: HTMLTextAreaElement | undefined;
@@ -135,15 +135,15 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
public readonly onBell = this._onBell.event;
private _onFocus = this._register(new Emitter<void>());
public get onFocus(): Event<void> { return this._onFocus.event; }
public get onFocus(): IEvent<void> { return this._onFocus.event; }
private _onBlur = this._register(new Emitter<void>());
public get onBlur(): Event<void> { return this._onBlur.event; }
public get onBlur(): IEvent<void> { return this._onBlur.event; }
private _onA11yCharEmitter = this._register(new Emitter<string>());
public get onA11yChar(): Event<string> { return this._onA11yCharEmitter.event; }
public get onA11yChar(): IEvent<string> { return this._onA11yCharEmitter.event; }
private _onA11yTabEmitter = this._register(new Emitter<number>());
public get onA11yTab(): Event<number> { return this._onA11yTabEmitter.event; }
public get onA11yTab(): IEvent<number> { return this._onA11yTabEmitter.event; }
private _onWillOpen = this._register(new Emitter<HTMLElement>());
public get onWillOpen(): Event<HTMLElement> { return this._onWillOpen.event; }
public get onWillOpen(): IEvent<HTMLElement> { return this._onWillOpen.event; }
private readonly _onDimensionsChange = this._register(new Emitter<IRenderDimensionsApi>());
public readonly onDimensionsChange = this._onDimensionsChange.event;
@@ -187,10 +187,10 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
this._register(this._inputHandler.onRequestReset(() => this.reset()));
this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));
this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));
this._register(Event.forward(this._inputHandler.onCursorMove, this._onCursorMove));
this._register(Event.forward(this._inputHandler.onTitleChange, this._onTitleChange));
this._register(Event.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));
this._register(Event.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));
this._register(EventUtils.forward(this._inputHandler.onCursorMove, this._onCursorMove));
this._register(EventUtils.forward(this._inputHandler.onTitleChange, this._onTitleChange));
this._register(EventUtils.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));
this._register(EventUtils.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));
// Setup listeners
this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));
@@ -235,7 +235,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
const colorRgb = color.toColorRGB(acc === 'ansi'
? this._themeService.colors.ansi[req.index]
: this._themeService.colors[acc]);
this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1_ESCAPED.ST}`);
this.coreService.triggerDataEvent(`${C0.ESC}]${ident};${toRgbString(colorRgb)}${C1ESCAPED.ST}`);
break;
case ColorRequestType.SET:
if (acc === 'ansi') {
@@ -590,7 +590,7 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
this.textarea!.focus();
this.textarea!.select();
}));
this._register(Event.any(
this._register(EventUtils.any(
this._onScroll.event,
this._inputHandler.onScroll
)(() => {
@@ -817,15 +817,15 @@ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
if (!(events & CoreMouseEventType.UP)) {
this._document!.removeEventListener('mouseup', requestedEvents.mouseup!);
requestedEvents.mouseup = null;
} else if (!requestedEvents.mouseup) {
requestedEvents.mouseup = eventListeners.mouseup;
} else {
requestedEvents.mouseup ??= eventListeners.mouseup;
}
if (!(events & CoreMouseEventType.DRAG)) {
this._document!.removeEventListener('mousemove', requestedEvents.mousedrag!);
requestedEvents.mousedrag = null;
} else if (!requestedEvents.mousedrag) {
requestedEvents.mousedrag = eventListeners.mousedrag;
} else {
requestedEvents.mousedrag ??= eventListeners.mousedrag;
}
}));
// force initial onProtocolChange so we dont miss early mouse requests
+2 -2
View File
@@ -4,11 +4,11 @@
*/
import { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from 'browser/Types';
import { Disposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, dispose, toDisposable } from 'common/Lifecycle';
import { IDisposable } from 'common/Types';
import { IBufferService } from 'common/services/Services';
import { ILinkProviderService, IMouseService, IRenderService } from './services/Services';
import { Emitter } from 'vs/base/common/event';
import { Emitter } from 'common/Event';
import { addDisposableListener } from 'vs/base/browser/dom';
export class Linkifier extends Disposable implements ILinkifier2 {
+2 -2
View File
@@ -40,8 +40,8 @@ export class RenderDebouncer implements IRenderDebouncerWithCallback {
public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {
this._rowCount = rowCount;
// Get the min/max row start/end for the arg values
rowStart = rowStart !== undefined ? rowStart : 0;
rowEnd = rowEnd !== undefined ? rowEnd : this._rowCount - 1;
rowStart = rowStart ?? 0;
rowEnd = rowEnd ?? this._rowCount - 1;
// Set the properties to the updated values
this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;
this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;
+30 -27
View File
@@ -18,7 +18,7 @@ import { AttributeData } from 'common/buffer/AttributeData';
import { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types';
import { css } from 'common/Color';
import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
import { Emitter, type Event } from 'vs/base/common/event';
import { Emitter, type IEvent } from 'common/Event';
export class TestTerminal extends CoreBrowserTerminal {
public get curAttrData(): IAttributeData { return (this as any)._inputHandler._curAttrData; }
@@ -30,24 +30,24 @@ export class TestTerminal extends CoreBrowserTerminal {
}
export class MockTerminal implements ITerminal {
public onBlur!: Event<void>;
public onFocus!: Event<void>;
public onA11yChar!: Event<string>;
public onWriteParsed!: Event<void>;
public onA11yTab!: Event<number>;
public onCursorMove!: Event<void>;
public onLineFeed!: Event<void>;
public onSelectionChange!: Event<void>;
public onData!: Event<string>;
public onBinary!: Event<string>;
public onTitleChange!: Event<string>;
public onBell!: Event<void>;
public onScroll!: Event<number>;
public onWillOpen!: Event<HTMLElement>;
public onKey!: Event<{ key: string, domEvent: KeyboardEvent }>;
public onRender!: Event<{ start: number, end: number }>;
public onResize!: Event<{ cols: number, rows: number }>;
public onDimensionsChange!: Event<IRenderDimensionsApi>;
public onBlur!: IEvent<void>;
public onFocus!: IEvent<void>;
public onA11yChar!: IEvent<string>;
public onWriteParsed!: IEvent<void>;
public onA11yTab!: IEvent<number>;
public onCursorMove!: IEvent<void>;
public onLineFeed!: IEvent<void>;
public onSelectionChange!: IEvent<void>;
public onData!: IEvent<string>;
public onBinary!: IEvent<string>;
public onTitleChange!: IEvent<string>;
public onBell!: IEvent<void>;
public onScroll!: IEvent<number>;
public onWillOpen!: IEvent<HTMLElement>;
public onKey!: IEvent<{ key: string, domEvent: KeyboardEvent }>;
public onRender!: IEvent<{ start: number, end: number }>;
public onResize!: IEvent<{ cols: number, rows: number }>;
public onDimensionsChange!: IEvent<IRenderDimensionsApi>;
public dimensions: IRenderDimensionsApi | undefined;
public markers!: IMarker[];
public linkifier: ILinkifier2 | undefined;
@@ -107,6 +107,9 @@ export class MockTerminal implements ITerminal {
public registerOscHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
throw new Error('Method not implemented.');
}
public registerApcHandler(ident: number, callback: (data: string) => boolean | Promise<boolean>): IDisposable {
throw new Error('Method not implemented.');
}
public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
throw new Error('Method not implemented.');
}
@@ -273,9 +276,9 @@ export class MockBuffer implements IBuffer {
}
export class MockRenderer implements IRenderer {
public onRequestRedraw!: Event<IRequestRedrawEvent>;
public onCanvasResize!: Event<{ width: number, height: number }>;
public onRender!: Event<{ start: number, end: number }>;
public onRequestRedraw!: IEvent<IRequestRedrawEvent>;
public onCanvasResize!: IEvent<{ width: number, height: number }>;
public onRender!: IEvent<{ start: number, end: number }>;
public dispose(): void {
throw new Error('Method not implemented.');
}
@@ -378,7 +381,7 @@ export class MockCoreBrowserService implements ICoreBrowserService {
export class MockCharSizeService implements ICharSizeService {
public serviceBrand: undefined;
public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }
public onCharSizeChange: Event<void> = new Emitter<void>().event;
public onCharSizeChange: IEvent<void> = new Emitter<void>().event;
constructor(public width: number, public height: number) {}
public measure(): void {}
}
@@ -396,10 +399,10 @@ export class MockMouseService implements IMouseService {
export class MockRenderService implements IRenderService {
public serviceBrand: undefined;
public onDimensionsChange: Event<IRenderDimensions> = new Emitter<IRenderDimensions>().event;
public onRenderedViewportChange: Event<{ start: number, end: number }> = new Emitter<{ start: number, end: number }>().event;
public onRender: Event<{ start: number, end: number }> = new Emitter<{ start: number, end: number }>().event;
public onRefreshRequest: Event<{ start: number, end: number}> = new Emitter<{ start: number, end: number }>().event;
public onDimensionsChange: IEvent<IRenderDimensions> = new Emitter<IRenderDimensions>().event;
public onRenderedViewportChange: IEvent<{ start: number, end: number }> = new Emitter<{ start: number, end: number }>().event;
public onRender: IEvent<{ start: number, end: number }> = new Emitter<{ start: number, end: number }>().event;
public onRefreshRequest: IEvent<{ start: number, end: number}> = new Emitter<{ start: number, end: number }>().event;
public dimensions: IRenderDimensions = createRenderDimensions();
public refreshRows(start: number, end: number): void {
throw new Error('Method not implemented.');
+2 -2
View File
@@ -37,8 +37,8 @@ export class TimeBasedDebouncer implements IRenderDebouncer {
public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {
this._rowCount = rowCount;
// Get the min/max row start/end for the arg values
rowStart = rowStart !== undefined ? rowStart : 0;
rowEnd = rowEnd !== undefined ? rowEnd : this._rowCount - 1;
rowStart = rowStart ?? 0;
rowEnd = rowEnd ?? this._rowCount - 1;
// Set the properties to the updated values
this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;
this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;
+10 -10
View File
@@ -7,7 +7,7 @@ import { CharData, IColor, ICoreTerminal, ITerminalOptions } from 'common/Types'
import { IBuffer } from 'common/buffer/Types';
import { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';
import { channels, css } from 'common/Color';
import type { Event } from 'vs/base/common/event';
import type { IEvent } from 'common/Event';
/**
* A portion of the public API that are implemented identially internally and simply passed through.
@@ -23,12 +23,12 @@ export interface ITerminal extends InternalPassthroughApis, ICoreTerminal {
readonly dimensions: IRenderDimensionsApi | undefined;
onBlur: Event<void>;
onFocus: Event<void>;
onDimensionsChange: Event<IRenderDimensionsApi>;
onA11yChar: Event<string>;
onA11yTab: Event<number>;
onWillOpen: Event<HTMLElement>;
onBlur: IEvent<void>;
onFocus: IEvent<void>;
onDimensionsChange: IEvent<IRenderDimensionsApi>;
onA11yChar: IEvent<string>;
onA11yTab: IEvent<number>;
onWillOpen: IEvent<HTMLElement>;
cancel(ev: MouseEvent | WheelEvent | KeyboardEvent | InputEvent, force?: boolean): boolean | void;
}
@@ -101,7 +101,7 @@ export interface IPartialColorSet {
export interface IViewport extends IDisposable {
scrollBarWidth: number;
readonly onRequestScrollLines: Event<{ amount: number, suppressScrollEvent: boolean }>;
readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;
syncScrollArea(immediate?: boolean, force?: boolean): void;
getLinesScrolled(ev: WheelEvent): number;
getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };
@@ -131,8 +131,8 @@ export interface ILinkWithState {
}
export interface ILinkifier2 extends IDisposable {
onShowLinkUnderline: Event<ILinkifierEvent>;
onHideLinkUnderline: Event<ILinkifierEvent>;
onShowLinkUnderline: IEvent<ILinkifierEvent>;
onHideLinkUnderline: IEvent<ILinkifierEvent>;
readonly currentLink: ILinkWithState | undefined;
}
+4 -4
View File
@@ -5,13 +5,13 @@
import { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
import { ViewportConstants } from 'browser/shared/Constants';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { IBufferService, ICoreMouseService, IOptionsService } from 'common/services/Services';
import { CoreMouseEventType } from 'common/Types';
import { addDisposableListener, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import type { ScrollableElementChangeOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
import { Emitter, Event } from 'vs/base/common/event';
import { Emitter, EventUtils } from 'common/Event';
import { Scrollable, ScrollbarVisibility, type ScrollEvent } from 'vs/base/common/scrollable';
import { Gesture, EventType as GestureEventType, type GestureEvent } from 'vs/base/browser/touch';
@@ -71,7 +71,7 @@ export class Viewport extends Disposable {
}));
this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });
this._register(Event.runAndSubscribe(themeService.onChangeColors, () => {
this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {
element.style.backgroundColor = themeService.colors.background.css;
this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;
}));
@@ -81,7 +81,7 @@ export class Viewport extends Disposable {
this._styleElement = coreBrowserService.mainDocument.createElement('style');
screenElement.appendChild(this._styleElement);
this._register(toDisposable(() => this._styleElement.remove()));
this._register(Event.runAndSubscribe(themeService.onChangeColors, () => {
this._register(EventUtils.runAndSubscribe(themeService.onChangeColors, () => {
this._styleElement.textContent = [
`.xterm .xterm-scrollable-element > .scrollbar > .slider {`,
` background: ${themeService.colors.scrollbarSliderBackground.css};`,
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { ICoreBrowserService, IRenderService } from 'browser/services/Services';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { IBufferService, IDecorationService, IInternalDecoration } from 'common/services/Services';
export class BufferDecorationRenderer extends Disposable {
@@ -5,7 +5,7 @@
import { ColorZoneStore, IColorZone, IColorZoneStore } from 'browser/decorations/ColorZoneStore';
import { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
const enum Constants {
+17 -23
View File
@@ -6,14 +6,14 @@
import * as Strings from 'browser/LocalizableStrings';
import { CoreBrowserTerminal as TerminalCore } from 'browser/CoreBrowserTerminal';
import { IBufferRange, ITerminal } from 'browser/Types';
import { Disposable } from 'vs/base/common/lifecycle';
import { Disposable } from 'common/Lifecycle';
import { ITerminalOptions } from 'common/Types';
import { AddonManager } from 'common/public/AddonManager';
import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi';
import { ParserApi } from 'common/public/ParserApi';
import { UnicodeApi } from 'common/public/UnicodeApi';
import { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';
import type { Event } from 'vs/base/common/event';
import type { IEvent } from 'common/Event';
/**
* The set of options that only have an effect when set in the Terminal constructor.
@@ -68,26 +68,23 @@ export class Terminal extends Disposable implements ITerminalApi {
}
}
public get onBell(): Event<void> { return this._core.onBell; }
public get onBinary(): Event<string> { return this._core.onBinary; }
public get onCursorMove(): Event<void> { return this._core.onCursorMove; }
public get onData(): Event<string> { return this._core.onData; }
public get onKey(): Event<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }
public get onLineFeed(): Event<void> { return this._core.onLineFeed; }
public get onRender(): Event<{ start: number, end: number }> { return this._core.onRender; }
public get onResize(): Event<{ cols: number, rows: number }> { return this._core.onResize; }
public get onScroll(): Event<number> { return this._core.onScroll; }
public get onSelectionChange(): Event<void> { return this._core.onSelectionChange; }
public get onTitleChange(): Event<string> { return this._core.onTitleChange; }
public get onWriteParsed(): Event<void> { return this._core.onWriteParsed; }
public get onDimensionsChange(): Event<IRenderDimensions> { return this._core.onDimensionsChange; }
public get onBell(): IEvent<void> { return this._core.onBell; }
public get onBinary(): IEvent<string> { return this._core.onBinary; }
public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
public get onData(): IEvent<string> { return this._core.onData; }
public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }
public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }
public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }
public get onScroll(): IEvent<number> { return this._core.onScroll; }
public get onSelectionChange(): IEvent<void> { return this._core.onSelectionChange; }
public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }
public get onWriteParsed(): IEvent<void> { return this._core.onWriteParsed; }
public get onDimensionsChange(): IEvent<IRenderDimensions> { return this._core.onDimensionsChange; }
public get element(): HTMLElement | undefined { return this._core.element; }
public get parser(): IParser {
if (!this._parser) {
this._parser = new ParserApi(this._core);
}
return this._parser;
return this._parser ??= new ParserApi(this._core);
}
public get unicode(): IUnicodeHandling {
this._checkProposedApi();
@@ -97,10 +94,7 @@ export class Terminal extends Disposable implements ITerminalApi {
public get rows(): number { return this._core.rows; }
public get cols(): number { return this._core.cols; }
public get buffer(): IBufferNamespaceApi {
if (!this._buffer) {
this._buffer = this._register(new BufferNamespaceApi(this._core));
}
return this._buffer;
return this._buffer ??= this._register(new BufferNamespaceApi(this._core));
}
public get markers(): ReadonlyArray<IMarker> {
return this._core.markers;
+2 -2
View File
@@ -12,9 +12,9 @@ import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderMode
import { ICharSizeService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from 'browser/Types';
import { color } from 'common/Color';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { IBufferService, ICoreService, IInstantiationService, IOptionsService } from 'common/services/Services';
import { Emitter } from 'vs/base/common/event';
import { Emitter } from 'common/Event';
import { addDisposableListener } from 'vs/base/browser/dom';
@@ -494,8 +494,8 @@ export class DomRendererRowFactory {
// Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from
// non-dim cells
const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);
adjustedColor = color.ensureContrastRatio(bgOverride || bg, fgOverride || fg, ratio);
cache.setColor((bgOverride || bg).rgba, (fgOverride || fg).rgba, adjustedColor ?? null);
adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);
cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);
}
if (adjustedColor) {
@@ -28,7 +28,7 @@ describe('RendererUtils', () => {
line = 2;
variantOffset = 0;
cells = [cellWidth, cellWidth, doubleCellWidth, doubleCellWidth];
result = [3, 2, 0 ,2];
result = [3, 2, 0, 2];
for (let index = 0; index < cells.length; index++) {
const cell = cells[index];
variantOffset = computeNextVariantOffset(cell, line, variantOffset);
+2 -2
View File
@@ -6,7 +6,7 @@
import { Terminal } from '@xterm/xterm';
import { ITerminal } from 'browser/Types';
import { IDisposable } from 'common/Types';
import type { Event } from 'vs/base/common/event';
import type { IEvent } from 'common/Event';
export interface IDimensions {
width: number;
@@ -57,7 +57,7 @@ export interface IRenderer extends IDisposable {
* Fires when the renderer is requesting to be redrawn on the next animation
* frame but is _not_ a result of content changing (eg. selection changes).
*/
readonly onRequestRedraw: Event<IRequestRedrawEvent>;
readonly onRequestRedraw: IEvent<IRequestRedrawEvent>;
dispose(): void;
handleDevicePixelRatioChange(): void;
+2 -2
View File
@@ -5,8 +5,8 @@
import { IOptionsService } from 'common/services/Services';
import { ICharSizeService } from 'browser/services/Services';
import { Disposable } from 'vs/base/common/lifecycle';
import { Emitter } from 'vs/base/common/event';
import { Disposable } from 'common/Lifecycle';
import { Emitter } from 'common/Event';
export class CharSizeService extends Disposable implements ICharSizeService {
public serviceBrand: undefined;
+3 -3
View File
@@ -4,9 +4,9 @@
*/
import { ICoreBrowserService } from './Services';
import { Emitter, Event } from 'vs/base/common/event';
import { Emitter, EventUtils } from 'common/Event';
import { addDisposableListener } from 'vs/base/browser/dom';
import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
export class CoreBrowserService extends Disposable implements ICoreBrowserService {
public serviceBrand: undefined;
@@ -29,7 +29,7 @@ export class CoreBrowserService extends Disposable implements ICoreBrowserServic
// Monitor device pixel ratio
this._register(this.onWindowChange(w => this._screenDprMonitor.setWindow(w)));
this._register(Event.forward(this._screenDprMonitor.onDprChange, this._onDprChange));
this._register(EventUtils.forward(this._screenDprMonitor.onDprChange, this._onDprChange));
this._register(addDisposableListener(this._textarea, 'focus', () => this._isFocused = true));
this._register(addDisposableListener(this._textarea, 'blur', () => this._isFocused = false));
+20 -7
View File
@@ -5,8 +5,8 @@
import { IKeyboardService } from 'browser/services/Services';
import { evaluateKeyboardEvent } from 'common/input/Keyboard';
import { evaluateKeyboardEventKitty, KittyKeyboardEventType, KittyKeyboardFlags, shouldUseKittyProtocol } from 'common/input/KittyKeyboard';
import { evaluateKeyboardEventWin32 } from 'common/input/Win32InputMode';
import { KittyKeyboard, KittyKeyboardEventType, KittyKeyboardFlags } from 'common/input/KittyKeyboard';
import { Win32InputMode } from 'common/input/Win32InputMode';
import { isMac } from 'common/Platform';
import { ICoreService, IOptionsService } from 'common/services/Services';
import { IKeyboardResult } from 'common/Types';
@@ -14,38 +14,51 @@ import { IKeyboardResult } from 'common/Types';
export class KeyboardService implements IKeyboardService {
public serviceBrand: undefined;
private _win32InputMode: Win32InputMode | undefined;
private _kittyKeyboard: KittyKeyboard | undefined;
constructor(
@ICoreService private readonly _coreService: ICoreService,
@IOptionsService private readonly _optionsService: IOptionsService
) {
}
private _getWin32InputMode(): Win32InputMode {
this._win32InputMode ??= new Win32InputMode();
return this._win32InputMode;
}
private _getKittyKeyboard(): KittyKeyboard {
this._kittyKeyboard ??= new KittyKeyboard();
return this._kittyKeyboard;
}
public evaluateKeyDown(event: KeyboardEvent): IKeyboardResult {
// Win32 input mode takes priority (most raw)
if (this.useWin32InputMode) {
return evaluateKeyboardEventWin32(event, true);
return this._getWin32InputMode().evaluateKeyboardEvent(event, true);
}
const kittyFlags = this._coreService.kittyKeyboard.flags;
return this.useKitty
? evaluateKeyboardEventKitty(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS)
? this._getKittyKeyboard().evaluate(event, kittyFlags, event.repeat ? KittyKeyboardEventType.REPEAT : KittyKeyboardEventType.PRESS)
: evaluateKeyboardEvent(event, this._coreService.decPrivateModes.applicationCursorKeys, isMac, this._optionsService.rawOptions.macOptionIsMeta);
}
public evaluateKeyUp(event: KeyboardEvent): IKeyboardResult | undefined {
// Win32 input mode sends key up events
if (this.useWin32InputMode) {
return evaluateKeyboardEventWin32(event, false);
return this._getWin32InputMode().evaluateKeyboardEvent(event, false);
}
const kittyFlags = this._coreService.kittyKeyboard.flags;
if (this.useKitty && (kittyFlags & KittyKeyboardFlags.REPORT_EVENT_TYPES)) {
return evaluateKeyboardEventKitty(event, kittyFlags, KittyKeyboardEventType.RELEASE);
return this._getKittyKeyboard().evaluate(event, kittyFlags, KittyKeyboardEventType.RELEASE);
}
return undefined;
}
public get useKitty(): boolean {
const kittyFlags = this._coreService.kittyKeyboard.flags;
return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && shouldUseKittyProtocol(kittyFlags));
return !!(this._optionsService.rawOptions.vtExtensions?.kittyKeyboard && KittyKeyboard.shouldUseProtocol(kittyFlags));
}
public get useWin32InputMode(): boolean {
+1 -1
View File
@@ -1,5 +1,5 @@
import { ILinkProvider, ILinkProviderService } from 'browser/services/Services';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, toDisposable } from 'common/Lifecycle';
import { IDisposable } from 'common/Types';
export class LinkProviderService extends Disposable implements ILinkProviderService {
+7 -9
View File
@@ -7,10 +7,10 @@ import { RenderDebouncer } from 'browser/RenderDebouncer';
import { IRenderDebouncerWithCallback } from 'browser/Types';
import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types';
import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, MutableDisposable, toDisposable } from 'common/Lifecycle';
import { DebouncedIdleTask } from 'common/TaskQueue';
import { IBufferService, ICoreService, IDecorationService, IOptionsService } from 'common/services/Services';
import { Emitter } from 'vs/base/common/event';
import { Emitter } from 'common/Event';
interface ISelectionState {
start: [number, number] | undefined;
@@ -347,13 +347,11 @@ class SynchronizedOutputHandler {
this._end = Math.max(this._end, end);
}
if (this._timeout === undefined) {
this._timeout = this._coreBrowserService.window.setTimeout(() => {
this._timeout = undefined;
this._coreService.decPrivateModes.synchronizedOutput = false;
this._onTimeout();
}, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);
}
this._timeout ??= this._coreBrowserService.window.setTimeout(() => {
this._timeout = undefined;
this._coreService.decPrivateModes.synchronizedOutput = false;
this._onTimeout();
}, Constants.SYNCHRONIZED_OUTPUT_TIMEOUT_MS);
}
public flush(): { start: number, end: number } | undefined {
+2 -2
View File
@@ -9,14 +9,14 @@ import { moveToCellSequence } from 'browser/input/MoveToCell';
import { SelectionModel } from 'browser/selection/SelectionModel';
import { ISelectionRedrawRequestEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types';
import { ICoreBrowserService, IMouseService, IRenderService, ISelectionService } from 'browser/services/Services';
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable, toDisposable } from 'common/Lifecycle';
import * as Browser from 'common/Platform';
import { IBufferLine, IDisposable } from 'common/Types';
import { getRangeLength } from 'common/buffer/BufferRange';
import { CellData } from 'common/buffer/CellData';
import { IBuffer } from 'common/buffer/Types';
import { IBufferService, ICoreService, IOptionsService } from 'common/services/Services';
import { Emitter } from 'vs/base/common/event';
import { Emitter } from 'common/Event';
/**
* The number of pixels the mouse needs to be above or below the viewport in
+13 -13
View File
@@ -8,7 +8,7 @@ import { IColorSet, ILink, ReadonlyColorSet } from 'browser/Types';
import { ISelectionRedrawRequestEvent as ISelectionRequestRedrawEvent, ISelectionRequestScrollLinesEvent } from 'browser/selection/Types';
import { createDecorator } from 'common/services/ServiceRegistry';
import { AllColorIndex, IDisposable, IKeyboardResult } from 'common/Types';
import type { Event } from 'vs/base/common/event';
import type { IEvent } from 'common/Event';
export const ICharSizeService = createDecorator<ICharSizeService>('CharSizeService');
export interface ICharSizeService {
@@ -18,7 +18,7 @@ export interface ICharSizeService {
readonly height: number;
readonly hasValidSize: boolean;
readonly onCharSizeChange: Event<void>;
readonly onCharSizeChange: IEvent<void>;
measure(): void;
}
@@ -29,8 +29,8 @@ export interface ICoreBrowserService {
readonly isFocused: boolean;
readonly onDprChange: Event<number>;
readonly onWindowChange: Event<Window & typeof globalThis>;
readonly onDprChange: IEvent<number>;
readonly onWindowChange: IEvent<Window & typeof globalThis>;
/**
* Gets or sets the parent window that the terminal is rendered into. DOM and rendering APIs (e.g.
@@ -61,17 +61,17 @@ export const IRenderService = createDecorator<IRenderService>('RenderService');
export interface IRenderService extends IDisposable {
serviceBrand: undefined;
onDimensionsChange: Event<IRenderDimensions>;
onDimensionsChange: IEvent<IRenderDimensions>;
/**
* Fires when buffer changes are rendered. This does not fire when only cursor
* or selections are rendered.
*/
onRenderedViewportChange: Event<{ start: number, end: number }>;
onRenderedViewportChange: IEvent<{ start: number, end: number }>;
/**
* Fires on render
*/
onRender: Event<{ start: number, end: number }>;
onRefreshRequest: Event<{ start: number, end: number }>;
onRender: IEvent<{ start: number, end: number }>;
onRefreshRequest: IEvent<{ start: number, end: number }>;
dimensions: IRenderDimensions;
@@ -101,10 +101,10 @@ export interface ISelectionService {
readonly selectionStart: [number, number] | undefined;
readonly selectionEnd: [number, number] | undefined;
readonly onLinuxMouseSelection: Event<string>;
readonly onRequestRedraw: Event<ISelectionRequestRedrawEvent>;
readonly onRequestScrollLines: Event<ISelectionRequestScrollLinesEvent>;
readonly onSelectionChange: Event<void>;
readonly onLinuxMouseSelection: IEvent<string>;
readonly onRequestRedraw: IEvent<ISelectionRequestRedrawEvent>;
readonly onRequestScrollLines: IEvent<ISelectionRequestScrollLinesEvent>;
readonly onSelectionChange: IEvent<void>;
disable(): void;
enable(): void;
@@ -136,7 +136,7 @@ export interface IThemeService {
readonly colors: ReadonlyColorSet;
readonly onChangeColors: Event<ReadonlyColorSet>;
readonly onChangeColors: IEvent<ReadonlyColorSet>;
restoreColor(slot?: AllColorIndex): void;
/**
+2 -2
View File
@@ -7,10 +7,10 @@ import { ColorContrastCache } from 'browser/ColorContrastCache';
import { IThemeService } from 'browser/services/Services';
import { DEFAULT_ANSI_COLORS, IColorContrastCache, IColorSet, ReadonlyColorSet } from 'browser/Types';
import { color, css, NULL_COLOR } from 'common/Color';
import { Disposable } from 'vs/base/common/lifecycle';
import { Disposable } from 'common/Lifecycle';
import { IOptionsService, ITheme } from 'common/services/Services';
import { AllColorIndex, IColor, SpecialColorIndex } from 'common/Types';
import { Emitter } from 'vs/base/common/event';
import { Emitter } from 'common/Event';
interface IRestoreColorSet {
foreground: IColor;