Skip to content

Commit

Permalink
Merge pull request #4837 from tisilent/fix-dom-renderer-selection
Browse files Browse the repository at this point in the history
handle selection when resizing
  • Loading branch information
Tyriar committed Nov 2, 2023
2 parents 139bf36 + b6a09d6 commit 4036ab7
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 17 deletions.
2 changes: 1 addition & 1 deletion addons/addon-canvas/src/BaseRenderLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
public handleGridChanged(startRow: number, endRow: number): void {}

public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {
this._selectionModel.update(this._terminal, start, end, columnSelectMode);
this._selectionModel.update((this._terminal as any)._core, start, end, columnSelectMode);
}

protected _setTransparency(alpha: boolean): void {
Expand Down
2 changes: 1 addition & 1 deletion addons/addon-webgl/src/WebglRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
for (const l of this._renderLayers) {
l.handleSelectionChanged(this._terminal, start, end, columnSelectMode);
}
this._model.selection.update(this._terminal, start, end, columnSelectMode);
this._model.selection.update(this._core, start, end, columnSelectMode);
this._requestRedrawViewport();
}

Expand Down
2 changes: 1 addition & 1 deletion src/browser/Terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
}

private _createRenderer(): IRenderer {
return this._instantiationService.createInstance(DomRenderer, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier2);
return this._instantiationService.createInstance(DomRenderer, this, this._document!, this.element!, this.screenElement!, this._viewportElement!, this._helperContainer!, this.linkifier2);
}

/**
Expand Down
29 changes: 20 additions & 9 deletions src/browser/renderer/dom/DomRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { DomRendererRowFactory, RowCss } from 'browser/renderer/dom/DomRendererR
import { WidthCache } from 'browser/renderer/dom/WidthCache';
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types';
import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRenderModel';
import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from 'browser/renderer/shared/Types';
import { ICharSizeService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
import { ILinkifier2, ILinkifierEvent, ReadonlyColorSet } from 'browser/Types';
import { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from 'browser/Types';
import { color } from 'common/Color';
import { EventEmitter } from 'common/EventEmitter';
import { Disposable, toDisposable } from 'common/Lifecycle';
Expand All @@ -25,7 +26,6 @@ const SELECTION_CLASS = 'xterm-selection';

let nextTerminalId = 1;


/**
* A fallback renderer for when canvas is slow. This is not meant to be
* particularly fast or feature complete, more just stable and usable for when
Expand All @@ -41,12 +41,14 @@ export class DomRenderer extends Disposable implements IRenderer {
private _rowElements: HTMLElement[] = [];
private _selectionContainer: HTMLElement;
private _widthCache: WidthCache;
private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();

public dimensions: IRenderDimensions;

public readonly onRequestRedraw = this.register(new EventEmitter<IRequestRedrawEvent>()).event;

constructor(
private readonly _terminal: ITerminal,
private readonly _document: Document,
private readonly _element: HTMLElement,
private readonly _screenElement: HTMLElement,
Expand Down Expand Up @@ -291,6 +293,7 @@ export class DomRenderer extends Disposable implements IRenderer {
public handleResize(cols: number, rows: number): void {
this._refreshRowElements(cols, rows);
this._updateDimensions();
this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode);
}

public handleCharSizeChanged(): void {
Expand Down Expand Up @@ -320,11 +323,13 @@ export class DomRenderer extends Disposable implements IRenderer {
return;
}

this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);

// Translate from buffer position to viewport position
const viewportStartRow = start[1] - this._bufferService.buffer.ydisp;
const viewportEndRow = end[1] - this._bufferService.buffer.ydisp;
const viewportCappedStartRow = Math.max(viewportStartRow, 0);
const viewportCappedEndRow = Math.min(viewportEndRow, this._bufferService.rows - 1);
const viewportStartRow = this._selectionRenderModel.viewportStartRow;
const viewportEndRow = this._selectionRenderModel.viewportEndRow;
const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;
const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;

// No need to draw the selection
if (viewportCappedStartRow >= this._bufferService.rows || viewportCappedEndRow < 0) {
Expand Down Expand Up @@ -365,10 +370,16 @@ export class DomRenderer extends Disposable implements IRenderer {
*/
private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {
const element = this._document.createElement('div');
const left = colStart * this.dimensions.css.cell.width;
let width = this.dimensions.css.cell.width * (colEnd - colStart);
if (left + width > this.dimensions.css.canvas.width) {
width = this.dimensions.css.canvas.width - left;
}

element.style.height = `${rowCount * this.dimensions.css.cell.height}px`;
element.style.top = `${row * this.dimensions.css.cell.height}px`;
element.style.left = `${colStart * this.dimensions.css.cell.width}px`;
element.style.width = `${this.dimensions.css.cell.width * (colEnd - colStart)}px`;
element.style.left = `${left}px`;
element.style.width = `${width}px`;
return element;
}

Expand Down
8 changes: 5 additions & 3 deletions src/browser/renderer/shared/SelectionRenderModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* @license MIT
*/

import { ITerminal } from 'browser/Types';
import { ISelectionRenderModel } from 'browser/renderer/shared/Types';
import { Terminal } from '@xterm/xterm';

Expand Down Expand Up @@ -35,7 +36,7 @@ class SelectionRenderModel implements ISelectionRenderModel {
this.selectionEnd = undefined;
}

public update(terminal: Terminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {
public update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean = false): void {
this.selectionStart = start;
this.selectionEnd = end;
// Selection does not exist
Expand All @@ -45,8 +46,9 @@ class SelectionRenderModel implements ISelectionRenderModel {
}

// Translate from buffer position to viewport position
const viewportStartRow = start[1] - terminal.buffer.active.viewportY;
const viewportEndRow = end[1] - terminal.buffer.active.viewportY;
const viewportY = terminal.buffers.active.ydisp;
const viewportStartRow = start[1] - viewportY;
const viewportEndRow = end[1] - viewportY;
const viewportCappedStartRow = Math.max(viewportStartRow, 0);
const viewportCappedEndRow = Math.min(viewportEndRow, terminal.rows - 1);

Expand Down
4 changes: 2 additions & 2 deletions src/browser/renderer/shared/Types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { FontWeight, Terminal } from '@xterm/xterm';
import { IColorSet } from 'browser/Types';
import { IColorSet, ITerminal } from 'browser/Types';
import { IDisposable } from 'common/Types';
import { IEvent } from 'common/EventEmitter';

Expand Down Expand Up @@ -168,6 +168,6 @@ export interface ISelectionRenderModel {
readonly selectionStart: [number, number] | undefined;
readonly selectionEnd: [number, number] | undefined;
clear(): void;
update(terminal: Terminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode?: boolean): void;
update(terminal: ITerminal, start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode?: boolean): void;
isCellSelected(terminal: Terminal, x: number, y: number): boolean;
}

0 comments on commit 4036ab7

Please sign in to comment.