diff --git a/tabby-core/src/api/platform.ts b/tabby-core/src/api/platform.ts index 63bf00e634..9a87dc1834 100644 --- a/tabby-core/src/api/platform.ts +++ b/tabby-core/src/api/platform.ts @@ -86,14 +86,18 @@ export interface FileUploadOptions { multiple: boolean } +export type PlatformTheme = 'light'|'dark' + export abstract class PlatformService { supportsWindowControls = false get fileTransferStarted$ (): Observable { return this.fileTransferStarted } get displayMetricsChanged$ (): Observable { return this.displayMetricsChanged } + get themeChanged$ (): Observable { return this.themeChanged } protected fileTransferStarted = new Subject() protected displayMetricsChanged = new Subject() + protected themeChanged = new Subject() abstract readClipboard (): string abstract setClipboard (content: ClipboardContent): void @@ -169,6 +173,10 @@ export abstract class PlatformService { throw new Error('Not implemented') } + getTheme (): PlatformTheme { + return 'dark' + } + abstract getOSRelease (): string abstract getAppVersion (): string abstract openExternal (url: string): void diff --git a/tabby-core/src/configDefaults.yaml b/tabby-core/src/configDefaults.yaml index 7a7ee99cc1..693c888b5c 100644 --- a/tabby-core/src/configDefaults.yaml +++ b/tabby-core/src/configDefaults.yaml @@ -11,7 +11,7 @@ appearance: tabsLocation: top tabsInFullscreen: false cycleTabs: true - theme: Standard + theme: Follow the color scheme frame: thin css: '/* * { color: blue !important; } */' opacity: 1.0 diff --git a/tabby-core/src/services/themes.service.ts b/tabby-core/src/services/themes.service.ts index 802ac399f9..01a6a2bd44 100644 --- a/tabby-core/src/services/themes.service.ts +++ b/tabby-core/src/services/themes.service.ts @@ -3,6 +3,7 @@ import { Subject, Observable } from 'rxjs' import * as Color from 'color' import { ConfigService } from '../services/config.service' import { Theme } from '../api/theme' +import { PlatformService } from '../api/platform' import { NewTheme } from '../theme' @Injectable({ providedIn: 'root' }) @@ -17,6 +18,7 @@ export class ThemesService { private constructor ( private config: ConfigService, private standardTheme: NewTheme, + private platform: PlatformService, @Inject(Theme) private themes: Theme[], ) { this.rootElementStyleBackup = document.documentElement.style.cssText @@ -24,6 +26,10 @@ export class ThemesService { config.ready$.toPromise().then(() => { this.applyCurrentTheme() this.applyThemeVariables() + platform.themeChanged$.subscribe(() => { + this.applyCurrentTheme() + this.applyThemeVariables() + }) config.changed$.subscribe(() => { this.applyCurrentTheme() this.applyThemeVariables() @@ -36,7 +42,7 @@ export class ThemesService { document.documentElement.style.cssText = this.rootElementStyleBackup } - const theme = this.config.store.terminal.colorScheme + const theme = this._getActiveColorScheme() const isDark = Color(theme.background).luminosity() < Color(theme.foreground).luminosity() function more (some, factor) { @@ -106,8 +112,10 @@ export class ThemesService { const themeColors = { primary: theme.colors[accentIndex], - secondary: less(theme.background, 0.5).string(), - tertiary: theme.colors[8], + secondary: isDark + ? less(theme.background, 0.5).string() + : less(theme.background, 0.125).string(), + tertiary: more(theme.background, 0.75).string(), warning: theme.colors[3], danger: theme.colors[1], success: theme.colors[2], @@ -184,6 +192,15 @@ export class ThemesService { return this.findTheme(this.config.store.appearance.theme) ?? this.standardTheme } + /// @hidden + _getActiveColorScheme (): any { + if (this.platform.getTheme() === 'light') { + return this.config.store.terminal.lightColorScheme + } else { + return this.config.store.terminal.colorScheme + } + } + applyTheme (theme: Theme): void { if (!this.styleElement) { this.styleElement = document.createElement('style') diff --git a/tabby-core/src/theme.new.scss b/tabby-core/src/theme.new.scss index 07e35aa604..9b86408c33 100644 --- a/tabby-core/src/theme.new.scss +++ b/tabby-core/src/theme.new.scss @@ -110,7 +110,7 @@ body { } .nav { - --bs-nav-link-color: var(--theme-fg); + --bs-nav-link-color: var(--theme-fg-more); --bs-nav-link-hover-color: var(--theme-fg-less); --bs-nav-link-disabled-color: var(--bs-gray); } @@ -119,8 +119,8 @@ body { --bs-nav-tabs-border-width: 2px; --bs-nav-tabs-border-radius: 0; --bs-nav-tabs-link-hover-border-color: var(--bs-body-bg); - --bs-nav-tabs-border-color: var(--theme-fg-less-2); - --bs-nav-tabs-link-active-color: var(--theme-fg-less-2); + --bs-nav-tabs-border-color: var(--theme-fg); + --bs-nav-tabs-link-active-color: var(--theme-fg); --bs-nav-tabs-link-active-bg: transparent; --bs-nav-tabs-link-active-border-color: transparent; diff --git a/tabby-electron/src/services/electron.service.ts b/tabby-electron/src/services/electron.service.ts index aab81e7310..a56e32ca20 100644 --- a/tabby-electron/src/services/electron.service.ts +++ b/tabby-electron/src/services/electron.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core' -import { App, IpcRenderer, Shell, Dialog, Clipboard, GlobalShortcut, Screen, AutoUpdater, TouchBar, BrowserWindow, Menu, MenuItem, PowerSaveBlocker } from 'electron' +import { App, IpcRenderer, Shell, Dialog, Clipboard, GlobalShortcut, Screen, AutoUpdater, TouchBar, BrowserWindow, Menu, MenuItem, PowerSaveBlocker, NativeTheme } from 'electron' import * as remote from '@electron/remote' export interface MessageBoxResponse { @@ -20,6 +20,7 @@ export class ElectronService { process: any autoUpdater: AutoUpdater powerSaveBlocker: PowerSaveBlocker + nativeTheme: NativeTheme TouchBar: typeof TouchBar BrowserWindow: typeof BrowserWindow Menu: typeof Menu @@ -43,5 +44,7 @@ export class ElectronService { this.BrowserWindow = remote.BrowserWindow this.Menu = remote.Menu this.MenuItem = remote.MenuItem + this.MenuItem = remote.MenuItem + this.nativeTheme = remote.nativeTheme } } diff --git a/tabby-electron/src/services/platform.service.ts b/tabby-electron/src/services/platform.service.ts index d6243c796f..604cddc2c4 100644 --- a/tabby-electron/src/services/platform.service.ts +++ b/tabby-electron/src/services/platform.service.ts @@ -10,6 +10,7 @@ import { ElectronService } from '../services/electron.service' import { ElectronHostWindow } from './hostWindow.service' import { ShellIntegrationService } from './shellIntegration.service' import { ElectronHostAppService } from './hostApp.service' +import { PlatformTheme } from '../../../tabby-core/src/api/platform' const fontManager = require('fontmanager-redux') // eslint-disable-line /* eslint-disable block-scoped-var */ @@ -40,6 +41,10 @@ export class ElectronPlatformService extends PlatformService { electron.ipcRenderer.on('host:display-metrics-changed', () => { this.zone.run(() => this.displayMetricsChanged.next()) }) + + electron.nativeTheme.on('updated', () => { + this.zone.run(() => this.themeChanged.next(this.getTheme())) + }) } readClipboard (): string { @@ -243,6 +248,14 @@ export class ElectronPlatformService extends PlatformService { }, )).filePaths[0] } + + getTheme (): PlatformTheme { + if (this.electron.nativeTheme.shouldUseDarkColors) { + return 'dark' + } else { + return 'light' + } + } } class ElectronFileUpload extends FileUpload { diff --git a/tabby-terminal/src/api/baseTerminalTab.component.ts b/tabby-terminal/src/api/baseTerminalTab.component.ts index c1adf56dfe..8c89074560 100644 --- a/tabby-terminal/src/api/baseTerminalTab.component.ts +++ b/tabby-terminal/src/api/baseTerminalTab.component.ts @@ -331,6 +331,10 @@ export class BaseTerminalTabComponent

extends Bas this.frontend?.focus() }) + this.subscribeUntilDestroyed(this.platform.themeChanged$, () => { + this.configure() + }) + const cls: new (..._) => Frontend = { xterm: XTermFrontend, 'xterm-webgl': XTermWebGLFrontend, diff --git a/tabby-terminal/src/colorSchemes.ts b/tabby-terminal/src/colorSchemes.ts index 22b799c53a..32e763e874 100644 --- a/tabby-terminal/src/colorSchemes.ts +++ b/tabby-terminal/src/colorSchemes.ts @@ -27,9 +27,41 @@ export class DefaultColorSchemes extends TerminalColorSchemeProvider { '#b7fff9', '#ffffff', ], + selection: undefined, + cursorAccent: undefined, + } + + static defaultLightColorScheme: TerminalColorScheme = { + name: 'Tabby Default Light', + foreground: '#4d4d4c', + background: '#ffffff', + cursor: '#4d4d4c', + colors: [ + '#000000', + '#c82829', + '#718c00', + '#eab700', + '#4271ae', + '#8959a8', + '#3e999f', + '#ffffff', + '#000000', + '#c82829', + '#718c00', + '#eab700', + '#4271ae', + '#8959a8', + '#3e999f', + '#ffffff', + ], + selection: undefined, + cursorAccent: undefined, } async getSchemes (): Promise { - return [DefaultColorSchemes.defaultColorScheme] + return [ + DefaultColorSchemes.defaultColorScheme, + DefaultColorSchemes.defaultLightColorScheme, + ] } } diff --git a/tabby-terminal/src/components/colorSchemeSettingsForMode.component.pug b/tabby-terminal/src/components/colorSchemeSettingsForMode.component.pug new file mode 100644 index 0000000000..31f73b8563 --- /dev/null +++ b/tabby-terminal/src/components/colorSchemeSettingsForMode.component.pug @@ -0,0 +1,116 @@ +.head + .d-flex.align-items-center(*ngIf='!editing') + strong.me-2(translate) Current color scheme + span {{getCurrentSchemeName()}} + .me-auto + .btn-toolbar + button.btn.btn-secondary((click)='editScheme()') + i.fas.fa-pen + span(translate) Edit + .me-1 + button.btn.btn-danger( + (click)='deleteScheme(config.store.terminal[this.configKey])', + *ngIf='currentCustomScheme' + ) + i.fas.fa-trash + span(translate) Delete + + div(*ngIf='editing') + .mb-3 + label(translate) Name + input.form-control(type='text', [(ngModel)]='config.store.terminal[this.configKey].name') + + .mb-3 + color-picker( + [(model)]='config.store.terminal[this.configKey].foreground', + (modelChange)='config.save()', + title='FG', + hint='Foreground' + ) + color-picker( + [(model)]='config.store.terminal[this.configKey].background', + (modelChange)='config.save()', + title='BG', + hint='Background' + ) + color-picker( + [(model)]='config.store.terminal[this.configKey].cursor', + (modelChange)='config.save()', + title='CU', + hint='Cursor color' + ) + color-picker( + [(model)]='config.store.terminal[this.configKey].cursorAccent', + (modelChange)='config.save()', + title='CA', + hint='Block cursor foreground' + ) + color-picker( + [(model)]='config.store.terminal[this.configKey].selection', + (modelChange)='config.save()', + title='SB', + hint='Selection background' + ) + color-picker( + [(model)]='config.store.terminal[this.configKey].selectionForeground', + (modelChange)='config.save()', + title='SF', + hint='Selection foreground' + ) + color-picker( + *ngFor='let _ of config.store.terminal[this.configKey].colors; let idx = index; trackBy: colorsTrackBy', + [(model)]='config.store.terminal[this.configKey].colors[idx]', + (modelChange)='config.save()', + [title]='idx.toString()', + hint='ANSI color {{idx}}' + ) + + color-scheme-preview([scheme]='config.store.terminal[this.configKey]') + + .btn-toolbar.d-flex.mt-2(*ngIf='editing') + .me-auto + button.btn.btn-primary((click)='saveScheme()') + i.fas.fa-check + span(translate) Save + .me-1 + button.btn.btn-secondary((click)='cancelEditing()') + i.fas.fa-times + span(translate) Cancel + + hr.mt-3.mb-4 + + .input-group.mb-3 + .input-group-text + i.fas.fa-fw.fa-search + input.form-control(type='search', [placeholder]='"Search color schemes"|translate', [(ngModel)]='filter') + +.body + .list-group.list-group-light.mb-3 + ng-container(*ngFor='let scheme of allColorSchemes') + .list-group-item.list-group-item-action( + [hidden]='filter && !scheme.name.toLowerCase().includes(filter.toLowerCase())', + (click)='selectScheme(scheme)', + [class.active]='(currentCustomScheme || currentStockScheme) === scheme' + ) + .d-flex.w-100.align-items-center + i.fas.fa-fw([class.fa-check]='(currentCustomScheme || currentStockScheme) === scheme') + + .ms-2 + + .me-auto + span {{scheme.name}} + .badge.text-bg-info.ms-2(*ngIf='customColorSchemes.includes(scheme)', translate) Custom + + div + .d-flex + .swatch( + *ngFor='let index of colorIndexes.slice(0, 8)', + [style.background-color]='scheme.colors[index]' + ) + .d-flex + .swatch( + *ngFor='let index of colorIndexes.slice(8, 16)', + [style.background-color]='scheme.colors[index]' + ) + + color-scheme-preview([scheme]='scheme') diff --git a/tabby-terminal/src/components/colorSchemeSettingsTab.component.scss b/tabby-terminal/src/components/colorSchemeSettingsForMode.component.scss similarity index 100% rename from tabby-terminal/src/components/colorSchemeSettingsTab.component.scss rename to tabby-terminal/src/components/colorSchemeSettingsForMode.component.scss diff --git a/tabby-terminal/src/components/colorSchemeSettingsForMode.component.ts b/tabby-terminal/src/components/colorSchemeSettingsForMode.component.ts new file mode 100644 index 0000000000..1adeb69c8a --- /dev/null +++ b/tabby-terminal/src/components/colorSchemeSettingsForMode.component.ts @@ -0,0 +1,117 @@ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +import deepEqual from 'deep-equal' +import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker' + +import { Component, Inject, Input, ChangeDetectionStrategy, ChangeDetectorRef, HostBinding } from '@angular/core' +import { ConfigService, PlatformService, TranslateService } from 'tabby-core' +import { TerminalColorSchemeProvider } from '../api/colorSchemeProvider' +import { TerminalColorScheme } from '../api/interfaces' + +_('Search color schemes') + +/** @hidden */ +@Component({ + selector: 'color-scheme-settings-for-mode', + templateUrl: './colorSchemeSettingsForMode.component.pug', + styleUrls: ['./colorSchemeSettingsForMode.component.scss'], + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class ColorSchemeSettingsForModeComponent { + @Input() configKey: 'colorScheme'|'lightColorScheme' + + @Input() stockColorSchemes: TerminalColorScheme[] = [] + @Input() customColorSchemes: TerminalColorScheme[] = [] + @Input() allColorSchemes: TerminalColorScheme[] = [] + @Input() filter = '' + @Input() editing = false + colorIndexes = [...new Array(16).keys()] + + currentStockScheme: TerminalColorScheme|null = null + currentCustomScheme: TerminalColorScheme|null = null + + @HostBinding('class.content-box') true + + constructor ( + @Inject(TerminalColorSchemeProvider) private colorSchemeProviders: TerminalColorSchemeProvider[], + private changeDetector: ChangeDetectorRef, + private platform: PlatformService, + private translate: TranslateService, + public config: ConfigService, + ) { } + + async ngOnInit () { + this.stockColorSchemes = (await Promise.all(this.config.enabledServices(this.colorSchemeProviders).map(x => x.getSchemes()))).reduce((a, b) => a.concat(b)) + this.stockColorSchemes.sort((a, b) => a.name.localeCompare(b.name)) + this.customColorSchemes = this.config.store.terminal.customColorSchemes + this.changeDetector.markForCheck() + + this.update() + } + + ngOnChanges () { + this.update() + } + + selectScheme (scheme: TerminalColorScheme) { + this.config.store.terminal[this.configKey] = { ...scheme } + this.config.save() + this.cancelEditing() + this.update() + } + + update () { + this.currentCustomScheme = this.findMatchingScheme(this.config.store.terminal[this.configKey], this.customColorSchemes) + this.currentStockScheme = this.findMatchingScheme(this.config.store.terminal[this.configKey], this.stockColorSchemes) + this.allColorSchemes = this.customColorSchemes.concat(this.stockColorSchemes) + this.changeDetector.markForCheck() + } + + editScheme () { + this.editing = true + } + + saveScheme () { + this.customColorSchemes = this.customColorSchemes.filter(x => x.name !== this.config.store.terminal[this.configKey].name) + this.customColorSchemes.push(this.config.store.terminal[this.configKey]) + this.config.store.terminal.customColorSchemes = this.customColorSchemes + this.config.save() + this.cancelEditing() + this.update() + } + + cancelEditing () { + this.editing = false + } + + async deleteScheme (scheme: TerminalColorScheme) { + if ((await this.platform.showMessageBox( + { + type: 'warning', + message: this.translate.instant('Delete "{name}"?', scheme), + buttons: [ + this.translate.instant('Delete'), + this.translate.instant('Keep'), + ], + defaultId: 1, + cancelId: 1, + }, + )).response === 0) { + this.customColorSchemes = this.customColorSchemes.filter(x => x.name !== scheme.name) + this.config.store.terminal.customColorSchemes = this.customColorSchemes + this.config.save() + this.update() + } + } + + getCurrentSchemeName () { + return (this.currentCustomScheme ?? this.currentStockScheme)?.name ?? 'Custom' + } + + findMatchingScheme (scheme: TerminalColorScheme, schemes: TerminalColorScheme[]) { + return schemes.find(x => deepEqual(x, scheme)) ?? null + } + + colorsTrackBy (index) { + return index + } +} diff --git a/tabby-terminal/src/components/colorSchemeSettingsTab.component.pug b/tabby-terminal/src/components/colorSchemeSettingsTab.component.pug index 21444a2c7c..dfc2294f8f 100644 --- a/tabby-terminal/src/components/colorSchemeSettingsTab.component.pug +++ b/tabby-terminal/src/components/colorSchemeSettingsTab.component.pug @@ -1,117 +1,14 @@ -.head - h3.mb-3(translate) Current color scheme +h3.mb-3(translate) Color schemes - .d-flex.align-items-center(*ngIf='!editing') - span {{getCurrentSchemeName()}} - .me-auto - .btn-toolbar - button.btn.btn-secondary((click)='editScheme()') - i.fas.fa-pen - span(translate) Edit - .me-1 - button.btn.btn-danger( - (click)='deleteScheme(config.store.terminal.colorScheme)', - *ngIf='currentCustomScheme' - ) - i.fas.fa-trash - span(translate) Delete +ul.nav-tabs(ngbNav, #nav='ngbNav', [activeId]='defaultTab') + li(ngbNavItem='dark') + a(ngbNavLink, translate) Dark mode + ng-template(ngbNavContent) + color-scheme-settings-for-mode(configKey='colorScheme') - div(*ngIf='editing') - .mb-3 - label(translate) Name - input.form-control(type='text', [(ngModel)]='config.store.terminal.colorScheme.name') + li(ngbNavItem='light') + a(ngbNavLink, translate) Light mode + ng-template(ngbNavContent) + color-scheme-settings-for-mode(configKey='lightColorScheme') - .mb-3 - color-picker( - [(model)]='config.store.terminal.colorScheme.foreground', - (modelChange)='config.save()', - title='FG', - hint='Foreground' - ) - color-picker( - [(model)]='config.store.terminal.colorScheme.background', - (modelChange)='config.save()', - title='BG', - hint='Background' - ) - color-picker( - [(model)]='config.store.terminal.colorScheme.cursor', - (modelChange)='config.save()', - title='CU', - hint='Cursor color' - ) - color-picker( - [(model)]='config.store.terminal.colorScheme.cursorAccent', - (modelChange)='config.save()', - title='CA', - hint='Block cursor foreground' - ) - color-picker( - [(model)]='config.store.terminal.colorScheme.selection', - (modelChange)='config.save()', - title='SB', - hint='Selection background' - ) - color-picker( - [(model)]='config.store.terminal.colorScheme.selectionForeground', - (modelChange)='config.save()', - title='SF', - hint='Selection foreground' - ) - color-picker( - *ngFor='let _ of config.store.terminal.colorScheme.colors; let idx = index; trackBy: colorsTrackBy', - [(model)]='config.store.terminal.colorScheme.colors[idx]', - (modelChange)='config.save()', - [title]='idx.toString()', - hint='ANSI color {{idx}}' - ) - - color-scheme-preview([scheme]='config.store.terminal.colorScheme') - - .btn-toolbar.d-flex.mt-2(*ngIf='editing') - .me-auto - button.btn.btn-primary((click)='saveScheme()') - i.fas.fa-check - span(translate) Save - .me-1 - button.btn.btn-secondary((click)='cancelEditing()') - i.fas.fa-times - span(translate) Cancel - - hr.mt-3.mb-4 - - .input-group.mb-3 - .input-group-text - i.fas.fa-fw.fa-search - input.form-control(type='search', [placeholder]='"Search color schemes"|translate', [(ngModel)]='filter') - -.body - .list-group.list-group-light.mb-3 - ng-container(*ngFor='let scheme of allColorSchemes') - .list-group-item.list-group-item-action( - [hidden]='filter && !scheme.name.toLowerCase().includes(filter.toLowerCase())', - (click)='selectScheme(scheme)', - [class.active]='(currentCustomScheme || currentStockScheme) === scheme' - ) - .d-flex.w-100.align-items-center - i.fas.fa-fw([class.fa-check]='(currentCustomScheme || currentStockScheme) === scheme') - - .ms-2 - - .me-auto - span {{scheme.name}} - .badge.text-bg-info.ms-2(*ngIf='customColorSchemes.includes(scheme)', translate) Custom - - div - .d-flex - .swatch( - *ngFor='let index of colorIndexes.slice(0, 8)', - [style.background-color]='scheme.colors[index]' - ) - .d-flex - .swatch( - *ngFor='let index of colorIndexes.slice(8, 16)', - [style.background-color]='scheme.colors[index]' - ) - - color-scheme-preview([scheme]='scheme') +div([ngbNavOutlet]='nav') diff --git a/tabby-terminal/src/components/colorSchemeSettingsTab.component.ts b/tabby-terminal/src/components/colorSchemeSettingsTab.component.ts index 03443ea435..dc2d849fa8 100644 --- a/tabby-terminal/src/components/colorSchemeSettingsTab.component.ts +++ b/tabby-terminal/src/components/colorSchemeSettingsTab.component.ts @@ -1,114 +1,16 @@ -/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ -import deepEqual from 'deep-equal' -import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker' - -import { Component, Inject, Input, ChangeDetectionStrategy, ChangeDetectorRef, HostBinding } from '@angular/core' -import { ConfigService, PlatformService, TranslateService } from 'tabby-core' -import { TerminalColorSchemeProvider } from '../api/colorSchemeProvider' -import { TerminalColorScheme } from '../api/interfaces' - -_('Search color schemes') +import { Component } from '@angular/core' +import { PlatformService } from 'tabby-core' /** @hidden */ @Component({ templateUrl: './colorSchemeSettingsTab.component.pug', - styleUrls: ['./colorSchemeSettingsTab.component.scss'], - changeDetection: ChangeDetectionStrategy.OnPush, }) export class ColorSchemeSettingsTabComponent { - @Input() stockColorSchemes: TerminalColorScheme[] = [] - @Input() customColorSchemes: TerminalColorScheme[] = [] - @Input() allColorSchemes: TerminalColorScheme[] = [] - @Input() filter = '' - @Input() editing = false - colorIndexes = [...new Array(16).keys()] - - currentStockScheme: TerminalColorScheme|null = null - currentCustomScheme: TerminalColorScheme|null = null - - @HostBinding('class.content-box') true + defaultTab = 'dark' constructor ( - @Inject(TerminalColorSchemeProvider) private colorSchemeProviders: TerminalColorSchemeProvider[], - private changeDetector: ChangeDetectorRef, - private platform: PlatformService, - private translate: TranslateService, - public config: ConfigService, - ) { } - - async ngOnInit () { - this.stockColorSchemes = (await Promise.all(this.config.enabledServices(this.colorSchemeProviders).map(x => x.getSchemes()))).reduce((a, b) => a.concat(b)) - this.stockColorSchemes.sort((a, b) => a.name.localeCompare(b.name)) - this.customColorSchemes = this.config.store.terminal.customColorSchemes - this.changeDetector.markForCheck() - - this.update() - } - - ngOnChanges () { - this.update() - } - - selectScheme (scheme: TerminalColorScheme) { - this.config.store.terminal.colorScheme = { ...scheme } - this.config.save() - this.cancelEditing() - this.update() - } - - update () { - this.currentCustomScheme = this.findMatchingScheme(this.config.store.terminal.colorScheme, this.customColorSchemes) - this.currentStockScheme = this.findMatchingScheme(this.config.store.terminal.colorScheme, this.stockColorSchemes) - this.allColorSchemes = this.customColorSchemes.concat(this.stockColorSchemes) - this.changeDetector.markForCheck() - } - - editScheme () { - this.editing = true - } - - saveScheme () { - this.customColorSchemes = this.customColorSchemes.filter(x => x.name !== this.config.store.terminal.colorScheme.name) - this.customColorSchemes.push(this.config.store.terminal.colorScheme) - this.config.store.terminal.customColorSchemes = this.customColorSchemes - this.config.save() - this.cancelEditing() - this.update() - } - - cancelEditing () { - this.editing = false - } - - async deleteScheme (scheme: TerminalColorScheme) { - if ((await this.platform.showMessageBox( - { - type: 'warning', - message: this.translate.instant('Delete "{name}"?', scheme), - buttons: [ - this.translate.instant('Delete'), - this.translate.instant('Keep'), - ], - defaultId: 1, - cancelId: 1, - }, - )).response === 0) { - this.customColorSchemes = this.customColorSchemes.filter(x => x.name !== scheme.name) - this.config.store.terminal.customColorSchemes = this.customColorSchemes - this.config.save() - this.update() - } - } - - getCurrentSchemeName () { - return (this.currentCustomScheme ?? this.currentStockScheme)?.name ?? 'Custom' - } - - findMatchingScheme (scheme: TerminalColorScheme, schemes: TerminalColorScheme[]) { - return schemes.find(x => deepEqual(x, scheme)) ?? null - } - - colorsTrackBy (index) { - return index + platform: PlatformService, + ) { + this.defaultTab = platform.getTheme() } } diff --git a/tabby-terminal/src/config.ts b/tabby-terminal/src/config.ts index 25a7531710..2daf66f640 100644 --- a/tabby-terminal/src/config.ts +++ b/tabby-terminal/src/config.ts @@ -33,10 +33,12 @@ export class TerminalConfigProvider extends ConfigProvider { wordSeparator: ' ()[]{}\'"', colorScheme: { __nonStructural: true, - selection: null, - cursorAccent: null, ...DefaultColorSchemes.defaultColorScheme, }, + lightColorScheme: { + __nonStructural: true, + ...DefaultColorSchemes.defaultLightColorScheme, + }, customColorSchemes: [], warnOnMultilinePaste: true, searchRegexAlwaysEnabled: false, diff --git a/tabby-terminal/src/frontends/xtermFrontend.ts b/tabby-terminal/src/frontends/xtermFrontend.ts index 309a819f76..bfec17657e 100644 --- a/tabby-terminal/src/frontends/xtermFrontend.ts +++ b/tabby-terminal/src/frontends/xtermFrontend.ts @@ -363,7 +363,7 @@ export class XTermFrontend extends Frontend { private configureColors (scheme: TerminalColorScheme|undefined): void { const config = this.configService.store - scheme = scheme ?? config.terminal.colorScheme + scheme = scheme ?? this.themes._getActiveColorScheme() const theme: ITheme = { foreground: scheme!.foreground, diff --git a/tabby-terminal/src/index.ts b/tabby-terminal/src/index.ts index 2ae09431b7..7622612440 100644 --- a/tabby-terminal/src/index.ts +++ b/tabby-terminal/src/index.ts @@ -19,6 +19,7 @@ import { LoginScriptsSettingsComponent } from './components/loginScriptsSettings import { TerminalToolbarComponent } from './components/terminalToolbar.component' import { ColorSchemeSelectorComponent } from './components/colorSchemeSelector.component' import { InputProcessingSettingsComponent } from './components/inputProcessingSettings.component' +import { ColorSchemeSettingsForModeComponent } from './components/colorSchemeSettingsForMode.component' import { TerminalDecorator } from './api/decorator' import { TerminalContextMenuItemProvider } from './api/contextMenuProvider' @@ -78,6 +79,7 @@ import { DefaultColorSchemes } from './colorSchemes' LoginScriptsSettingsComponent, TerminalToolbarComponent, InputProcessingSettingsComponent, + ColorSchemeSettingsForModeComponent, ], exports: [ ColorPickerComponent,