diff --git a/css/xterm.css b/css/xterm.css index 3f413d95..b3aa9e08 100644 --- a/css/xterm.css +++ b/css/xterm.css @@ -283,15 +283,3 @@ .xterm .monaco-scrollable-element > .shadow.top.left { box-shadow: var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset; } - -.xterm .monaco-scrollable-element > .scrollbar > .slider { - background: var(--vscode-scrollbarSlider-background, #79797966); -} - -.xterm .monaco-scrollable-element > .scrollbar > .slider:hover { - background: var(--vscode-scrollbarSlider-hoverBackground, #646464b3); -} - -.xterm .monaco-scrollable-element > .scrollbar > .slider.active { - background: var(--vscode-scrollbarSlider-activeBackground, #bfbfbf66); -} diff --git a/src/browser/Types.ts b/src/browser/Types.ts index 7000c9e3..43e1f9e2 100644 --- a/src/browser/Types.ts +++ b/src/browser/Types.ts @@ -66,6 +66,9 @@ export interface IColorSet { selectionBackgroundOpaque: IColor; selectionInactiveBackgroundTransparent: IColor; selectionInactiveBackgroundOpaque: IColor; + scrollbarSliderBackground: IColor; + scrollbarSliderHoverBackground: IColor; + scrollbarSliderActiveBackground: IColor; overviewRulerBorder: IColor; ansi: IColor[]; /** Maps original colors to colors that respect minimum contrast ratio. */ diff --git a/src/browser/Viewport.ts b/src/browser/Viewport.ts index 3e0b5079..bdfa1ac7 100644 --- a/src/browser/Viewport.ts +++ b/src/browser/Viewport.ts @@ -3,9 +3,9 @@ * @license MIT */ -import { IRenderService, IThemeService } from 'browser/services/Services'; +import { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services'; import { EventEmitter, runAndSubscribe } from 'common/EventEmitter'; -import { Disposable } from 'common/Lifecycle'; +import { Disposable, toDisposable } from 'common/Lifecycle'; import { IBufferService, IOptionsService } from 'common/services/Services'; import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import type { ScrollableElementChangeOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions'; @@ -17,6 +17,7 @@ export class Viewport extends Disposable{ public readonly onRequestScrollLines = this._onRequestScrollLines.event; private _scrollableElement: DomScrollableElement; + private _styleElement: HTMLStyleElement; private _queuedAnimationFrame?: number; private _latestYDisp?: number; @@ -28,6 +29,7 @@ export class Viewport extends Disposable{ element: HTMLElement, screenElement: HTMLElement, @IBufferService private readonly _bufferService: IBufferService, + @ICoreBrowserService coreBrowserService: ICoreBrowserService, @IThemeService themeService: IThemeService, @IOptionsService private readonly _optionsService: IOptionsService, @IRenderService private readonly _renderService: IRenderService @@ -55,6 +57,24 @@ export class Viewport extends Disposable{ this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css; })); element.appendChild(this._scrollableElement.getDomNode()); + this.register(toDisposable(() => this._scrollableElement.getDomNode().remove())); + + this._styleElement = coreBrowserService.window.document.createElement('style'); + screenElement.appendChild(this._styleElement); + this.register(toDisposable(() => this._styleElement.remove())); + this.register(runAndSubscribe(themeService.onChangeColors, () => { + this._styleElement.textContent = [ + `.xterm .monaco-scrollable-element > .scrollbar > .slider {`, + ` background: ${themeService.colors.scrollbarSliderBackground.css};`, + `}`, + `.xterm .monaco-scrollable-element > .scrollbar > .slider:hover {`, + ` background: ${themeService.colors.scrollbarSliderHoverBackground.css};`, + `}`, + `.xterm .monaco-scrollable-element > .scrollbar > .slider.active {`, + ` background: ${themeService.colors.scrollbarSliderActiveBackground.css};`, + `}` + ].join('\n'); + })); this.register(this._bufferService.onResize(() => this._queueSync())); this.register(this._bufferService.onScroll(ydisp => this._queueSync(ydisp))); diff --git a/src/browser/renderer/shared/CharAtlasUtils.ts b/src/browser/renderer/shared/CharAtlasUtils.ts index d3460fce..fb3fae88 100644 --- a/src/browser/renderer/shared/CharAtlasUtils.ts +++ b/src/browser/renderer/shared/CharAtlasUtils.ts @@ -22,6 +22,9 @@ export function generateConfig(deviceCellWidth: number, deviceCellHeight: number selectionInactiveBackgroundTransparent: NULL_COLOR, selectionInactiveBackgroundOpaque: NULL_COLOR, overviewRulerBorder: NULL_COLOR, + scrollbarSliderBackground: NULL_COLOR, + scrollbarSliderHoverBackground: NULL_COLOR, + scrollbarSliderActiveBackground: NULL_COLOR, // For the static char atlas, we only use the first 16 colors, but we need all 256 for the // dynamic character atlas. ansi: colors.ansi.slice(), diff --git a/src/browser/services/ThemeService.ts b/src/browser/services/ThemeService.ts index 605f020d..645777b9 100644 --- a/src/browser/services/ThemeService.ts +++ b/src/browser/services/ThemeService.ts @@ -58,6 +58,9 @@ export class ThemeService extends Disposable implements IThemeService { selectionBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION), selectionInactiveBackgroundTransparent: DEFAULT_SELECTION, selectionInactiveBackgroundOpaque: color.blend(DEFAULT_BACKGROUND, DEFAULT_SELECTION), + scrollbarSliderBackground: color.opacity(DEFAULT_FOREGROUND, 0.2), + scrollbarSliderHoverBackground: color.opacity(DEFAULT_FOREGROUND, 0.4), + scrollbarSliderActiveBackground: color.opacity(DEFAULT_FOREGROUND, 0.5), overviewRulerBorder: DEFAULT_OVERVIEW_RULER_BORDER, ansi: DEFAULT_ANSI_COLORS.slice(), contrastCache: this._contrastCache, @@ -102,6 +105,9 @@ export class ThemeService extends Disposable implements IThemeService { const opacity = 0.3; colors.selectionInactiveBackgroundTransparent = color.opacity(colors.selectionInactiveBackgroundTransparent, opacity); } + colors.scrollbarSliderBackground = parseColor(theme.scrollbarSliderBackground, color.opacity(colors.foreground, 0.2)); + colors.scrollbarSliderHoverBackground = parseColor(theme.scrollbarSliderHoverBackground, color.opacity(colors.foreground, 0.4)); + colors.scrollbarSliderActiveBackground = parseColor(theme.scrollbarSliderActiveBackground, color.opacity(colors.foreground, 0.5)); colors.overviewRulerBorder = parseColor(theme.overviewRulerBorder, DEFAULT_OVERVIEW_RULER_BORDER); colors.ansi = DEFAULT_ANSI_COLORS.slice(); colors.ansi[0] = parseColor(theme.black, DEFAULT_ANSI_COLORS[0]); diff --git a/src/common/services/Services.ts b/src/common/services/Services.ts index e8922e4f..cd046bb8 100644 --- a/src/common/services/Services.ts +++ b/src/common/services/Services.ts @@ -263,6 +263,9 @@ export interface ITheme { selectionForeground?: string; selectionBackground?: string; selectionInactiveBackground?: string; + scrollbarSliderBackground?: string; + scrollbarSliderHoverBackground?: string; + scrollbarSliderActiveBackground?: string; overviewRulerBorder?: string; black?: string; red?: string; diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index e83ee5db..a4ad28c0 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -368,6 +368,21 @@ declare module '@xterm/xterm' { * be transparent) */ selectionInactiveBackground?: string; + /** + * The scrollbar slider background color. Defaults to + * {@link ITerminalOptions.foreground foreground} with 20% opacity. + */ + scrollbarSliderBackground?: string; + /** + * The scrollbar slider background color when hovered. Defaults to + * {@link ITerminalOptions.foreground foreground} with 40% opacity. + */ + scrollbarSliderHoverBackground?: string; + /** + * The scrollbar slider background color when clicked. Defaults to + * {@link ITerminalOptions.foreground foreground} with 50% opacity. + */ + scrollbarSliderActiveBackground?: string; /** * The border color of the overview ruler. This visually separates the terminal from the scroll * bar when {@link ITerminalOptions.overviewRulerWidth overviewRulerWidth} is set. When this is