Merge branch 'master' into progress-addon
This commit is contained in:
@@ -499,12 +499,16 @@ export class SearchAddon extends Disposable implements ITerminalAddon , ISearchA
|
||||
const [stringLine, offsets] = cache;
|
||||
|
||||
const offset = this._bufferColsToStringOffset(row, col);
|
||||
const searchTerm = searchOptions.caseSensitive ? term : term.toLowerCase();
|
||||
const searchStringLine = searchOptions.caseSensitive ? stringLine : stringLine.toLowerCase();
|
||||
let searchTerm = term;
|
||||
let searchStringLine = stringLine;
|
||||
if (!searchOptions.regex) {
|
||||
searchTerm = searchOptions.caseSensitive ? term : term.toLowerCase();
|
||||
searchStringLine = searchOptions.caseSensitive ? stringLine : stringLine.toLowerCase();
|
||||
}
|
||||
|
||||
let resultIndex = -1;
|
||||
if (searchOptions.regex) {
|
||||
const searchRegex = RegExp(searchTerm, 'g');
|
||||
const searchRegex = RegExp(searchTerm, searchOptions.caseSensitive ? 'g' : 'gi');
|
||||
let foundTerm: RegExpExecArray | null;
|
||||
if (isReverseSearch) {
|
||||
// This loop will get the resultIndex of the _last_ regex match in the range 0..offset
|
||||
|
||||
@@ -222,7 +222,7 @@ describe('SerializeAddon', () => {
|
||||
|
||||
it('empty terminal with default options', async () => {
|
||||
const output = serializeAddon.serializeAsHTML();
|
||||
assert.equal((output.match(/color: #000000; background-color: #ffffff; font-family: courier-new, courier, monospace; font-size: 15px;/g) || []).length, 1, output);
|
||||
assert.equal((output.match(/color: #000000; background-color: #ffffff; font-family: monospace; font-size: 15px;/g) || []).length, 1, output);
|
||||
});
|
||||
|
||||
it('empty terminal with custom options', async () => {
|
||||
@@ -242,7 +242,7 @@ describe('SerializeAddon', () => {
|
||||
const output = serializeAddon.serializeAsHTML({
|
||||
includeGlobalBackground: true
|
||||
});
|
||||
assert.equal((output.match(/color: #ffffff; background-color: #000000; font-family: courier-new, courier, monospace; font-size: 15px;/g) || []).length, 1, output);
|
||||
assert.equal((output.match(/color: #ffffff; background-color: #000000; font-family: monospace; font-size: 15px;/g) || []).length, 1, output);
|
||||
});
|
||||
|
||||
it('cells with custom color styling', async () => {
|
||||
|
||||
@@ -33,6 +33,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
private _charAtlasDisposable = this._register(new MutableDisposable());
|
||||
private _charAtlas: ITextureAtlas | undefined;
|
||||
private _devicePixelRatio: number;
|
||||
private _deviceMaxTextureSize: number;
|
||||
private _observerDisposable = this._register(new MutableDisposable());
|
||||
|
||||
private _model: RenderModel = new RenderModel();
|
||||
@@ -102,6 +103,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
throw new Error('WebGL2 not supported ' + this._gl);
|
||||
}
|
||||
|
||||
this._deviceMaxTextureSize = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE);
|
||||
|
||||
this._register(addDisposableListener(this._canvas, 'webglcontextlost', (e) => {
|
||||
console.log('webglcontextlost event received');
|
||||
// Prevent the default behavior in order to enable WebGL context restoration.
|
||||
@@ -272,7 +275,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
this.dimensions.device.cell.height,
|
||||
this.dimensions.device.char.width,
|
||||
this.dimensions.device.char.height,
|
||||
this._coreBrowserService.dpr
|
||||
this._coreBrowserService.dpr,
|
||||
this._deviceMaxTextureSize
|
||||
);
|
||||
if (this._charAtlas !== atlas) {
|
||||
this._onChangeTextureAtlas.fire(atlas.pages[0].canvas);
|
||||
@@ -354,7 +358,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
}
|
||||
|
||||
private _updateCursorBlink(): void {
|
||||
if (this._terminal.options.cursorBlink) {
|
||||
if (this._coreService.decPrivateModes.cursorBlink ?? this._terminal.options.cursorBlink) {
|
||||
this._cursorBlinkStateManager.value = new CursorBlinkStateManager(() => {
|
||||
this._requestRedrawCursor();
|
||||
}, this._coreBrowserService);
|
||||
@@ -377,8 +381,11 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
let line: IBufferLine;
|
||||
let joinedRanges: [number, number][];
|
||||
let isJoined: boolean;
|
||||
let skipJoinedCheckUntilX: number = 0;
|
||||
let isValidJoinRange: boolean = true;
|
||||
let lastCharX: number;
|
||||
let range: [number, number];
|
||||
let isCursorRow: boolean;
|
||||
let chars: string;
|
||||
let code: number;
|
||||
let width: number;
|
||||
@@ -387,6 +394,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
let j: number;
|
||||
start = clamp(start, terminal.rows - 1, 0);
|
||||
end = clamp(end, terminal.rows - 1, 0);
|
||||
const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? terminal.options.cursorStyle ?? 'block';
|
||||
|
||||
const cursorY = this._terminal.buffer.active.baseY + this._terminal.buffer.active.cursorY;
|
||||
const viewportRelativeCursorY = cursorY - terminal.buffer.ydisp;
|
||||
@@ -404,6 +412,8 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
row = y + terminal.buffer.ydisp;
|
||||
line = terminal.buffer.lines.get(row)!;
|
||||
this._model.lineLengths[y] = 0;
|
||||
isCursorRow = cursorY === row;
|
||||
skipJoinedCheckUntilX = 0;
|
||||
joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
|
||||
for (x = 0; x < terminal.cols; x++) {
|
||||
lastBg = this._cellColorResolver.result.bg;
|
||||
@@ -415,25 +425,43 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
|
||||
// If true, indicates that the current character(s) to draw were joined.
|
||||
isJoined = false;
|
||||
|
||||
// Indicates whether this cell is part of a joined range that should be ignored as it cannot
|
||||
// be rendered entirely, like the selection state differs across the range.
|
||||
isValidJoinRange = (x >= skipJoinedCheckUntilX);
|
||||
|
||||
lastCharX = x;
|
||||
|
||||
// Process any joined character ranges as needed. Because of how the
|
||||
// ranges are produced, we know that they are valid for the characters
|
||||
// and attributes of our input.
|
||||
if (joinedRanges.length > 0 && x === joinedRanges[0][0]) {
|
||||
isJoined = true;
|
||||
if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {
|
||||
range = joinedRanges.shift()!;
|
||||
|
||||
// We already know the exact start and end column of the joined range,
|
||||
// so we get the string and width representing it directly.
|
||||
cell = new JoinedCellData(
|
||||
cell,
|
||||
line!.translateToString(true, range[0], range[1]),
|
||||
range[1] - range[0]
|
||||
);
|
||||
// If the ligature's selection state is not consistent, don't join it. This helps the
|
||||
// selection render correctly regardless whether they should be joined.
|
||||
const firstSelectionState = this._model.selection.isCellSelected(this._terminal, range[0], row);
|
||||
for (i = range[0] + 1; i < range[1]; i++) {
|
||||
isValidJoinRange &&= (firstSelectionState === this._model.selection.isCellSelected(this._terminal, i, row));
|
||||
}
|
||||
// Similarly, if the cursor is in the ligature, don't join it.
|
||||
isValidJoinRange &&= !isCursorRow || cursorX < range[0] || cursorX >= range[1];
|
||||
if (!isValidJoinRange) {
|
||||
skipJoinedCheckUntilX = range[1];
|
||||
} else {
|
||||
isJoined = true;
|
||||
|
||||
// Skip over the cells occupied by this range in the loop
|
||||
lastCharX = range[1] - 1;
|
||||
// We already know the exact start and end column of the joined range,
|
||||
// so we get the string and width representing it directly.
|
||||
cell = new JoinedCellData(
|
||||
cell,
|
||||
line!.translateToString(true, range[0], range[1]),
|
||||
range[1] - range[0]
|
||||
);
|
||||
|
||||
// Skip over the cells occupied by this range in the loop
|
||||
lastCharX = range[1] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
chars = cell.getChars();
|
||||
@@ -450,8 +478,7 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
x: cursorX,
|
||||
y: viewportRelativeCursorY,
|
||||
width: cell.getWidth(),
|
||||
style: this._coreBrowserService.isFocused ?
|
||||
(terminal.options.cursorStyle || 'block') : terminal.options.cursorInactiveStyle,
|
||||
style: this._coreBrowserService.isFocused ? cursorStyle : terminal.options.cursorInactiveStyle,
|
||||
cursorWidth: terminal.options.cursorWidth,
|
||||
dpr: this._devicePixelRatio
|
||||
};
|
||||
@@ -459,9 +486,10 @@ export class WebglRenderer extends Disposable implements IRenderer {
|
||||
}
|
||||
if (x >= cursorX && x <= lastCursorX &&
|
||||
((this._coreBrowserService.isFocused &&
|
||||
(terminal.options.cursorStyle || 'block') === 'block') ||
|
||||
cursorStyle === 'block') ||
|
||||
(this._coreBrowserService.isFocused === false &&
|
||||
terminal.options.cursorInactiveStyle === 'block'))) {
|
||||
terminal.options.cursorInactiveStyle === 'block'))
|
||||
) {
|
||||
this._cellColorResolver.result.fg =
|
||||
Attributes.CM_RGB | (this._themeService.colors.cursorAccent.rgba >> 8 & Attributes.RGB_MASK);
|
||||
this._cellColorResolver.result.bg =
|
||||
|
||||
@@ -94,7 +94,8 @@ export abstract class BaseRenderLayer extends Disposable implements IRenderLayer
|
||||
if (this._deviceCharWidth <= 0 && this._deviceCharHeight <= 0) {
|
||||
return;
|
||||
}
|
||||
this._charAtlas = acquireTextureAtlas(terminal, this._optionsService.rawOptions, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr);
|
||||
|
||||
this._charAtlas = acquireTextureAtlas(terminal, this._optionsService.rawOptions, colorSet, this._deviceCellWidth, this._deviceCellHeight, this._deviceCharWidth, this._deviceCharHeight, this._coreBrowserService.dpr, 2048);
|
||||
this._charAtlas.warmUp();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user