Allow setting renderer addon before open is called
This commit is contained in:
@@ -26,7 +26,8 @@ export class WebglAddon implements ITerminalAddon {
|
|||||||
|
|
||||||
public activate(terminal: Terminal): void {
|
public activate(terminal: Terminal): void {
|
||||||
if (!terminal.element) {
|
if (!terminal.element) {
|
||||||
throw new Error('Cannot activate WebglAddon before Terminal.open');
|
(terminal as any)._core.onWillOpen(() => this.activate(terminal));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (isSafari) {
|
if (isSafari) {
|
||||||
throw new Error('Webgl is not currently supported on Safari');
|
throw new Error('Webgl is not currently supported on Safari');
|
||||||
|
|||||||
+7
-11
@@ -267,18 +267,14 @@ function createTerminal(): void {
|
|||||||
protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
|
protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
|
||||||
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';
|
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';
|
||||||
|
|
||||||
term.open(terminalContainer);
|
|
||||||
addons.fit.instance!.fit();
|
addons.fit.instance!.fit();
|
||||||
try {
|
typedTerm.loadAddon(addons.webgl.instance);
|
||||||
typedTerm.loadAddon(addons.webgl.instance);
|
setTimeout(() => {
|
||||||
setTimeout(() => {
|
addTextureAtlas(addons.webgl.instance.textureAtlas);
|
||||||
addTextureAtlas(addons.webgl.instance.textureAtlas);
|
addons.webgl.instance.onChangeTextureAtlas(e => addTextureAtlas(e));
|
||||||
addons.webgl.instance.onChangeTextureAtlas(e => addTextureAtlas(e));
|
}, 0);
|
||||||
}, 0);
|
|
||||||
}
|
term.open(terminalContainer);
|
||||||
catch {
|
|
||||||
addons.webgl.instance = undefined;
|
|
||||||
}
|
|
||||||
term.focus();
|
term.focus();
|
||||||
|
|
||||||
addDomListener(paddingElement, 'change', setPadding);
|
addDomListener(paddingElement, 'change', setPadding);
|
||||||
|
|||||||
@@ -143,6 +143,9 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
public get onA11yChar(): IEvent<string> { return this._onA11yCharEmitter.event; }
|
public get onA11yChar(): IEvent<string> { return this._onA11yCharEmitter.event; }
|
||||||
private _onA11yTabEmitter = new EventEmitter<number>();
|
private _onA11yTabEmitter = new EventEmitter<number>();
|
||||||
public get onA11yTab(): IEvent<number> { return this._onA11yTabEmitter.event; }
|
public get onA11yTab(): IEvent<number> { return this._onA11yTabEmitter.event; }
|
||||||
|
private _onWillOpen = new EventEmitter<HTMLElement>();
|
||||||
|
public get onWillOpen(): IEvent<HTMLElement> { return this._onWillOpen.event; }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new `Terminal` object.
|
* Creates a new `Terminal` object.
|
||||||
@@ -509,12 +512,16 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
|||||||
this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);
|
this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);
|
||||||
this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);
|
this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);
|
||||||
|
|
||||||
const renderer = this._createRenderer();
|
this._renderService = this.register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));
|
||||||
this._renderService = this.register(this._instantiationService.createInstance(RenderService, renderer, this.rows, this.screenElement));
|
|
||||||
this._instantiationService.setService(IRenderService, this._renderService);
|
this._instantiationService.setService(IRenderService, this._renderService);
|
||||||
this.register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));
|
this.register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));
|
||||||
this.onResize(e => this._renderService!.resize(e.cols, e.rows));
|
this.onResize(e => this._renderService!.resize(e.cols, e.rows));
|
||||||
|
|
||||||
|
this._onWillOpen.fire(this.element);
|
||||||
|
if (!this._renderService.hasRenderer()) {
|
||||||
|
this._renderService.setRenderer(this._createRenderer());
|
||||||
|
}
|
||||||
|
|
||||||
this._compositionView = document.createElement('div');
|
this._compositionView = document.createElement('div');
|
||||||
this._compositionView.classList.add('composition-view');
|
this._compositionView.classList.add('composition-view');
|
||||||
this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);
|
this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export class MockTerminal implements ITerminal {
|
|||||||
public onTitleChange!: IEvent<string>;
|
public onTitleChange!: IEvent<string>;
|
||||||
public onBell!: IEvent<void>;
|
public onBell!: IEvent<void>;
|
||||||
public onScroll!: IEvent<number>;
|
public onScroll!: IEvent<number>;
|
||||||
|
public onWillOpen!: IEvent<HTMLElement>;
|
||||||
public onKey!: IEvent<{ key: string, domEvent: KeyboardEvent }>;
|
public onKey!: IEvent<{ key: string, domEvent: KeyboardEvent }>;
|
||||||
public onRender!: IEvent<{ start: number, end: number }>;
|
public onRender!: IEvent<{ start: number, end: number }>;
|
||||||
public onResize!: IEvent<{ cols: number, rows: number }>;
|
public onResize!: IEvent<{ cols: number, rows: number }>;
|
||||||
@@ -400,6 +401,9 @@ export class MockRenderService implements IRenderService {
|
|||||||
public resize(cols: number, rows: number): void {
|
public resize(cols: number, rows: number): void {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
public hasRenderer(): boolean {
|
||||||
|
throw new Error('Method not implemented.');
|
||||||
|
}
|
||||||
public setRenderer(renderer: IRenderer): void {
|
public setRenderer(renderer: IRenderer): void {
|
||||||
throw new Error('Method not implemented.');
|
throw new Error('Method not implemented.');
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
@@ -23,6 +23,7 @@ export interface ITerminal extends IPublicTerminal, ICoreTerminal {
|
|||||||
onFocus: IEvent<void>;
|
onFocus: IEvent<void>;
|
||||||
onA11yChar: IEvent<string>;
|
onA11yChar: IEvent<string>;
|
||||||
onA11yTab: IEvent<number>;
|
onA11yTab: IEvent<number>;
|
||||||
|
onWillOpen: IEvent<HTMLElement>;
|
||||||
|
|
||||||
cancel(ev: Event, force?: boolean): boolean | void;
|
cancel(ev: Event, force?: boolean): boolean | void;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ interface ISelectionState {
|
|||||||
export class RenderService extends Disposable implements IRenderService {
|
export class RenderService extends Disposable implements IRenderService {
|
||||||
public serviceBrand: undefined;
|
public serviceBrand: undefined;
|
||||||
|
|
||||||
|
private _renderer: IRenderer | undefined;
|
||||||
private _renderDebouncer: IRenderDebouncerWithCallback;
|
private _renderDebouncer: IRenderDebouncerWithCallback;
|
||||||
private _screenDprMonitor: ScreenDprMonitor;
|
private _screenDprMonitor: ScreenDprMonitor;
|
||||||
private _pausedResizeTask = new DebouncedIdleTask();
|
private _pausedResizeTask = new DebouncedIdleTask();
|
||||||
@@ -48,10 +49,9 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
private _onRefreshRequest = new EventEmitter<{ start: number, end: number }>();
|
private _onRefreshRequest = new EventEmitter<{ start: number, end: number }>();
|
||||||
public get onRefreshRequest(): IEvent<{ start: number, end: number }> { return this._onRefreshRequest.event; }
|
public get onRefreshRequest(): IEvent<{ start: number, end: number }> { return this._onRefreshRequest.event; }
|
||||||
|
|
||||||
public get dimensions(): IRenderDimensions { return this._renderer.dimensions; }
|
public get dimensions(): IRenderDimensions { return this._renderer!.dimensions; }
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private _renderer: IRenderer,
|
|
||||||
private _rowCount: number,
|
private _rowCount: number,
|
||||||
screenElement: HTMLElement,
|
screenElement: HTMLElement,
|
||||||
@IOptionsService optionsService: IOptionsService,
|
@IOptionsService optionsService: IOptionsService,
|
||||||
@@ -62,7 +62,7 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.register({ dispose: () => this._renderer.dispose() });
|
this.register({ dispose: () => this._renderer?.dispose() });
|
||||||
|
|
||||||
this._renderDebouncer = new RenderDebouncer(coreBrowserService.window, (start, end) => this._renderRows(start, end));
|
this._renderDebouncer = new RenderDebouncer(coreBrowserService.window, (start, end) => this._renderRows(start, end));
|
||||||
this.register(this._renderDebouncer);
|
this.register(this._renderDebouncer);
|
||||||
@@ -83,7 +83,7 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
this.register(decorationService.onDecorationRemoved(() => this._fullRefresh()));
|
this.register(decorationService.onDecorationRemoved(() => this._fullRefresh()));
|
||||||
|
|
||||||
// No need to register this as renderer is explicitly disposed in RenderService.dispose
|
// No need to register this as renderer is explicitly disposed in RenderService.dispose
|
||||||
this._renderer.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
|
// this._renderer.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
|
||||||
|
|
||||||
// dprchange should handle this case, we need this as well for browsers that don't support the
|
// dprchange should handle this case, we need this as well for browsers that don't support the
|
||||||
// matchMedia query.
|
// matchMedia query.
|
||||||
@@ -125,6 +125,9 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _renderRows(start: number, end: number): void {
|
private _renderRows(start: number, end: number): void {
|
||||||
|
if (!this._renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._renderer.renderRows(start, end);
|
this._renderer.renderRows(start, end);
|
||||||
|
|
||||||
// Update selection if needed
|
// Update selection if needed
|
||||||
@@ -147,12 +150,18 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleOptionsChanged(): void {
|
private _handleOptionsChanged(): void {
|
||||||
|
if (!this._renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._renderer.onOptionsChanged();
|
this._renderer.onOptionsChanged();
|
||||||
this.refreshRows(0, this._rowCount - 1);
|
this.refreshRows(0, this._rowCount - 1);
|
||||||
this._fireOnCanvasResize();
|
this._fireOnCanvasResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _fireOnCanvasResize(): void {
|
private _fireOnCanvasResize(): void {
|
||||||
|
if (!this._renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Don't fire the event if the dimensions haven't changed
|
// Don't fire the event if the dimensions haven't changed
|
||||||
if (this._renderer.dimensions.canvasWidth === this._canvasWidth && this._renderer.dimensions.canvasHeight === this._canvasHeight) {
|
if (this._renderer.dimensions.canvasWidth === this._canvasWidth && this._renderer.dimensions.canvasHeight === this._canvasHeight) {
|
||||||
return;
|
return;
|
||||||
@@ -164,9 +173,13 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public hasRenderer(): boolean {
|
||||||
|
return !!this._renderer;
|
||||||
|
}
|
||||||
|
|
||||||
public setRenderer(renderer: IRenderer): void {
|
public setRenderer(renderer: IRenderer): void {
|
||||||
// TODO: RenderService should be the only one to dispose the renderer
|
// TODO: RenderService should be the only one to dispose the renderer
|
||||||
this._renderer.dispose();
|
this._renderer?.dispose();
|
||||||
this._renderer = renderer;
|
this._renderer = renderer;
|
||||||
this._renderer.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
|
this._renderer.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
|
||||||
|
|
||||||
@@ -188,11 +201,17 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public clearTextureAtlas(): void {
|
public clearTextureAtlas(): void {
|
||||||
this._renderer?.clearTextureAtlas?.();
|
if (!this._renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._renderer.clearTextureAtlas?.();
|
||||||
this._fullRefresh();
|
this._fullRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public setColors(colors: IColorSet): void {
|
public setColors(colors: IColorSet): void {
|
||||||
|
if (!this._renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._renderer.setColors(colors);
|
this._renderer.setColors(colors);
|
||||||
this._fullRefresh();
|
this._fullRefresh();
|
||||||
}
|
}
|
||||||
@@ -202,13 +221,19 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
// when devicePixelRatio changes
|
// when devicePixelRatio changes
|
||||||
this._charSizeService.measure();
|
this._charSizeService.measure();
|
||||||
|
|
||||||
|
if (!this._renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this._renderer.onDevicePixelRatioChange();
|
this._renderer.onDevicePixelRatioChange();
|
||||||
this.refreshRows(0, this._rowCount - 1);
|
this.refreshRows(0, this._rowCount - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onResize(cols: number, rows: number): void {
|
public onResize(cols: number, rows: number): void {
|
||||||
|
if (!this._renderer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (this._isPaused) {
|
if (this._isPaused) {
|
||||||
this._pausedResizeTask.set(() => this._renderer.onResize(cols, rows));
|
this._pausedResizeTask.set(() => this._renderer!.onResize(cols, rows));
|
||||||
} else {
|
} else {
|
||||||
this._renderer.onResize(cols, rows);
|
this._renderer.onResize(cols, rows);
|
||||||
}
|
}
|
||||||
@@ -217,29 +242,29 @@ export class RenderService extends Disposable implements IRenderService {
|
|||||||
|
|
||||||
// TODO: Is this useful when we have onResize?
|
// TODO: Is this useful when we have onResize?
|
||||||
public onCharSizeChanged(): void {
|
public onCharSizeChanged(): void {
|
||||||
this._renderer.onCharSizeChanged();
|
this._renderer?.onCharSizeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onBlur(): void {
|
public onBlur(): void {
|
||||||
this._renderer.onBlur();
|
this._renderer?.onBlur();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onFocus(): void {
|
public onFocus(): void {
|
||||||
this._renderer.onFocus();
|
this._renderer?.onFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {
|
public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {
|
||||||
this._selectionState.start = start;
|
this._selectionState.start = start;
|
||||||
this._selectionState.end = end;
|
this._selectionState.end = end;
|
||||||
this._selectionState.columnSelectMode = columnSelectMode;
|
this._selectionState.columnSelectMode = columnSelectMode;
|
||||||
this._renderer.onSelectionChanged(start, end, columnSelectMode);
|
this._renderer?.onSelectionChanged(start, end, columnSelectMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public onCursorMove(): void {
|
public onCursorMove(): void {
|
||||||
this._renderer.onCursorMove();
|
this._renderer?.onCursorMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
public clear(): void {
|
public clear(): void {
|
||||||
this._renderer.clear();
|
this._renderer?.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ export interface IRenderService extends IDisposable {
|
|||||||
refreshRows(start: number, end: number): void;
|
refreshRows(start: number, end: number): void;
|
||||||
clearTextureAtlas(): void;
|
clearTextureAtlas(): void;
|
||||||
resize(cols: number, rows: number): void;
|
resize(cols: number, rows: number): void;
|
||||||
|
hasRenderer(): boolean;
|
||||||
setRenderer(renderer: IRenderer): void;
|
setRenderer(renderer: IRenderer): void;
|
||||||
setColors(colors: IColorSet): void;
|
setColors(colors: IColorSet): void;
|
||||||
onDevicePixelRatioChange(): void;
|
onDevicePixelRatioChange(): void;
|
||||||
|
|||||||
Reference in New Issue
Block a user