mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Support opaque selections in DOM renderer
Brings the DOM renderer closer to the webgl renderer which draws the text on top of the selection. This is done by leveraging the override system similar to in webgl and as well as forcing the element above the selection. This also improves contrast color caching for the DOM renderer. This should result in a slight performance hit but only when a selection is being made. The improved contrast seems worth it. Fixes #3838
This commit is contained in:
@@ -226,7 +226,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
`}` +
|
||||
`${this._terminalSelector} .${SELECTION_CLASS} div {` +
|
||||
` position: absolute;` +
|
||||
` background-color: ${this._colors.selectionTransparent.css};` +
|
||||
` background-color: ${this._colors.selectionOpaque.css};` +
|
||||
`}`;
|
||||
// Colors
|
||||
this._colors.ansi.forEach((c, i) => {
|
||||
|
||||
@@ -206,14 +206,22 @@ export class DomRendererRowFactory {
|
||||
}
|
||||
|
||||
// Apply selection foreground if applicable
|
||||
const isInSelection = this._isCellInSelection(x, row);
|
||||
if (!isTop) {
|
||||
if (this._colors.selectionForeground && this._isCellInSelection(x, row)) {
|
||||
if (this._colors.selectionForeground && isInSelection) {
|
||||
fgColorMode = Attributes.CM_RGB;
|
||||
fg = this._colors.selectionForeground.rgba >> 8 & 0xFFFFFF;
|
||||
fgOverride = this._colors.selectionForeground;
|
||||
}
|
||||
}
|
||||
|
||||
// If in the selection, force the element to be above the selection to improve contrast and
|
||||
// support opaque selections
|
||||
if (isInSelection) {
|
||||
bgOverride = this._colors.selectionOpaque;
|
||||
isTop = true;
|
||||
}
|
||||
|
||||
// If it's a top decoration, render above the selection
|
||||
if (isTop) {
|
||||
charElement.classList.add(`xterm-decoration-top`);
|
||||
@@ -226,7 +234,7 @@ export class DomRendererRowFactory {
|
||||
if (cell.isBold() && fg < 8 && this._optionsService.rawOptions.drawBoldTextInBrightColors) {
|
||||
fg += 8;
|
||||
}
|
||||
if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.ansi[fg], cell, undefined, undefined)) {
|
||||
if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.ansi[fg], cell, bgOverride, undefined)) {
|
||||
charElement.classList.add(`xterm-fg-${fg}`);
|
||||
}
|
||||
break;
|
||||
@@ -242,7 +250,7 @@ export class DomRendererRowFactory {
|
||||
break;
|
||||
case Attributes.CM_DEFAULT:
|
||||
default:
|
||||
if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.foreground, cell, undefined, undefined)) {
|
||||
if (!this._applyMinimumContrast(charElement, this._colors.background, this._colors.foreground, cell, bgOverride, undefined)) {
|
||||
if (isInverse) {
|
||||
charElement.classList.add(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);
|
||||
}
|
||||
@@ -279,16 +287,14 @@ export class DomRendererRowFactory {
|
||||
|
||||
// Try get from cache first, only use the cache when there are no decoration overrides
|
||||
let adjustedColor: IColor | undefined | null = undefined;
|
||||
if (!bgOverride || !fgOverride) {
|
||||
adjustedColor = this._colors.contrastCache.getColor(this._workCell.bg, this._workCell.fg);
|
||||
if (!bgOverride && !fgOverride) {
|
||||
adjustedColor = this._colors.contrastCache.getColor(bg.rgba, fg.rgba);
|
||||
}
|
||||
|
||||
// Calculate and store in cache
|
||||
if (adjustedColor === undefined) {
|
||||
adjustedColor = color.ensureContrastRatio(bgOverride || bg, fgOverride || fg, this._optionsService.rawOptions.minimumContrastRatio);
|
||||
if (!bgOverride || !fgOverride) {
|
||||
this._colors.contrastCache.setColor(this._workCell.bg, this._workCell.fg, adjustedColor ?? null);
|
||||
}
|
||||
this._colors.contrastCache.setColor((bgOverride || bg).rgba, (fgOverride || fg).rgba, adjustedColor ?? null);
|
||||
}
|
||||
|
||||
if (adjustedColor) {
|
||||
|
||||
Reference in New Issue
Block a user