mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
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 {
|
||||
if (!terminal.element) {
|
||||
throw new Error('Cannot activate WebglAddon before Terminal.open');
|
||||
(terminal as any)._core.onWillOpen(() => this.activate(terminal));
|
||||
return;
|
||||
}
|
||||
if (isSafari) {
|
||||
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://';
|
||||
socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/terminals/';
|
||||
|
||||
term.open(terminalContainer);
|
||||
addons.fit.instance!.fit();
|
||||
try {
|
||||
typedTerm.loadAddon(addons.webgl.instance);
|
||||
setTimeout(() => {
|
||||
addTextureAtlas(addons.webgl.instance.textureAtlas);
|
||||
addons.webgl.instance.onChangeTextureAtlas(e => addTextureAtlas(e));
|
||||
}, 0);
|
||||
}
|
||||
catch {
|
||||
addons.webgl.instance = undefined;
|
||||
}
|
||||
typedTerm.loadAddon(addons.webgl.instance);
|
||||
setTimeout(() => {
|
||||
addTextureAtlas(addons.webgl.instance.textureAtlas);
|
||||
addons.webgl.instance.onChangeTextureAtlas(e => addTextureAtlas(e));
|
||||
}, 0);
|
||||
|
||||
term.open(terminalContainer);
|
||||
term.focus();
|
||||
|
||||
addDomListener(paddingElement, 'change', setPadding);
|
||||
|
||||
@@ -143,6 +143,9 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
public get onA11yChar(): IEvent<string> { return this._onA11yCharEmitter.event; }
|
||||
private _onA11yTabEmitter = new EventEmitter<number>();
|
||||
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.
|
||||
@@ -509,12 +512,16 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);
|
||||
this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);
|
||||
|
||||
const renderer = this._createRenderer();
|
||||
this._renderService = this.register(this._instantiationService.createInstance(RenderService, renderer, this.rows, this.screenElement));
|
||||
this._renderService = this.register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));
|
||||
this._instantiationService.setService(IRenderService, this._renderService);
|
||||
this.register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));
|
||||
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.classList.add('composition-view');
|
||||
this._compositionHelper = this._instantiationService.createInstance(CompositionHelper, this.textarea, this._compositionView);
|
||||
|
||||
@@ -41,6 +41,7 @@ export class MockTerminal implements ITerminal {
|
||||
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 }>;
|
||||
@@ -400,6 +401,9 @@ export class MockRenderService implements IRenderService {
|
||||
public resize(cols: number, rows: number): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
public hasRenderer(): boolean {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
public setRenderer(renderer: IRenderer): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -23,6 +23,7 @@ export interface ITerminal extends IPublicTerminal, ICoreTerminal {
|
||||
onFocus: IEvent<void>;
|
||||
onA11yChar: IEvent<string>;
|
||||
onA11yTab: IEvent<number>;
|
||||
onWillOpen: IEvent<HTMLElement>;
|
||||
|
||||
cancel(ev: Event, force?: boolean): boolean | void;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ interface ISelectionState {
|
||||
export class RenderService extends Disposable implements IRenderService {
|
||||
public serviceBrand: undefined;
|
||||
|
||||
private _renderer: IRenderer | undefined;
|
||||
private _renderDebouncer: IRenderDebouncerWithCallback;
|
||||
private _screenDprMonitor: ScreenDprMonitor;
|
||||
private _pausedResizeTask = new DebouncedIdleTask();
|
||||
@@ -48,10 +49,9 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
private _onRefreshRequest = new EventEmitter<{ start: number, end: number }>();
|
||||
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(
|
||||
private _renderer: IRenderer,
|
||||
private _rowCount: number,
|
||||
screenElement: HTMLElement,
|
||||
@IOptionsService optionsService: IOptionsService,
|
||||
@@ -62,7 +62,7 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
) {
|
||||
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.register(this._renderDebouncer);
|
||||
@@ -83,7 +83,7 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
this.register(decorationService.onDecorationRemoved(() => this._fullRefresh()));
|
||||
|
||||
// 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
|
||||
// matchMedia query.
|
||||
@@ -125,6 +125,9 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
}
|
||||
|
||||
private _renderRows(start: number, end: number): void {
|
||||
if (!this._renderer) {
|
||||
return;
|
||||
}
|
||||
this._renderer.renderRows(start, end);
|
||||
|
||||
// Update selection if needed
|
||||
@@ -147,12 +150,18 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
}
|
||||
|
||||
private _handleOptionsChanged(): void {
|
||||
if (!this._renderer) {
|
||||
return;
|
||||
}
|
||||
this._renderer.onOptionsChanged();
|
||||
this.refreshRows(0, this._rowCount - 1);
|
||||
this._fireOnCanvasResize();
|
||||
}
|
||||
|
||||
private _fireOnCanvasResize(): void {
|
||||
if (!this._renderer) {
|
||||
return;
|
||||
}
|
||||
// Don't fire the event if the dimensions haven't changed
|
||||
if (this._renderer.dimensions.canvasWidth === this._canvasWidth && this._renderer.dimensions.canvasHeight === this._canvasHeight) {
|
||||
return;
|
||||
@@ -164,9 +173,13 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
public hasRenderer(): boolean {
|
||||
return !!this._renderer;
|
||||
}
|
||||
|
||||
public setRenderer(renderer: IRenderer): void {
|
||||
// TODO: RenderService should be the only one to dispose the renderer
|
||||
this._renderer.dispose();
|
||||
this._renderer?.dispose();
|
||||
this._renderer = renderer;
|
||||
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 {
|
||||
this._renderer?.clearTextureAtlas?.();
|
||||
if (!this._renderer) {
|
||||
return;
|
||||
}
|
||||
this._renderer.clearTextureAtlas?.();
|
||||
this._fullRefresh();
|
||||
}
|
||||
|
||||
public setColors(colors: IColorSet): void {
|
||||
if (!this._renderer) {
|
||||
return;
|
||||
}
|
||||
this._renderer.setColors(colors);
|
||||
this._fullRefresh();
|
||||
}
|
||||
@@ -202,13 +221,19 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
// when devicePixelRatio changes
|
||||
this._charSizeService.measure();
|
||||
|
||||
if (!this._renderer) {
|
||||
return;
|
||||
}
|
||||
this._renderer.onDevicePixelRatioChange();
|
||||
this.refreshRows(0, this._rowCount - 1);
|
||||
}
|
||||
|
||||
public onResize(cols: number, rows: number): void {
|
||||
if (!this._renderer) {
|
||||
return;
|
||||
}
|
||||
if (this._isPaused) {
|
||||
this._pausedResizeTask.set(() => this._renderer.onResize(cols, rows));
|
||||
this._pausedResizeTask.set(() => this._renderer!.onResize(cols, rows));
|
||||
} else {
|
||||
this._renderer.onResize(cols, rows);
|
||||
}
|
||||
@@ -217,29 +242,29 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
|
||||
// TODO: Is this useful when we have onResize?
|
||||
public onCharSizeChanged(): void {
|
||||
this._renderer.onCharSizeChanged();
|
||||
this._renderer?.onCharSizeChanged();
|
||||
}
|
||||
|
||||
public onBlur(): void {
|
||||
this._renderer.onBlur();
|
||||
this._renderer?.onBlur();
|
||||
}
|
||||
|
||||
public onFocus(): void {
|
||||
this._renderer.onFocus();
|
||||
this._renderer?.onFocus();
|
||||
}
|
||||
|
||||
public onSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {
|
||||
this._selectionState.start = start;
|
||||
this._selectionState.end = end;
|
||||
this._selectionState.columnSelectMode = columnSelectMode;
|
||||
this._renderer.onSelectionChanged(start, end, columnSelectMode);
|
||||
this._renderer?.onSelectionChanged(start, end, columnSelectMode);
|
||||
}
|
||||
|
||||
public onCursorMove(): void {
|
||||
this._renderer.onCursorMove();
|
||||
this._renderer?.onCursorMove();
|
||||
}
|
||||
|
||||
public clear(): void {
|
||||
this._renderer.clear();
|
||||
this._renderer?.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ export interface IRenderService extends IDisposable {
|
||||
refreshRows(start: number, end: number): void;
|
||||
clearTextureAtlas(): void;
|
||||
resize(cols: number, rows: number): void;
|
||||
hasRenderer(): boolean;
|
||||
setRenderer(renderer: IRenderer): void;
|
||||
setColors(colors: IColorSet): void;
|
||||
onDevicePixelRatioChange(): void;
|
||||
|
||||
Reference in New Issue
Block a user