Skip to content

Commit 900200b

Browse files
committed
Merge remote-tracking branch 'upstream/master' into 3773
2 parents f18528d + 3abbaa9 commit 900200b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+762
-357
lines changed

addons/xterm-addon-fit/src/FitAddon.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export class FitAddon implements ITerminalAddon {
6363
return undefined;
6464
}
6565

66+
const scrollbarWidth = this._terminal.options.scrollback === 0 ?
67+
0 : core.viewport.scrollBarWidth;
68+
6669
const parentElementStyle = window.getComputedStyle(this._terminal.element.parentElement);
6770
const parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height'));
6871
const parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')));
@@ -76,7 +79,7 @@ export class FitAddon implements ITerminalAddon {
7679
const elementPaddingVer = elementPadding.top + elementPadding.bottom;
7780
const elementPaddingHor = elementPadding.right + elementPadding.left;
7881
const availableHeight = parentElementHeight - elementPaddingVer;
79-
const availableWidth = parentElementWidth - elementPaddingHor - core.viewport.scrollBarWidth;
82+
const availableWidth = parentElementWidth - elementPaddingHor - scrollbarWidth;
8083
const geometry = {
8184
cols: Math.max(MINIMUM_COLS, Math.floor(availableWidth / core._renderService.dimensions.actualCellWidth)),
8285
rows: Math.max(MINIMUM_ROWS, Math.floor(availableHeight / core._renderService.dimensions.actualCellHeight))

addons/xterm-addon-search/src/SearchAddon.ts

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@ export class SearchAddon implements ITerminalAddon {
115115
}
116116
}
117117

118+
public clearActiveDecoration(): void {
119+
this._selectedDecoration?.dispose();
120+
this._selectedDecoration = undefined;
121+
}
122+
118123
/**
119124
* Find the next instance of the term, then scroll to and select it. If it
120125
* doesn't exist, do nothing.
@@ -653,26 +658,28 @@ export class SearchAddon implements ITerminalAddon {
653658
* @param result The result to select.
654659
* @return Whether a result was selected.
655660
*/
656-
private _selectResult(result: ISearchResult | undefined, decorations?: ISearchDecorationOptions, noScroll?: boolean): boolean {
661+
private _selectResult(result: ISearchResult | undefined, options?: ISearchDecorationOptions, noScroll?: boolean): boolean {
657662
const terminal = this._terminal!;
658-
this._selectedDecoration?.dispose();
663+
this.clearActiveDecoration();
659664
if (!result) {
660665
terminal.clearSelection();
661666
return false;
662667
}
663668
terminal.select(result.col, result.row, result.size);
664-
if (decorations?.activeMatchColorOverviewRuler) {
669+
if (options) {
665670
const marker = terminal.registerMarker(-terminal.buffer.active.baseY - terminal.buffer.active.cursorY + result.row);
666671
if (marker) {
667672
this._selectedDecoration = terminal.registerDecoration({
668673
marker,
669674
x: result.col,
670675
width: result.size,
676+
backgroundColor: options.activeMatchBackground,
677+
layer: 'top',
671678
overviewRulerOptions: {
672-
color: decorations.activeMatchColorOverviewRuler
679+
color: options.activeMatchColorOverviewRuler
673680
}
674681
});
675-
this._selectedDecoration?.onRender((e) => this._applyStyles(e, decorations.activeMatchBackground, decorations.activeMatchBorder));
682+
this._selectedDecoration?.onRender((e) => this._applyStyles(e, options.activeMatchBorder));
676683
this._selectedDecoration?.onDispose(() => marker.dispose());
677684
}
678685
}
@@ -695,15 +702,12 @@ export class SearchAddon implements ITerminalAddon {
695702
* @param borderColor the border color to apply
696703
* @returns
697704
*/
698-
private _applyStyles(element: HTMLElement, backgroundColor: string | undefined, borderColor: string | undefined): void {
705+
private _applyStyles(element: HTMLElement, borderColor: string | undefined): void {
699706
if (element.clientWidth <= 0) {
700707
return;
701708
}
702709
if (!element.classList.contains('xterm-find-result-decoration')) {
703710
element.classList.add('xterm-find-result-decoration');
704-
if (backgroundColor) {
705-
element.style.backgroundColor = backgroundColor;
706-
}
707711
if (borderColor) {
708712
element.style.outline = `1px solid ${borderColor}`;
709713
}
@@ -719,18 +723,20 @@ export class SearchAddon implements ITerminalAddon {
719723
private _createResultDecoration(result: ISearchResult, options: ISearchDecorationOptions): IDecoration | undefined {
720724
const terminal = this._terminal!;
721725
const marker = terminal.registerMarker(-terminal.buffer.active.baseY - terminal.buffer.active.cursorY + result.row);
722-
if (!marker || !options?.matchOverviewRuler) {
726+
if (!marker) {
723727
return undefined;
724728
}
725729
const findResultDecoration = terminal.registerDecoration({
726730
marker,
727731
x: result.col,
728732
width: result.size,
733+
backgroundColor: options.matchBackground,
729734
overviewRulerOptions: this._resultDecorations?.get(marker.line) ? undefined : {
730-
color: options.matchOverviewRuler, position: 'center'
735+
color: options.matchOverviewRuler,
736+
position: 'center'
731737
}
732738
});
733-
findResultDecoration?.onRender((e) => this._applyStyles(e, options.matchBackground, options.matchBorder));
739+
findResultDecoration?.onRender((e) => this._applyStyles(e, options.matchBorder));
734740
findResultDecoration?.onDispose(() => marker.dispose());
735741
return findResultDecoration;
736742
}

addons/xterm-addon-search/typings/xterm-addon-search.d.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ declare module 'xterm-addon-search' {
4545
*/
4646
interface ISearchDecorationOptions {
4747
/**
48-
* The background color of a match.
48+
* The background color of a match, this must use #RRGGBB format.
4949
*/
5050
matchBackground?: string;
5151

5252
/**
53-
* The border color of a match
53+
* The border color of a match.
5454
*/
5555
matchBorder?: string;
5656

@@ -60,7 +60,7 @@ declare module 'xterm-addon-search' {
6060
matchOverviewRuler: string;
6161

6262
/**
63-
* The background color for the currently active match.
63+
* The background color for the currently active match, this must use #RRGGBB format.
6464
*/
6565
activeMatchBackground?: string;
6666

@@ -111,6 +111,13 @@ declare module 'xterm-addon-search' {
111111
*/
112112
public clearDecorations(): void;
113113

114+
/**
115+
* Clears the active result decoration, this decoration is applied on top of the selection so
116+
* removing it will reveal the selection underneath. This is intended to be called on the search
117+
* textarea's `blur` event.
118+
*/
119+
public clearActiveDecoration(): void;
120+
114121
/**
115122
* When decorations are enabled, fires when
116123
* the search results change.

addons/xterm-addon-webgl/src/GlyphRenderer.ts

Lines changed: 7 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,11 @@
66
import { createProgram, PROJECTION_MATRIX, throwIfFalsy } from './WebglUtils';
77
import { WebglCharAtlas } from './atlas/WebglCharAtlas';
88
import { IWebGL2RenderingContext, IWebGLVertexArrayObject, IRenderModel, IRasterizedGlyph } from './Types';
9-
import { COMBINED_CHAR_BIT_MASK, RENDER_MODEL_INDICIES_PER_CELL, RENDER_MODEL_FG_OFFSET, RENDER_MODEL_BG_OFFSET } from './RenderModel';
109
import { fill } from 'common/TypedArrayUtils';
11-
import { slice } from './TypedArray';
12-
import { NULL_CELL_CODE, WHITESPACE_CELL_CODE, Attributes, FgFlags } from 'common/buffer/Constants';
10+
import { NULL_CELL_CODE } from 'common/buffer/Constants';
1311
import { Terminal, IBufferLine } from 'xterm';
14-
import { IColorSet, IColor } from 'browser/Types';
12+
import { IColorSet } from 'browser/Types';
1513
import { IRenderDimensions } from 'browser/renderer/Types';
16-
import { AttributeData } from 'common/buffer/AttributeData';
1714

1815
interface IVertices {
1916
attributes: Float32Array;
@@ -24,7 +21,6 @@ interface IVertices {
2421
* working on the next frame.
2522
*/
2623
attributesBuffers: Float32Array[];
27-
selectionAttributes: Float32Array;
2824
count: number;
2925
}
3026

@@ -91,8 +87,7 @@ export class GlyphRenderer {
9187
attributesBuffers: [
9288
new Float32Array(0),
9389
new Float32Array(0)
94-
],
95-
selectionAttributes: new Float32Array(0)
90+
]
9691
};
9792

9893
constructor(
@@ -187,6 +182,8 @@ export class GlyphRenderer {
187182
if (!this._atlas) {
188183
return;
189184
}
185+
186+
// Get the glyph
190187
if (chars && chars.length > 1) {
191188
rasterizedGlyph = this._atlas.getRasterizedGlyphCombinedChar(chars, bg, fg);
192189
} else {
@@ -214,91 +211,6 @@ export class GlyphRenderer {
214211
// a_cellpos only changes on resize
215212
}
216213

217-
public updateSelection(model: IRenderModel): void {
218-
const terminal = this._terminal;
219-
220-
this._vertices.selectionAttributes = slice(this._vertices.attributes, 0);
221-
222-
const bg = (this._colors.selectionOpaque.rgba >>> 8) | Attributes.CM_RGB;
223-
224-
if (model.selection.columnSelectMode) {
225-
const startCol = model.selection.startCol;
226-
const width = model.selection.endCol - startCol;
227-
const height = model.selection.viewportCappedEndRow - model.selection.viewportCappedStartRow + 1;
228-
for (let y = model.selection.viewportCappedStartRow; y < model.selection.viewportCappedStartRow + height; y++) {
229-
this._updateSelectionRange(startCol, startCol + width, y, model, bg);
230-
}
231-
} else {
232-
// Draw first row
233-
const startCol = model.selection.viewportStartRow === model.selection.viewportCappedStartRow ? model.selection.startCol : 0;
234-
const startRowEndCol = model.selection.viewportCappedStartRow === model.selection.viewportCappedEndRow ? model.selection.endCol : terminal.cols;
235-
this._updateSelectionRange(startCol, startRowEndCol, model.selection.viewportCappedStartRow, model, bg);
236-
237-
// Draw middle rows
238-
const middleRowsCount = Math.max(model.selection.viewportCappedEndRow - model.selection.viewportCappedStartRow - 1, 0);
239-
for (let y = model.selection.viewportCappedStartRow + 1; y <= model.selection.viewportCappedStartRow + middleRowsCount; y++) {
240-
this._updateSelectionRange(0, startRowEndCol, y, model, bg);
241-
}
242-
243-
// Draw final row
244-
if (model.selection.viewportCappedStartRow !== model.selection.viewportCappedEndRow) {
245-
// Only draw viewportEndRow if it's not the same as viewportStartRow
246-
const endCol = model.selection.viewportEndRow === model.selection.viewportCappedEndRow ? model.selection.endCol : terminal.cols;
247-
this._updateSelectionRange(0, endCol, model.selection.viewportCappedEndRow, model, bg);
248-
}
249-
}
250-
}
251-
252-
private _updateSelectionRange(startCol: number, endCol: number, y: number, model: IRenderModel, bg: number): void {
253-
const terminal = this._terminal;
254-
const row = y + terminal.buffer.active.viewportY;
255-
let line: IBufferLine | undefined;
256-
for (let x = startCol; x < endCol; x++) {
257-
const offset = (y * this._terminal.cols + x) * RENDER_MODEL_INDICIES_PER_CELL;
258-
const code = model.cells[offset];
259-
let fg = model.cells[offset + RENDER_MODEL_FG_OFFSET];
260-
if (fg & FgFlags.INVERSE) {
261-
const workCell = new AttributeData();
262-
workCell.fg = fg;
263-
workCell.bg = model.cells[offset + RENDER_MODEL_BG_OFFSET];
264-
// Get attributes from fg (excluding inverse) and resolve inverse by pullibng rgb colors
265-
// from bg. This is needed since the inverse fg color should be based on the original bg
266-
// color, not on the selection color
267-
fg &= ~(Attributes.CM_MASK | Attributes.RGB_MASK | FgFlags.INVERSE);
268-
switch (workCell.getBgColorMode()) {
269-
case Attributes.CM_P16:
270-
case Attributes.CM_P256:
271-
const c = this._getColorFromAnsiIndex(workCell.getBgColor()).rgba;
272-
fg |= (c >> 8) & Attributes.RED_MASK | (c >> 8) & Attributes.GREEN_MASK | (c >> 8) & Attributes.BLUE_MASK;
273-
case Attributes.CM_RGB:
274-
const arr = AttributeData.toColorRGB(workCell.getBgColor());
275-
fg |= arr[0] << Attributes.RED_SHIFT | arr[1] << Attributes.GREEN_SHIFT | arr[2] << Attributes.BLUE_SHIFT;
276-
case Attributes.CM_DEFAULT:
277-
default:
278-
const c2 = this._colors.background.rgba;
279-
fg |= (c2 >> 8) & Attributes.RED_MASK | (c2 >> 8) & Attributes.GREEN_MASK | (c2 >> 8) & Attributes.BLUE_MASK;
280-
}
281-
fg |= Attributes.CM_RGB;
282-
}
283-
if (code & COMBINED_CHAR_BIT_MASK) {
284-
if (!line) {
285-
line = terminal.buffer.active.getLine(row);
286-
}
287-
const chars = line!.getCell(x)!.getChars();
288-
this._updateCell(this._vertices.selectionAttributes, x, y, model.cells[offset], bg, fg, chars);
289-
} else {
290-
this._updateCell(this._vertices.selectionAttributes, x, y, model.cells[offset], bg, fg);
291-
}
292-
}
293-
}
294-
295-
private _getColorFromAnsiIndex(idx: number): IColor {
296-
if (idx >= this._colors.ansi.length) {
297-
throw new Error('No color found for idx ' + idx);
298-
}
299-
return this._colors.ansi[idx];
300-
}
301-
302214
public clear(force?: boolean): void {
303215
const terminal = this._terminal;
304216
const newCount = terminal.cols * terminal.rows * INDICES_PER_CELL;
@@ -333,7 +245,7 @@ export class GlyphRenderer {
333245
public setColors(): void {
334246
}
335247

336-
public render(renderModel: IRenderModel, isSelectionVisible: boolean): void {
248+
public render(renderModel: IRenderModel): void {
337249
if (!this._atlas) {
338250
return;
339251
}
@@ -357,7 +269,7 @@ export class GlyphRenderer {
357269
let bufferLength = 0;
358270
for (let y = 0; y < renderModel.lineLengths.length; y++) {
359271
const si = y * this._terminal.cols * INDICES_PER_CELL;
360-
const sub = (isSelectionVisible ? this._vertices.selectionAttributes : this._vertices.attributes).subarray(si, si + renderModel.lineLengths[y] * INDICES_PER_CELL);
272+
const sub = this._vertices.attributes.subarray(si, si + renderModel.lineLengths[y] * INDICES_PER_CELL);
361273
activeBuffer.set(sub, bufferLength);
362274
bufferLength += sub.length;
363275
}

0 commit comments

Comments
 (0)