Merge pull request #3637 from meganrogge/master

polish decorations
This commit is contained in:
Megan Rogge
2022-02-11 17:19:34 -06:00
committed by GitHub
2 changed files with 33 additions and 25 deletions
+32 -25
View File
@@ -16,11 +16,7 @@ export class DecorationService extends Disposable implements IDecorationService
private _screenElement: HTMLElement | undefined;
private _renderService: IRenderService | undefined;
constructor(
@IBufferService private readonly _bufferService: IBufferService,
@IInstantiationService private readonly _instantiationService: IInstantiationService) {
super();
}
constructor(@IInstantiationService private readonly _instantiationService: IInstantiationService) { super(); }
public attachToDom(screenElement: HTMLElement, renderService: IRenderService): void {
this._renderService = renderService;
@@ -28,7 +24,6 @@ export class DecorationService extends Disposable implements IDecorationService
this._container = document.createElement('div');
this._container.classList.add('xterm-decoration-container');
screenElement.appendChild(this._container);
this.refresh();
this.register(this._renderService.onRenderedBufferChange(() => this.refresh()));
this.register(this._renderService.onDimensionsChange(() => this.refresh(true)));
}
@@ -43,12 +38,12 @@ export class DecorationService extends Disposable implements IDecorationService
return decoration;
}
public refresh(recreate?: boolean): void {
if (!this._bufferService || !this._renderService) {
public refresh(shouldRecreate?: boolean): void {
if (!this._renderService) {
return;
}
for (const decoration of this._decorations) {
decoration.render(this._renderService, recreate);
decoration.render(this._renderService, shouldRecreate);
}
}
@@ -56,16 +51,16 @@ export class DecorationService extends Disposable implements IDecorationService
for (const decoration of this._decorations) {
decoration.dispose();
}
if (this._container) {
this._screenElement?.removeChild(this._container);
if (this._screenElement && this._container && this._screenElement.contains(this._container)) {
this._screenElement.removeChild(this._container);
}
}
}
export class Decoration extends Disposable implements IDecoration {
private static _nextId = 1;
private readonly _marker: IMarker;
private _element: HTMLElement | undefined;
private readonly _id: number = Decoration._nextId++;
private _altBufferActive: boolean = false;
public isDisposed: boolean = false;
public get element(): HTMLElement | undefined { return this._element; }
@@ -90,24 +85,28 @@ export class Decoration extends Disposable implements IDecoration {
super();
this.x = options.x ?? 0;
this._marker = options.marker;
this._marker.onDispose(() => this.dispose());
this.anchor = options.anchor || 'left';
this.width = options.width || 1;
this.height = options.height || 1;
this.register(this._bufferService.buffers.onBufferActivate((event) => this._altBufferActive = event.activeBuffer === this._bufferService.buffers.alt));
}
public render(renderService: IRenderService, recreate?: boolean): void {
if (!this._element || recreate) {
this._createElement(renderService, recreate);
public render(renderService: IRenderService, shouldRecreate?: boolean): void {
if (!this._element || shouldRecreate) {
this._createElement(renderService, shouldRecreate);
}
if (this._container && this._element && !this._container.contains(this._element)) {
this._container.append(this._element);
}
this._refreshStyle(renderService);
this._onRender.fire(this._element!);
if (this._element) {
this._onRender.fire(this._element);
}
}
private _createElement(renderService: IRenderService, recreate?: boolean): void {
if (recreate && this._element) {
private _createElement(renderService: IRenderService, shouldRecreate?: boolean): void {
if (shouldRecreate && this._element && this._container.contains(this._element)) {
this._container.removeChild(this._element);
}
this._element = document.createElement('div');
@@ -117,7 +116,8 @@ export class Decoration extends Disposable implements IDecoration {
this._element.style.top = `${(this.marker.line - this._bufferService.buffers.active.ydisp) * renderService.dimensions.scaledCellHeight}px`;
if (this.x && this.x > this._bufferService.cols) {
this._element!.style.display = 'none';
// exceeded the container width, so hide
this._element.style.display = 'none';
}
if (this.anchor === 'right') {
this._element.style.right = this.x ? `${this.x * renderService.dimensions.scaledCellWidth}px` : '';
@@ -129,9 +129,13 @@ export class Decoration extends Disposable implements IDecoration {
if (this.isDisposed) {
return;
}
this._container.removeChild(this._element!);
if (!this.marker.isDisposed) {
this.marker.dispose();
}
if (this._element && this._container.contains(this._element)) {
this._container.removeChild(this._element);
}
this.isDisposed = true;
this._marker.dispose();
// Emit before super.dispose such that dispose listeners get a change to react
this._onDispose.fire();
super.dispose();
@@ -140,13 +144,16 @@ export class Decoration extends Disposable implements IDecoration {
}
private _refreshStyle(renderService: IRenderService): void {
if (!this._element) {
return;
}
const line = this.marker.line - this._bufferService.buffers.active.ydisp;
if (line < 0 || line > this._bufferService.rows) {
// outside of viewport
this._element!.style.display = 'none';
this._element.style.display = 'none';
} else {
this._element!.style.top = `${line * renderService.dimensions.scaledCellHeight}px`;
this._element!.style.display = 'block';
this._element.style.top = `${line * renderService.dimensions.scaledCellHeight}px`;
this._element.style.display = this._altBufferActive ? 'none' : 'block';
}
}
}
+1
View File
@@ -1292,6 +1292,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._resetBufferLine(j);
}
this._dirtyRowService.markDirty(0);
this._bufferService.buffer.clearMarkers();
break;
case 3:
// Clear scrollback (everything not in viewport)