mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-10-21 18:54:01 -04:00
feat(theme): terminal background opacity and wallpaper-tinted colors (#3662)
This commit is contained in:
@@ -28,9 +28,13 @@ func init() {
|
||||
dank16Cmd.Flags().Bool("wezterm", false, "Output in Wezterm terminal format")
|
||||
dank16Cmd.Flags().String("background", "", "Custom background color")
|
||||
dank16Cmd.Flags().String("contrast", "dps", "Contrast algorithm: dps (Delta Phi Star, default) or wcag")
|
||||
dank16Cmd.Flags().String("profile", "default", "Palette: default, low, medium or high")
|
||||
dank16Cmd.Flags().Bool("variants", false, "Output all variants (dark/light/default) in JSON")
|
||||
dank16Cmd.Flags().String("primary-dark", "", "Primary color for dark mode (use with --variants)")
|
||||
dank16Cmd.Flags().String("primary-light", "", "Primary color for light mode (use with --variants)")
|
||||
_ = dank16Cmd.RegisterFlagCompletionFunc("profile", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return []string{"default", "low", "medium", "high"}, cobra.ShellCompDirectiveNoFileComp
|
||||
})
|
||||
_ = dank16Cmd.RegisterFlagCompletionFunc("contrast", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return []string{"dps", "wcag"}, cobra.ShellCompDirectiveNoFileComp
|
||||
})
|
||||
@@ -47,6 +51,7 @@ func runDank16(cmd *cobra.Command, args []string) {
|
||||
isWezterm, _ := cmd.Flags().GetBool("wezterm")
|
||||
background, _ := cmd.Flags().GetString("background")
|
||||
contrastAlgo, _ := cmd.Flags().GetString("contrast")
|
||||
profile, _ := cmd.Flags().GetString("profile")
|
||||
useVariants, _ := cmd.Flags().GetBool("variants")
|
||||
primaryDark, _ := cmd.Flags().GetString("primary-dark")
|
||||
primaryLight, _ := cmd.Flags().GetString("primary-light")
|
||||
@@ -84,6 +89,7 @@ func runDank16(cmd *cobra.Command, args []string) {
|
||||
BackgroundDark: background,
|
||||
UseDPS: contrastAlgo == "dps",
|
||||
IsLightMode: isLight,
|
||||
Profile: profile,
|
||||
}
|
||||
variantColors := dank16.GenerateVariantPalette(variantOpts)
|
||||
fmt.Print(dank16.GenerateVariantJSON(variantColors))
|
||||
@@ -102,6 +108,7 @@ func runDank16(cmd *cobra.Command, args []string) {
|
||||
IsLight: isLight,
|
||||
Background: background,
|
||||
UseDPS: contrastAlgo == "dps",
|
||||
Profile: profile,
|
||||
}
|
||||
|
||||
colors := dank16.GeneratePalette(primaryColor, opts)
|
||||
|
||||
@@ -70,6 +70,8 @@ func init() {
|
||||
cmd.Flags().String("stock-colors", "", "Stock theme colors JSON")
|
||||
cmd.Flags().Bool("sync-mode-with-portal", false, "Sync color scheme with GNOME portal")
|
||||
cmd.Flags().Bool("terminals-always-dark", false, "Force terminal themes to dark variant")
|
||||
cmd.Flags().Int("terminal-opacity", 0, "Terminal background opacity percent, 1-99 (0 or 100 leaves the terminal's own setting)")
|
||||
cmd.Flags().String("terminal-palette", "", "Terminal palette: default, low, medium or high")
|
||||
cmd.Flags().String("skip-templates", "", "Comma-separated list of templates to skip")
|
||||
cmd.Flags().Float64("contrast", 0, "Contrast value from -1 to 1 (0 = standard)")
|
||||
cmd.Flags().String("source-mode", "", "Source color selection: dominant, colorful, darkness, lightness, saturation, less-saturation, value")
|
||||
@@ -100,6 +102,8 @@ func buildMatugenOptions(cmd *cobra.Command) matugen.Options {
|
||||
stockColors, _ := cmd.Flags().GetString("stock-colors")
|
||||
syncModeWithPortal, _ := cmd.Flags().GetBool("sync-mode-with-portal")
|
||||
terminalsAlwaysDark, _ := cmd.Flags().GetBool("terminals-always-dark")
|
||||
terminalOpacity, _ := cmd.Flags().GetInt("terminal-opacity")
|
||||
terminalPalette, _ := cmd.Flags().GetString("terminal-palette")
|
||||
skipTemplates, _ := cmd.Flags().GetString("skip-templates")
|
||||
contrast, _ := cmd.Flags().GetFloat64("contrast")
|
||||
sourceMode, _ := cmd.Flags().GetString("source-mode")
|
||||
@@ -120,6 +124,8 @@ func buildMatugenOptions(cmd *cobra.Command) matugen.Options {
|
||||
StockColors: stockColors,
|
||||
SyncModeWithPortal: syncModeWithPortal,
|
||||
TerminalsAlwaysDark: terminalsAlwaysDark,
|
||||
TerminalOpacity: terminalOpacity,
|
||||
TerminalPalette: terminalPalette,
|
||||
SkipTemplates: skipTemplates,
|
||||
SourceMode: sourceMode,
|
||||
SeedColor: seedColor,
|
||||
@@ -159,6 +165,8 @@ func runMatugenQueue(cmd *cobra.Command, args []string) {
|
||||
"stockColors": opts.StockColors,
|
||||
"syncModeWithPortal": opts.SyncModeWithPortal,
|
||||
"terminalsAlwaysDark": opts.TerminalsAlwaysDark,
|
||||
"terminalOpacity": opts.TerminalOpacity,
|
||||
"terminalPalette": opts.TerminalPalette,
|
||||
"skipTemplates": opts.SkipTemplates,
|
||||
"contrast": opts.Contrast,
|
||||
"sourceMode": opts.SourceMode,
|
||||
|
||||
@@ -4,7 +4,10 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/AvengeMedia/dankgo/material/color"
|
||||
"github.com/AvengeMedia/dankgo/material/num"
|
||||
"github.com/lucasb-eyer/go-colorful"
|
||||
)
|
||||
|
||||
@@ -452,11 +455,64 @@ func EnsureContrastDPSBidirectional(hexColor, hexBg string, minLc float64, isLig
|
||||
return hexColor
|
||||
}
|
||||
|
||||
const (
|
||||
ProfileLow = "low"
|
||||
ProfileMedium = "medium"
|
||||
ProfileHigh = "high"
|
||||
)
|
||||
|
||||
var profileStrength = map[string]float64{ProfileLow: 0.25, ProfileMedium: 0.5, ProfileHigh: 0.85}
|
||||
|
||||
type PaletteOptions struct {
|
||||
IsLight bool
|
||||
Background string
|
||||
Container string
|
||||
UseDPS bool
|
||||
Profile string
|
||||
}
|
||||
|
||||
func rotateTowardPrimary(hex string, primary color.Hct, strength float64) string {
|
||||
argb, err := color.ARGBFromHex(hex)
|
||||
if err != nil {
|
||||
return hex
|
||||
}
|
||||
c := argb.ToHct()
|
||||
rot := math.Min(num.DifferenceDegrees(c.Hue, primary.Hue)*0.8, 100) * strength
|
||||
hue := num.NormalizeDegree(c.Hue + rot*num.RotationDirection(c.Hue, primary.Hue))
|
||||
return strings.ToLower(color.NewHct(hue, c.Chroma, c.Tone).ToARGB().HexRGB())
|
||||
}
|
||||
|
||||
func applyProfile(p *Palette, primaryColor, bg string, normalTarget, accentTarget float64, opts PaletteOptions) {
|
||||
strength := profileStrength[opts.Profile]
|
||||
if strength == 0 {
|
||||
return
|
||||
}
|
||||
argb, err := color.ARGBFromHex(primaryColor)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
primary := argb.ToHct()
|
||||
// A near-grey primary has no usable hue to rotate toward.
|
||||
if primary.Chroma < 5 {
|
||||
return
|
||||
}
|
||||
normal := func(h string) string { return ensureContrastAuto(h, bg, normalTarget, opts) }
|
||||
accent := func(h string) string { return ensureContrastBidirectional(h, bg, accentTarget, opts) }
|
||||
none := func(h string) string { return h }
|
||||
// Same per-slot contrast guards GeneratePalette applies.
|
||||
slots := []struct {
|
||||
c *ColorInfo
|
||||
guard func(string) string
|
||||
}{
|
||||
{&p.Color1, normal}, {&p.Color2, normal}, {&p.Color3, normal}, {&p.Color4, normal},
|
||||
{&p.Color9, accent}, {&p.Color10, accent}, {&p.Color11, accent}, {&p.Color12, accent}, {&p.Color13, none}, {&p.Color14, none},
|
||||
}
|
||||
if opts.IsLight {
|
||||
slots[8].guard = accent
|
||||
}
|
||||
for _, s := range slots {
|
||||
*s.c = NewColorInfo(s.guard(rotateTowardPrimary(s.c.Hex, primary, strength)))
|
||||
}
|
||||
}
|
||||
|
||||
func ensureContrastAuto(hexColor, hexBg string, target float64, opts PaletteOptions) string {
|
||||
@@ -690,6 +746,8 @@ func GeneratePalette(primaryColor string, opts PaletteOptions) Palette {
|
||||
palette.Color15 = NewColorInfo(ensureContrastAuto(RGBToHex(HSVToRGB(HSV{H: hsv.H, S: white15S, V: white15V})), bgColor, normalTextTarget, opts))
|
||||
}
|
||||
|
||||
applyProfile(&palette, primaryColor, bgColor, normalTextTarget, accentTarget, opts)
|
||||
|
||||
return palette
|
||||
}
|
||||
|
||||
@@ -702,6 +760,7 @@ type VariantOptions struct {
|
||||
ContainerLight string
|
||||
UseDPS bool
|
||||
IsLightMode bool
|
||||
Profile string
|
||||
}
|
||||
|
||||
func mergeColorInfo(dark, light ColorInfo, isLightMode bool) VariantColorInfo {
|
||||
@@ -718,8 +777,8 @@ func mergeColorInfo(dark, light ColorInfo, isLightMode bool) VariantColorInfo {
|
||||
}
|
||||
|
||||
func GenerateVariantPalette(opts VariantOptions) VariantPalette {
|
||||
darkOpts := PaletteOptions{IsLight: false, Background: opts.BackgroundDark, Container: opts.ContainerDark, UseDPS: opts.UseDPS}
|
||||
lightOpts := PaletteOptions{IsLight: true, Background: opts.BackgroundLight, Container: opts.ContainerLight, UseDPS: opts.UseDPS}
|
||||
darkOpts := PaletteOptions{IsLight: false, Background: opts.BackgroundDark, Container: opts.ContainerDark, UseDPS: opts.UseDPS, Profile: opts.Profile}
|
||||
lightOpts := PaletteOptions{IsLight: true, Background: opts.BackgroundLight, Container: opts.ContainerLight, UseDPS: opts.UseDPS, Profile: opts.Profile}
|
||||
|
||||
dark := GeneratePalette(opts.PrimaryDark, darkOpts)
|
||||
light := GeneratePalette(opts.PrimaryLight, lightOpts)
|
||||
|
||||
@@ -4,7 +4,11 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/AvengeMedia/dankgo/material/color"
|
||||
"github.com/AvengeMedia/dankgo/material/num"
|
||||
)
|
||||
|
||||
func TestHexToRGB(t *testing.T) {
|
||||
@@ -786,3 +790,139 @@ func TestGeneratePaletteFallsBackToDerivedContainer(t *testing.T) {
|
||||
t.Errorf("Color5 = %s with no container supplied, expected the derived %s", palette.Color5.Hex, want)
|
||||
}
|
||||
}
|
||||
|
||||
func paletteHexes(p Palette) [16]string {
|
||||
return [16]string{
|
||||
p.Color0.Hex, p.Color1.Hex, p.Color2.Hex, p.Color3.Hex, p.Color4.Hex, p.Color5.Hex, p.Color6.Hex, p.Color7.Hex,
|
||||
p.Color8.Hex, p.Color9.Hex, p.Color10.Hex, p.Color11.Hex, p.Color12.Hex, p.Color13.Hex, p.Color14.Hex, p.Color15.Hex,
|
||||
}
|
||||
}
|
||||
|
||||
func hctHue(hex string) float64 {
|
||||
return color.ARGBFromHexMust(hex).ToHct().Hue
|
||||
}
|
||||
|
||||
func TestDefaultProfileUnchanged(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
light bool
|
||||
want [16]string
|
||||
}{
|
||||
{"dark", false, [16]string{"#1a1a1a", "#ff72a0", "#77ee84", "#fff672", "#70bfe2", "#19546e", "#8ad0ee", "#eaf5f9", "#444b4d", "#ff9fbe", "#a5ffaf", "#fff9a5", "#a3e3ff", "#b3e8ff", "#cef0ff", "#f8fdff"}},
|
||||
{"light", true, [16]string{"#f8f8f8", "#c23c6c", "#00811d", "#727300", "#1a7895", "#dcf4ff", "#8ad0ee", "#3f4142", "#b8bbbc", "#dc608a", "#009f29", "#8f8e00", "#3993b4", "#5c90a6", "#c9eeff", "#f9fdff"}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
for _, profile := range []string{"", "default", "bogus"} {
|
||||
got := paletteHexes(GeneratePalette("#8ad0ee", PaletteOptions{UseDPS: true, IsLight: tt.light, Profile: profile}))
|
||||
if got != tt.want {
|
||||
t.Errorf("profile %q drifted:\n got %v\nwant %v", profile, got, tt.want)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestProfileGoldens(t *testing.T) {
|
||||
tests := []struct {
|
||||
profile string
|
||||
light bool
|
||||
want string
|
||||
}{
|
||||
{ProfileLow, false, "#1a1a1a #ea77d9 #31f2a9 #d6ffa0 #70bfe2 #19546e #8ad0ee #eaf5f9 #444b4d #eca4e1 #98ffce #e4ffbf #a3e3ff #b3e8ff #cef0ff #f8fdff"},
|
||||
{ProfileMedium, false, "#1a1a1a #c684ff #00f0ce #c8ffd2 #6fbfe1 #19546e #8ad0ee #eaf5f9 #444b4d #d2abf8 #89ffe6 #daffdf #a3e3ff #b4e8ff #cff0ff #f8fdff"},
|
||||
{ProfileHigh, false, "#1a1a1a #879bff #00ecf6 #b8fff6 #6fbfe1 #19546e #8ad0ee #eaf5f9 #444b4d #a7b8ff #a1f9ff #d0fff8 #a3e3ff #b4e8ff #cff0ff #f8fdff"},
|
||||
{ProfileLow, true, "#f8f8f8 #b240a4 #007f51 #507a2b #1a7895 #dcf4ff #8ad0ee #3f4142 #b8bbbc #c964bb #009d65 #669737 #3993b4 #5c90a6 #c9eeff #f9fdff"},
|
||||
{ProfileMedium, true, "#f8f8f8 #944bcf #007d68 #1d7f4c #1a7895 #dcf4ff #8ad0ee #3f4142 #b8bbbc #ab6fe0 #009b82 #2a9c5f #3993b4 #5c90a6 #c9eeff #f9fdff"},
|
||||
{ProfileHigh, true, "#f8f8f8 #4562e9 #007b7f #007d76 #1b7895 #dcf4ff #8ad0ee #3f4142 #b8bbbc #6882f3 #00989d #009a91 #3993b4 #5c90a6 #caeeff #f9fdff"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := paletteHexes(GeneratePalette("#8ad0ee", PaletteOptions{UseDPS: true, IsLight: tt.light, Profile: tt.profile}))
|
||||
if s := strings.Join(got[:], " "); s != tt.want {
|
||||
t.Errorf("%s light=%v:\n got %s\nwant %s", tt.profile, tt.light, s, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProfileMalformedPrimaryDoesNotPanic(t *testing.T) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
t.Fatalf("panicked: %v", r)
|
||||
}
|
||||
}()
|
||||
GeneratePalette("not-a-color", PaletteOptions{UseDPS: true, Profile: ProfileHigh})
|
||||
GeneratePalette("#12345", PaletteOptions{UseDPS: true, Profile: ProfileHigh})
|
||||
GeneratePalette("#8ad0ee", PaletteOptions{UseDPS: true, Container: "steelblue", Profile: ProfileLow})
|
||||
GeneratePalette("#8ad0ee", PaletteOptions{UseDPS: true, Container: "#12345", Profile: ProfileLow})
|
||||
}
|
||||
|
||||
var profiles = []string{ProfileLow, ProfileMedium, ProfileHigh}
|
||||
|
||||
func TestProfileInvariants(t *testing.T) {
|
||||
for _, primary := range []string{"#e91e63", "#f59e0b", "#22c55e", "#06b6d4", "#8b5cf6", "#8ad0ee"} {
|
||||
for _, light := range []bool{false, true} {
|
||||
def := PaletteOptions{UseDPS: true, IsLight: light}
|
||||
dh := paletteHexes(GeneratePalette(primary, def))
|
||||
for _, profile := range profiles {
|
||||
opts := def
|
||||
opts.Profile = profile
|
||||
hh := paletteHexes(GeneratePalette(primary, opts))
|
||||
for _, i := range []int{0, 5, 6, 7, 8, 15} {
|
||||
if dh[i] != hh[i] {
|
||||
t.Errorf("%s %s light=%v slot %d: %s != default %s", primary, profile, light, i, hh[i], dh[i])
|
||||
}
|
||||
}
|
||||
for i := 1; i <= 4; i++ {
|
||||
if lc := DeltaPhiStarContrast(hh[i], hh[0], light); lc < 30 {
|
||||
t.Errorf("%s %s light=%v slot %d Lc %.1f < 30", primary, profile, light, i, lc)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestProfileHueApproachesPrimaryWithStrength(t *testing.T) {
|
||||
const primary = "#1e66f5"
|
||||
ph := hctHue(primary)
|
||||
for _, light := range []bool{false, true} {
|
||||
prev := math.Inf(1)
|
||||
for _, profile := range append([]string{""}, profiles...) {
|
||||
red := GeneratePalette(primary, PaletteOptions{UseDPS: true, IsLight: light, Profile: profile}).Color1.Hex
|
||||
d := num.DifferenceDegrees(hctHue(red), ph)
|
||||
if d >= prev {
|
||||
t.Errorf("light=%v %q: red hue distance %.1f not below previous %.1f", light, profile, d, prev)
|
||||
}
|
||||
prev = d
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHighRotatesByCappedAmount(t *testing.T) {
|
||||
def := hctHue(GeneratePalette("#8ad0ee", PaletteOptions{UseDPS: true}).Color1.Hex)
|
||||
got := hctHue(GeneratePalette("#8ad0ee", PaletteOptions{UseDPS: true, Profile: ProfileHigh}).Color1.Hex)
|
||||
if d := num.DifferenceDegrees(def, got); math.Abs(d-85) > 3 {
|
||||
t.Errorf("slot 1 rotated %.1f degrees, want 85 (the 100 degree cap at high strength)", d)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProfileGreyPrimaryKeepsDefault(t *testing.T) {
|
||||
def := paletteHexes(GeneratePalette("#808080", PaletteOptions{UseDPS: true}))
|
||||
high := paletteHexes(GeneratePalette("#808080", PaletteOptions{UseDPS: true, Profile: ProfileHigh}))
|
||||
if def != high {
|
||||
t.Errorf("grey primary changed by high profile:\n got %v\nwant %v", high, def)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateVariantPaletteProfile(t *testing.T) {
|
||||
opts := VariantOptions{PrimaryDark: "#8ad0ee", PrimaryLight: "#1c5070", UseDPS: true}
|
||||
def := GenerateVariantPalette(opts)
|
||||
opts.Profile = ProfileHigh
|
||||
high := GenerateVariantPalette(opts)
|
||||
if def.Color1.Dark.Hex == high.Color1.Dark.Hex {
|
||||
t.Error("dark color1 unchanged by high profile")
|
||||
}
|
||||
if def.Color1.Light.Hex == high.Color1.Light.Hex {
|
||||
t.Error("light color1 unchanged by high profile")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,8 @@ type Options struct {
|
||||
StockColors string
|
||||
SyncModeWithPortal bool
|
||||
TerminalsAlwaysDark bool
|
||||
TerminalOpacity int
|
||||
TerminalPalette string
|
||||
SkipTemplates string
|
||||
AppChecker utils.AppChecker
|
||||
}
|
||||
@@ -441,8 +443,9 @@ func buildOnce(opts *Options) (bool, error) {
|
||||
primaryLight = primaryDark
|
||||
}
|
||||
|
||||
dank16JSON = generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight, containerDark, containerLight, opts.Mode)
|
||||
importData := fmt.Sprintf(`{"colors": %s, "dank16": %s}`, opts.StockColors, dank16JSON)
|
||||
dank16JSON = generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight, containerDark, containerLight, opts.Mode, "")
|
||||
dank16TermJSON := generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight, containerDark, containerLight, opts.Mode, opts.TerminalPalette)
|
||||
importData := fmt.Sprintf(`{"colors": %s, "dank16": %s, "dank16term": %s}`, opts.StockColors, dank16JSON, dank16TermJSON)
|
||||
importArgs = []string{"--import-json-string", importData}
|
||||
|
||||
log.Info("Running matugen color hex with stock color overrides")
|
||||
@@ -510,9 +513,10 @@ func buildOnce(opts *Options) (bool, error) {
|
||||
primaryLight = primaryDark
|
||||
}
|
||||
|
||||
injections := InjectedPalettes(opts.ConfigDir, sourceImage, opts.Mode)
|
||||
|
||||
dank16JSON = generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight, containerDark, containerLight, opts.Mode)
|
||||
dank16JSON = generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight, containerDark, containerLight, opts.Mode, "")
|
||||
// The terminal palette only reaches the terminal templates; editor themes and user templates keep dank16.
|
||||
dank16Term := paletteInjection{Namespace: "dank16term", JSON: generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight, containerDark, containerLight, opts.Mode, opts.TerminalPalette)}
|
||||
injections := append([]paletteInjection{dank16Term}, InjectedPalettes(opts.ConfigDir, sourceImage, opts.Mode)...)
|
||||
importArgs = []string{"--import-json-string", buildImportData(dank16JSON, sourceImage, specColors, injections)}
|
||||
|
||||
log.Infof("Running matugen %s with dank16 injection", opts.Kind)
|
||||
@@ -537,6 +541,7 @@ func buildOnce(opts *Options) (bool, error) {
|
||||
if err := renderTemplates(opts, args, tmpDir); err != nil {
|
||||
return false, err
|
||||
}
|
||||
signalTerminals(opts)
|
||||
if !changed {
|
||||
return false, nil
|
||||
}
|
||||
@@ -569,7 +574,6 @@ func buildOnce(opts *Options) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
signalTerminals(opts)
|
||||
if !opts.ShouldSkipTemplate("fcitx5") && appExists(opts.AppChecker, []string{"fcitx5"}, nil) {
|
||||
refreshFcitx5()
|
||||
}
|
||||
@@ -836,7 +840,7 @@ func appendTerminalConfig(opts *Options, cfgFile *os.File, tmpDir string, checkC
|
||||
|
||||
content := string(data)
|
||||
|
||||
if !opts.TerminalsAlwaysDark {
|
||||
if !opts.TerminalsAlwaysDark && !terminalOpacityManaged(opts) {
|
||||
cfgFile.WriteString(substituteVars(content, opts.ShellDir))
|
||||
cfgFile.WriteString("\n")
|
||||
return
|
||||
@@ -864,7 +868,7 @@ func appendTerminalConfig(opts *Options, cfgFile *os.File, tmpDir string, checkC
|
||||
continue
|
||||
}
|
||||
|
||||
modified := strings.ReplaceAll(string(origData), ".default.", ".dark.")
|
||||
modified := applyTerminalTemplate(templateName, string(origData), opts)
|
||||
tmpPath := filepath.Join(tmpDir, templateName)
|
||||
if err := os.WriteFile(tmpPath, []byte(modified), 0o644); err != nil {
|
||||
continue
|
||||
@@ -879,6 +883,37 @@ func appendTerminalConfig(opts *Options, cfgFile *os.File, tmpDir string, checkC
|
||||
cfgFile.WriteString("\n")
|
||||
}
|
||||
|
||||
func terminalOpacityManaged(opts *Options) bool {
|
||||
return opts.TerminalOpacity >= 1 && opts.TerminalOpacity <= 99
|
||||
}
|
||||
|
||||
func applyTerminalTemplate(name, content string, opts *Options) string {
|
||||
if opts.TerminalsAlwaysDark {
|
||||
content = strings.ReplaceAll(content, ".default.", ".dark.")
|
||||
}
|
||||
if !terminalOpacityManaged(opts) {
|
||||
return content
|
||||
}
|
||||
v := strconv.FormatFloat(float64(opts.TerminalOpacity)/100, 'f', -1, 64)
|
||||
var snippet string
|
||||
switch name {
|
||||
case "kitty.conf":
|
||||
snippet = "background_opacity " + v + "\ndynamic_background_opacity yes\n"
|
||||
case "foot.ini":
|
||||
snippet = "alpha=" + v + "\n"
|
||||
case "ghostty.conf":
|
||||
snippet = "background-opacity = " + v + "\n"
|
||||
case "alacritty.toml":
|
||||
snippet = "[window]\nopacity = " + v + "\n"
|
||||
default:
|
||||
return content
|
||||
}
|
||||
if content != "" && !strings.HasSuffix(content, "\n") {
|
||||
content += "\n"
|
||||
}
|
||||
return content + snippet
|
||||
}
|
||||
|
||||
func templateSessionActive(tmpl TemplateDef) bool {
|
||||
if tmpl.RequiredEnv == "" {
|
||||
return true
|
||||
@@ -1331,7 +1366,7 @@ func extractNestedColor(jsonStr, colorName, variant string) string {
|
||||
return color
|
||||
}
|
||||
|
||||
func generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight, containerDark, containerLight string, mode ColorMode) string {
|
||||
func generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight, containerDark, containerLight string, mode ColorMode, profile string) string {
|
||||
variantOpts := dank16.VariantOptions{
|
||||
PrimaryDark: primaryDark,
|
||||
PrimaryLight: primaryLight,
|
||||
@@ -1341,6 +1376,7 @@ func generateDank16Variants(primaryDark, primaryLight, surfaceDark, surfaceLight
|
||||
ContainerLight: containerLight,
|
||||
UseDPS: true,
|
||||
IsLightMode: mode == ColorModeLight,
|
||||
Profile: profile,
|
||||
}
|
||||
variantColors := dank16.GenerateVariantPalette(variantOpts)
|
||||
return dank16.GenerateVariantJSON(variantColors)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"math"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -1159,3 +1160,128 @@ func TestWriteDryRunConfigAlwaysDeclaresConfigAndTemplates(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyTerminalTemplate(t *testing.T) {
|
||||
opts := func(v int, dark bool) *Options { return &Options{TerminalOpacity: v, TerminalsAlwaysDark: dark} }
|
||||
tests := []struct {
|
||||
name, tmpl, in, want string
|
||||
opts *Options
|
||||
}{
|
||||
{"kitty", "kitty.conf", "a\n", "a\nbackground_opacity 0.85\ndynamic_background_opacity yes\n", opts(85, false)},
|
||||
{"foot", "foot.ini", "a\n", "a\nalpha=0.85\n", opts(85, false)},
|
||||
{"ghostty", "ghostty.conf", "a\n", "a\nbackground-opacity = 0.85\n", opts(85, false)},
|
||||
{"alacritty", "alacritty.toml", "a\n", "a\n[window]\nopacity = 0.85\n", opts(85, false)},
|
||||
{"no trailing newline", "foot.ini", "a", "a\nalpha=0.5\n", opts(50, false)},
|
||||
{"100", "kitty.conf", "a\n", "a\n", opts(100, false)},
|
||||
{"0", "kitty.conf", "a\n", "a\n", opts(0, false)},
|
||||
{"negative", "kitty.conf", "a\n", "a\n", opts(-5, false)},
|
||||
{"tabs", "kitty-tabs.conf", "a\n", "a\n", opts(85, false)},
|
||||
{"wezterm", "wezterm.toml", "a\n", "a\n", opts(85, false)},
|
||||
{"dark and opacity", "kitty.conf", "x.default.y\n", "x.dark.y\nbackground_opacity 0.85\ndynamic_background_opacity yes\n", opts(85, true)},
|
||||
{"opacity only keeps default", "kitty.conf", "x.default.y\n", "x.default.y\nbackground_opacity 0.85\ndynamic_background_opacity yes\n", opts(85, false)},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, applyTerminalTemplate(tt.tmpl, tt.in, tt.opts))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendTerminalConfigOpacity(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
shellDir := filepath.Join(tempDir, "shell")
|
||||
cfgDir := filepath.Join(shellDir, "matugen", "configs")
|
||||
tmplDir := filepath.Join(shellDir, "matugen", "templates")
|
||||
for _, d := range []string{cfgDir, tmplDir} {
|
||||
if err := os.MkdirAll(d, 0o755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
toml := "[templates.dmskitty]\ninput_path = 'SHELL_DIR/matugen/templates/kitty.conf'\noutput_path = 'out/kitty'\n\n" +
|
||||
"[templates.dmskittytabs]\ninput_path = 'SHELL_DIR/matugen/templates/kitty-tabs.conf'\noutput_path = 'out/tabs'\n"
|
||||
for name, c := range map[string]string{
|
||||
filepath.Join(cfgDir, "kitty.toml"): toml,
|
||||
filepath.Join(tmplDir, "kitty.conf"): "color0 {{x}}\n",
|
||||
filepath.Join(tmplDir, "kitty-tabs.conf"): "tab {{x}}\n",
|
||||
} {
|
||||
if err := os.WriteFile(name, []byte(c), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
run := func(opacity int) (string, string) {
|
||||
runTmp := t.TempDir()
|
||||
checker := mocks_utils.NewMockAppChecker(t)
|
||||
checker.EXPECT().AnyCommandExists("kitty").Return(true)
|
||||
out := filepath.Join(runTmp, "out.toml")
|
||||
f, err := os.Create(out)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
opts := &Options{ShellDir: shellDir, AppChecker: checker, TerminalOpacity: opacity}
|
||||
appendTerminalConfig(opts, f, runTmp, []string{"kitty"}, nil, "kitty.toml")
|
||||
f.Close()
|
||||
b, _ := os.ReadFile(out)
|
||||
return string(b), runTmp
|
||||
}
|
||||
|
||||
got, runTmp := run(85)
|
||||
kittyCopy := filepath.Join(runTmp, "kitty.conf")
|
||||
tabsCopy := filepath.Join(runTmp, "kitty-tabs.conf")
|
||||
assert.Contains(t, got, "input_path = '"+kittyCopy+"'")
|
||||
assert.Contains(t, got, "input_path = '"+tabsCopy+"'")
|
||||
b, err := os.ReadFile(kittyCopy)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, strings.HasSuffix(string(b), "background_opacity 0.85\ndynamic_background_opacity yes\n"))
|
||||
b, err = os.ReadFile(tabsCopy)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "tab {{x}}\n", string(b))
|
||||
|
||||
got, runTmp = run(0)
|
||||
assert.Equal(t, substituteVars(toml, shellDir)+"\n", got)
|
||||
_, err = os.Stat(filepath.Join(runTmp, "kitty.conf"))
|
||||
assert.True(t, os.IsNotExist(err))
|
||||
}
|
||||
|
||||
func TestGenerateDank16VariantsProfile(t *testing.T) {
|
||||
gen := func(profile string) map[string]any {
|
||||
out := generateDank16Variants("#8ad0ee", "#1c5070", "#0f1417", "#f5fafd", "#1b2023", "#e9eef2", ColorModeDark, profile)
|
||||
var m map[string]any
|
||||
if err := json.Unmarshal([]byte(out), &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return m
|
||||
}
|
||||
def, high := gen(""), gen("high")
|
||||
assert.NotEqual(t, def["color1"], high["color1"])
|
||||
assert.Equal(t, def["color0"], high["color0"])
|
||||
}
|
||||
|
||||
func TestTerminalPaletteOnlyReachesTerminalTemplates(t *testing.T) {
|
||||
shellDir := filepath.Join("..", "..", "..", "quickshell")
|
||||
inputPath := regexp.MustCompile(`input_path = 'SHELL_DIR/([^']+)'`)
|
||||
checked := 0
|
||||
for _, def := range templateRegistry {
|
||||
if def.ConfigFile == "" {
|
||||
continue
|
||||
}
|
||||
config, err := os.ReadFile(filepath.Join(shellDir, "matugen", "configs", def.ConfigFile))
|
||||
if !assert.NoError(t, err) {
|
||||
continue
|
||||
}
|
||||
for _, m := range inputPath.FindAllStringSubmatch(string(config), -1) {
|
||||
data, err := os.ReadFile(filepath.Join(shellDir, m[1]))
|
||||
if !assert.NoError(t, err) {
|
||||
continue
|
||||
}
|
||||
content := string(data)
|
||||
if def.Kind == TemplateKindTerminal {
|
||||
assert.NotContains(t, content, "{{dank16.", "%s: terminal templates read dank16term", m[1])
|
||||
} else {
|
||||
assert.NotContains(t, content, "dank16term", "%s: only terminal templates follow the terminal palette", m[1])
|
||||
}
|
||||
checked++
|
||||
}
|
||||
}
|
||||
assert.Greater(t, checked, 10)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ func handleMatugenQueue(conn *ipc.ConnWriter, req ipc.Request) {
|
||||
StockColors: req.GetOr("stockColors", ""),
|
||||
SyncModeWithPortal: req.GetOr("syncModeWithPortal", false),
|
||||
TerminalsAlwaysDark: req.GetOr("terminalsAlwaysDark", false),
|
||||
TerminalOpacity: int(req.GetOr("terminalOpacity", 0.0)),
|
||||
TerminalPalette: req.GetOr("terminalPalette", ""),
|
||||
SkipTemplates: req.GetOr("skipTemplates", ""),
|
||||
Contrast: req.GetOr("contrast", 0.0),
|
||||
SourceMode: req.GetOr("sourceMode", ""),
|
||||
|
||||
@@ -746,6 +746,8 @@ Singleton {
|
||||
|
||||
property bool syncModeWithPortal: Spec.SPEC.syncModeWithPortal.def
|
||||
property bool terminalsAlwaysDark: Spec.SPEC.terminalsAlwaysDark.def
|
||||
property int terminalOpacity: Spec.SPEC.terminalOpacity.def
|
||||
property string terminalPalette: Spec.SPEC.terminalPalette.def
|
||||
|
||||
property string muxType: Spec.SPEC.muxType.def
|
||||
property bool muxUseCustomCommand: Spec.SPEC.muxUseCustomCommand.def
|
||||
|
||||
@@ -1791,6 +1791,12 @@ Singleton {
|
||||
if (typeof SettingsData !== "undefined" && SettingsData.terminalsAlwaysDark) {
|
||||
args.push("--terminals-always-dark");
|
||||
}
|
||||
if (typeof SettingsData !== "undefined" && SettingsData.terminalOpacity < 100) {
|
||||
args.push("--terminal-opacity", SettingsData.terminalOpacity.toString());
|
||||
}
|
||||
if (typeof SettingsData !== "undefined" && SettingsData.terminalPalette !== "default") {
|
||||
args.push("--terminal-palette", SettingsData.terminalPalette);
|
||||
}
|
||||
if (typeof SettingsData !== "undefined" && SettingsData.matugenContrast !== 0) {
|
||||
args.push("--contrast", SettingsData.matugenContrast.toString());
|
||||
}
|
||||
|
||||
@@ -1121,6 +1121,14 @@ var LOCAL_SPEC = {
|
||||
def: false,
|
||||
onChange: "regenSystemThemes"
|
||||
},
|
||||
terminalOpacity: {
|
||||
def: 100,
|
||||
onChange: "regenSystemThemes"
|
||||
},
|
||||
terminalPalette: {
|
||||
def: "default",
|
||||
onChange: "regenSystemThemes"
|
||||
},
|
||||
muxType: {
|
||||
def: "tmux"
|
||||
},
|
||||
|
||||
@@ -132,6 +132,41 @@ Item {
|
||||
checked: SettingsData.terminalsAlwaysDark
|
||||
onToggled: checked => SettingsData.set("terminalsAlwaysDark", checked)
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["terminal", "opacity", "transparency", "background", "kitty", "foot", "ghostty", "alacritty"]
|
||||
settingKey: "terminalOpacity"
|
||||
text: I18n.tr("Opacity")
|
||||
value: SettingsData.terminalOpacity
|
||||
minimum: 10
|
||||
maximum: 100
|
||||
unit: "%"
|
||||
enabled: Theme.matugenAvailable
|
||||
onSliderDragFinished: finalValue => SettingsData.set("terminalOpacity", finalValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["terminal", "palette", "ansi", "colors", "wallpaper", "intensity"]
|
||||
settingKey: "terminalPalette"
|
||||
text: I18n.tr("Colors from wallpaper")
|
||||
enabled: Theme.matugenAvailable
|
||||
checked: SettingsData.terminalPalette !== "default"
|
||||
onToggled: checked => SettingsData.set("terminalPalette", checked ? "medium" : "default")
|
||||
}
|
||||
|
||||
SettingsButtonGroupRow {
|
||||
text: I18n.tr("Intensity")
|
||||
description: I18n.tr("How far terminal colors shift toward the wallpaper color", "terminal wallpaper colors intensity description")
|
||||
visible: SettingsData.terminalPalette !== "default"
|
||||
enabled: Theme.matugenAvailable
|
||||
model: [I18n.tr("Low"), I18n.tr("Medium"), I18n.tr("High")]
|
||||
values: ["low", "medium", "high"]
|
||||
value: SettingsData.terminalPalette
|
||||
fallbackValue: "medium"
|
||||
onValueSelected: value => SettingsData.set("terminalPalette", value)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
|
||||
@@ -11,21 +11,21 @@ text = '{{colors.background.default.hex}}'
|
||||
cursor = '{{colors.primary.default.hex}}'
|
||||
|
||||
[colors.normal]
|
||||
black = '{{dank16.color0.default.hex}}'
|
||||
red = '{{dank16.color1.default.hex}}'
|
||||
green = '{{dank16.color2.default.hex}}'
|
||||
yellow = '{{dank16.color3.default.hex}}'
|
||||
blue = '{{dank16.color4.default.hex}}'
|
||||
magenta = '{{dank16.color5.default.hex}}'
|
||||
cyan = '{{dank16.color6.default.hex}}'
|
||||
white = '{{dank16.color7.default.hex}}'
|
||||
black = '{{dank16term.color0.default.hex}}'
|
||||
red = '{{dank16term.color1.default.hex}}'
|
||||
green = '{{dank16term.color2.default.hex}}'
|
||||
yellow = '{{dank16term.color3.default.hex}}'
|
||||
blue = '{{dank16term.color4.default.hex}}'
|
||||
magenta = '{{dank16term.color5.default.hex}}'
|
||||
cyan = '{{dank16term.color6.default.hex}}'
|
||||
white = '{{dank16term.color7.default.hex}}'
|
||||
|
||||
[colors.bright]
|
||||
black = '{{dank16.color8.default.hex}}'
|
||||
red = '{{dank16.color9.default.hex}}'
|
||||
green = '{{dank16.color10.default.hex}}'
|
||||
yellow = '{{dank16.color11.default.hex}}'
|
||||
blue = '{{dank16.color12.default.hex}}'
|
||||
magenta = '{{dank16.color13.default.hex}}'
|
||||
cyan = '{{dank16.color14.default.hex}}'
|
||||
white = '{{dank16.color15.default.hex}}'
|
||||
black = '{{dank16term.color8.default.hex}}'
|
||||
red = '{{dank16term.color9.default.hex}}'
|
||||
green = '{{dank16term.color10.default.hex}}'
|
||||
yellow = '{{dank16term.color11.default.hex}}'
|
||||
blue = '{{dank16term.color12.default.hex}}'
|
||||
magenta = '{{dank16term.color13.default.hex}}'
|
||||
cyan = '{{dank16term.color14.default.hex}}'
|
||||
white = '{{dank16term.color15.default.hex}}'
|
||||
|
||||
@@ -5,21 +5,21 @@ selection-foreground={{colors.on_surface.default.hex_stripped}}
|
||||
selection-background={{colors.primary_container.default.hex_stripped}}
|
||||
cursor = {{colors.background.default.hex_stripped}} {{colors.primary.default.hex_stripped}}
|
||||
|
||||
regular0={{dank16.color0.default.hex_stripped}}
|
||||
regular1={{dank16.color1.default.hex_stripped}}
|
||||
regular2={{dank16.color2.default.hex_stripped}}
|
||||
regular3={{dank16.color3.default.hex_stripped}}
|
||||
regular4={{dank16.color4.default.hex_stripped}}
|
||||
regular5={{dank16.color5.default.hex_stripped}}
|
||||
regular6={{dank16.color6.default.hex_stripped}}
|
||||
regular7={{dank16.color7.default.hex_stripped}}
|
||||
bright0={{dank16.color8.default.hex_stripped}}
|
||||
bright1={{dank16.color9.default.hex_stripped}}
|
||||
bright2={{dank16.color10.default.hex_stripped}}
|
||||
bright3={{dank16.color11.default.hex_stripped}}
|
||||
bright4={{dank16.color12.default.hex_stripped}}
|
||||
bright5={{dank16.color13.default.hex_stripped}}
|
||||
bright6={{dank16.color14.default.hex_stripped}}
|
||||
bright7={{dank16.color15.default.hex_stripped}}
|
||||
regular0={{dank16term.color0.default.hex_stripped}}
|
||||
regular1={{dank16term.color1.default.hex_stripped}}
|
||||
regular2={{dank16term.color2.default.hex_stripped}}
|
||||
regular3={{dank16term.color3.default.hex_stripped}}
|
||||
regular4={{dank16term.color4.default.hex_stripped}}
|
||||
regular5={{dank16term.color5.default.hex_stripped}}
|
||||
regular6={{dank16term.color6.default.hex_stripped}}
|
||||
regular7={{dank16term.color7.default.hex_stripped}}
|
||||
bright0={{dank16term.color8.default.hex_stripped}}
|
||||
bright1={{dank16term.color9.default.hex_stripped}}
|
||||
bright2={{dank16term.color10.default.hex_stripped}}
|
||||
bright3={{dank16term.color11.default.hex_stripped}}
|
||||
bright4={{dank16term.color12.default.hex_stripped}}
|
||||
bright5={{dank16term.color13.default.hex_stripped}}
|
||||
bright6={{dank16term.color14.default.hex_stripped}}
|
||||
bright7={{dank16term.color15.default.hex_stripped}}
|
||||
|
||||
dim-blend-towards=<* if {{ is_dark_mode }} *>black<* else *>white<* endif *>
|
||||
|
||||
@@ -4,19 +4,19 @@ cursor-color = {{colors.primary.default.hex}}
|
||||
selection-background = {{colors.primary_container.default.hex}}
|
||||
selection-foreground = {{colors.on_surface.default.hex}}
|
||||
|
||||
palette = 0={{dank16.color0.default.hex}}
|
||||
palette = 1={{dank16.color1.default.hex}}
|
||||
palette = 2={{dank16.color2.default.hex}}
|
||||
palette = 3={{dank16.color3.default.hex}}
|
||||
palette = 4={{dank16.color4.default.hex}}
|
||||
palette = 5={{dank16.color5.default.hex}}
|
||||
palette = 6={{dank16.color6.default.hex}}
|
||||
palette = 7={{dank16.color7.default.hex}}
|
||||
palette = 8={{dank16.color8.default.hex}}
|
||||
palette = 9={{dank16.color9.default.hex}}
|
||||
palette = 10={{dank16.color10.default.hex}}
|
||||
palette = 11={{dank16.color11.default.hex}}
|
||||
palette = 12={{dank16.color12.default.hex}}
|
||||
palette = 13={{dank16.color13.default.hex}}
|
||||
palette = 14={{dank16.color14.default.hex}}
|
||||
palette = 15={{dank16.color15.default.hex}}
|
||||
palette = 0={{dank16term.color0.default.hex}}
|
||||
palette = 1={{dank16term.color1.default.hex}}
|
||||
palette = 2={{dank16term.color2.default.hex}}
|
||||
palette = 3={{dank16term.color3.default.hex}}
|
||||
palette = 4={{dank16term.color4.default.hex}}
|
||||
palette = 5={{dank16term.color5.default.hex}}
|
||||
palette = 6={{dank16term.color6.default.hex}}
|
||||
palette = 7={{dank16term.color7.default.hex}}
|
||||
palette = 8={{dank16term.color8.default.hex}}
|
||||
palette = 9={{dank16term.color9.default.hex}}
|
||||
palette = 10={{dank16term.color10.default.hex}}
|
||||
palette = 11={{dank16term.color11.default.hex}}
|
||||
palette = 12={{dank16term.color12.default.hex}}
|
||||
palette = 13={{dank16term.color13.default.hex}}
|
||||
palette = 14={{dank16term.color14.default.hex}}
|
||||
palette = 15={{dank16term.color15.default.hex}}
|
||||
|
||||
@@ -7,19 +7,19 @@ selection_foreground {{colors.on_secondary.default.hex}}
|
||||
selection_background {{colors.secondary_fixed_dim.default.hex}}
|
||||
url_color {{colors.primary.default.hex}}
|
||||
|
||||
color0 {{dank16.color0.default.hex}}
|
||||
color1 {{dank16.color1.default.hex}}
|
||||
color2 {{dank16.color2.default.hex}}
|
||||
color3 {{dank16.color3.default.hex}}
|
||||
color4 {{dank16.color4.default.hex}}
|
||||
color5 {{dank16.color5.default.hex}}
|
||||
color6 {{dank16.color6.default.hex}}
|
||||
color7 {{dank16.color7.default.hex}}
|
||||
color8 {{dank16.color8.default.hex}}
|
||||
color9 {{dank16.color9.default.hex}}
|
||||
color10 {{dank16.color10.default.hex}}
|
||||
color11 {{dank16.color11.default.hex}}
|
||||
color12 {{dank16.color12.default.hex}}
|
||||
color13 {{dank16.color13.default.hex}}
|
||||
color14 {{dank16.color14.default.hex}}
|
||||
color15 {{dank16.color15.default.hex}}
|
||||
color0 {{dank16term.color0.default.hex}}
|
||||
color1 {{dank16term.color1.default.hex}}
|
||||
color2 {{dank16term.color2.default.hex}}
|
||||
color3 {{dank16term.color3.default.hex}}
|
||||
color4 {{dank16term.color4.default.hex}}
|
||||
color5 {{dank16term.color5.default.hex}}
|
||||
color6 {{dank16term.color6.default.hex}}
|
||||
color7 {{dank16term.color7.default.hex}}
|
||||
color8 {{dank16term.color8.default.hex}}
|
||||
color9 {{dank16term.color9.default.hex}}
|
||||
color10 {{dank16term.color10.default.hex}}
|
||||
color11 {{dank16term.color11.default.hex}}
|
||||
color12 {{dank16term.color12.default.hex}}
|
||||
color13 {{dank16term.color13.default.hex}}
|
||||
color14 {{dank16term.color14.default.hex}}
|
||||
color15 {{dank16term.color15.default.hex}}
|
||||
|
||||
@@ -9,5 +9,5 @@ cursor_border = '{{colors.primary.default.hex}}'
|
||||
selection_bg = '{{colors.primary_container.default.hex}}'
|
||||
selection_fg = '{{colors.on_surface.default.hex}}'
|
||||
|
||||
ansi = ['{{dank16.color0.default.hex}}', '{{dank16.color1.default.hex}}', '{{dank16.color2.default.hex}}', '{{dank16.color3.default.hex}}', '{{dank16.color4.default.hex}}', '{{dank16.color5.default.hex}}', '{{dank16.color6.default.hex}}', '{{dank16.color7.default.hex}}']
|
||||
brights = ['{{dank16.color8.default.hex}}', '{{dank16.color9.default.hex}}', '{{dank16.color10.default.hex}}', '{{dank16.color11.default.hex}}', '{{dank16.color12.default.hex}}', '{{dank16.color13.default.hex}}', '{{dank16.color14.default.hex}}', '{{dank16.color15.default.hex}}']
|
||||
ansi = ['{{dank16term.color0.default.hex}}', '{{dank16term.color1.default.hex}}', '{{dank16term.color2.default.hex}}', '{{dank16term.color3.default.hex}}', '{{dank16term.color4.default.hex}}', '{{dank16term.color5.default.hex}}', '{{dank16term.color6.default.hex}}', '{{dank16term.color7.default.hex}}']
|
||||
brights = ['{{dank16term.color8.default.hex}}', '{{dank16term.color9.default.hex}}', '{{dank16term.color10.default.hex}}', '{{dank16term.color11.default.hex}}', '{{dank16term.color12.default.hex}}', '{{dank16term.color13.default.hex}}', '{{dank16term.color14.default.hex}}', '{{dank16term.color15.default.hex}}']
|
||||
|
||||
@@ -14709,6 +14709,32 @@
|
||||
"parentLabel": "Wallpaper & colors",
|
||||
"description": "GTK, Qt, portal, matugen templates"
|
||||
},
|
||||
{
|
||||
"section": "terminalPalette",
|
||||
"label": "Colors from wallpaper",
|
||||
"tabIndex": 50,
|
||||
"category": "App theming",
|
||||
"keywords": [
|
||||
"ansi",
|
||||
"app",
|
||||
"background",
|
||||
"bg",
|
||||
"colors",
|
||||
"colour",
|
||||
"colours",
|
||||
"desktop",
|
||||
"hue",
|
||||
"image",
|
||||
"intensity",
|
||||
"palette",
|
||||
"picture",
|
||||
"terminal",
|
||||
"theming",
|
||||
"tint",
|
||||
"wallpaper"
|
||||
],
|
||||
"parentLabel": "Wallpaper & colors"
|
||||
},
|
||||
{
|
||||
"section": "matugenTemplateNeovimSettings",
|
||||
"label": "Dark mode base",
|
||||
@@ -15023,6 +15049,36 @@
|
||||
"icon": "auto_awesome",
|
||||
"conditionKey": "matugenAvailable"
|
||||
},
|
||||
{
|
||||
"section": "terminalOpacity",
|
||||
"label": "Opacity",
|
||||
"tabIndex": 50,
|
||||
"category": "App theming",
|
||||
"keywords": [
|
||||
"alacritty",
|
||||
"app",
|
||||
"background",
|
||||
"bg",
|
||||
"colors",
|
||||
"colour",
|
||||
"colours",
|
||||
"desktop",
|
||||
"foot",
|
||||
"ghostty",
|
||||
"hue",
|
||||
"image",
|
||||
"kitty",
|
||||
"opacity",
|
||||
"palette",
|
||||
"picture",
|
||||
"terminal",
|
||||
"theming",
|
||||
"tint",
|
||||
"transparency",
|
||||
"wallpaper"
|
||||
],
|
||||
"parentLabel": "Wallpaper & colors"
|
||||
},
|
||||
{
|
||||
"section": "applications",
|
||||
"label": "Portal & terminals",
|
||||
|
||||
Reference in New Issue
Block a user