1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-03 20:32:07 -04:00

theme(greeter): fix auto theme accent variants & update selections

This commit is contained in:
purian23
2026-03-17 13:27:57 -04:00
parent 5c4ce86da4
commit 59dae954cd
6 changed files with 425 additions and 34 deletions

View File

@@ -1497,6 +1497,20 @@ func checkGreeterStatus() error {
}
fmt.Println("\nConfiguration Symlinks:")
colorSyncInfo, colorSyncErr := greeter.ResolveGreeterColorSyncInfo(homeDir)
if colorSyncErr != nil {
fmt.Printf(" ✗ Failed to resolve expected greeter color source: %v\n", colorSyncErr)
allGood = false
colorSyncInfo = greeter.GreeterColorSyncInfo{
SourcePath: filepath.Join(homeDir, ".cache", "DankMaterialShell", "dms-colors.json"),
}
}
colorThemeDesc := "Color theme"
if colorSyncInfo.UsesDynamicWallpaperOverride {
colorThemeDesc = "Color theme (greeter wallpaper override)"
}
symlinks := []struct {
source string
target string
@@ -1513,9 +1527,9 @@ func checkGreeterStatus() error {
desc: "Session state",
},
{
source: filepath.Join(homeDir, ".cache", "DankMaterialShell", "dms-colors.json"),
source: colorSyncInfo.SourcePath,
target: filepath.Join(cacheDir, "colors.json"),
desc: "Color theme",
desc: colorThemeDesc,
},
}
@@ -1557,6 +1571,10 @@ func checkGreeterStatus() error {
fmt.Printf(" ✓ %s: synced correctly\n", link.desc)
}
if colorSyncInfo.UsesDynamicWallpaperOverride {
fmt.Printf(" Dynamic theme uses greeter override colors from %s\n", colorSyncInfo.SourcePath)
}
fmt.Println("\nGreeter Wallpaper Override:")
overridePath := filepath.Join(cacheDir, "greeter_wallpaper_override.jpg")
if stat, err := os.Stat(overridePath); err == nil && !stat.IsDir() {

View File

@@ -5,6 +5,7 @@ import (
"context"
_ "embed"
"encoding/json"
"errors"
"fmt"
"os"
"os/exec"
@@ -14,6 +15,7 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/internal/config"
"github.com/AvengeMedia/DankMaterialShell/core/internal/distros"
"github.com/AvengeMedia/DankMaterialShell/core/internal/matugen"
"github.com/AvengeMedia/DankMaterialShell/core/internal/utils"
"github.com/sblinch/kdl-go"
"github.com/sblinch/kdl-go/document"
@@ -1074,6 +1076,7 @@ func SetupDMSGroup(logFunc func(string), sudoPassword string) error {
}{
{filepath.Join(homeDir, ".config", "DankMaterialShell"), "DankMaterialShell config"},
{filepath.Join(homeDir, ".local", "state", "DankMaterialShell"), "DankMaterialShell state"},
{filepath.Join(homeDir, ".cache", "DankMaterialShell"), "DankMaterialShell cache"},
{filepath.Join(homeDir, ".cache", "quickshell"), "quickshell cache"},
{filepath.Join(homeDir, ".config", "quickshell"), "quickshell config"},
{filepath.Join(homeDir, ".local", "share", "wayland-sessions"), "wayland sessions"},
@@ -1108,6 +1111,217 @@ func SetupDMSGroup(logFunc func(string), sudoPassword string) error {
return nil
}
type GreeterColorSyncInfo struct {
SourcePath string
ThemeName string
UsesDynamicWallpaperOverride bool
}
type greeterThemeSyncSettings struct {
CurrentThemeName string `json:"currentThemeName"`
GreeterWallpaperPath string `json:"greeterWallpaperPath"`
MatugenScheme string `json:"matugenScheme"`
IconTheme string `json:"iconTheme"`
}
type greeterThemeSyncSession struct {
IsLightMode bool `json:"isLightMode"`
}
type greeterThemeSyncState struct {
ThemeName string
GreeterWallpaperPath string
ResolvedGreeterWallpaperPath string
MatugenScheme string
IconTheme string
IsLightMode bool
UsesDynamicWallpaperOverride bool
}
func defaultGreeterColorsSource(homeDir string) string {
return filepath.Join(homeDir, ".cache", "DankMaterialShell", "dms-colors.json")
}
func greeterOverrideColorsStateDir(homeDir string) string {
return filepath.Join(homeDir, ".cache", "DankMaterialShell", "greeter-colors")
}
func greeterOverrideColorsSource(homeDir string) string {
return filepath.Join(greeterOverrideColorsStateDir(homeDir), "dms-colors.json")
}
func readOptionalJSONFile(path string, dst any) error {
data, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return err
}
if strings.TrimSpace(string(data)) == "" {
return nil
}
return json.Unmarshal(data, dst)
}
func readGreeterThemeSyncSettings(homeDir string) (greeterThemeSyncSettings, error) {
settings := greeterThemeSyncSettings{
CurrentThemeName: "purple",
MatugenScheme: "scheme-tonal-spot",
IconTheme: "System Default",
}
settingsPath := filepath.Join(homeDir, ".config", "DankMaterialShell", "settings.json")
if err := readOptionalJSONFile(settingsPath, &settings); err != nil {
return greeterThemeSyncSettings{}, fmt.Errorf("failed to parse settings at %s: %w", settingsPath, err)
}
return settings, nil
}
func readGreeterThemeSyncSession(homeDir string) (greeterThemeSyncSession, error) {
session := greeterThemeSyncSession{}
sessionPath := filepath.Join(homeDir, ".local", "state", "DankMaterialShell", "session.json")
if err := readOptionalJSONFile(sessionPath, &session); err != nil {
return greeterThemeSyncSession{}, fmt.Errorf("failed to parse session at %s: %w", sessionPath, err)
}
return session, nil
}
func resolveGreeterThemeSyncState(homeDir string) (greeterThemeSyncState, error) {
settings, err := readGreeterThemeSyncSettings(homeDir)
if err != nil {
return greeterThemeSyncState{}, err
}
session, err := readGreeterThemeSyncSession(homeDir)
if err != nil {
return greeterThemeSyncState{}, err
}
resolvedWallpaperPath := ""
if settings.GreeterWallpaperPath != "" {
resolvedWallpaperPath = settings.GreeterWallpaperPath
if !filepath.IsAbs(resolvedWallpaperPath) {
resolvedWallpaperPath = filepath.Join(homeDir, resolvedWallpaperPath)
}
}
usesDynamicWallpaperOverride := strings.EqualFold(strings.TrimSpace(settings.CurrentThemeName), "dynamic") && resolvedWallpaperPath != ""
return greeterThemeSyncState{
ThemeName: settings.CurrentThemeName,
GreeterWallpaperPath: settings.GreeterWallpaperPath,
ResolvedGreeterWallpaperPath: resolvedWallpaperPath,
MatugenScheme: settings.MatugenScheme,
IconTheme: settings.IconTheme,
IsLightMode: session.IsLightMode,
UsesDynamicWallpaperOverride: usesDynamicWallpaperOverride,
}, nil
}
func (s greeterThemeSyncState) effectiveColorsSource(homeDir string) string {
if s.UsesDynamicWallpaperOverride {
return greeterOverrideColorsSource(homeDir)
}
return defaultGreeterColorsSource(homeDir)
}
func ResolveGreeterColorSyncInfo(homeDir string) (GreeterColorSyncInfo, error) {
state, err := resolveGreeterThemeSyncState(homeDir)
if err != nil {
return GreeterColorSyncInfo{}, err
}
return GreeterColorSyncInfo{
SourcePath: state.effectiveColorsSource(homeDir),
ThemeName: state.ThemeName,
UsesDynamicWallpaperOverride: state.UsesDynamicWallpaperOverride,
}, nil
}
func ensureGreeterSyncSourceFile(path string) error {
sourceDir := filepath.Dir(path)
if err := os.MkdirAll(sourceDir, 0o755); err != nil {
return fmt.Errorf("failed to create source directory %s: %w", sourceDir, err)
}
if _, err := os.Stat(path); os.IsNotExist(err) {
if err := os.WriteFile(path, []byte("{}"), 0o644); err != nil {
return fmt.Errorf("failed to create source file %s: %w", path, err)
}
} else if err != nil {
return fmt.Errorf("failed to inspect source file %s: %w", path, err)
}
return nil
}
func syncGreeterDynamicOverrideColors(dmsPath, homeDir string, state greeterThemeSyncState, logFunc func(string)) error {
if !state.UsesDynamicWallpaperOverride {
return nil
}
st, err := os.Stat(state.ResolvedGreeterWallpaperPath)
if err != nil {
return fmt.Errorf("configured greeter wallpaper not found at %s: %w", state.ResolvedGreeterWallpaperPath, err)
}
if st.IsDir() {
return fmt.Errorf("configured greeter wallpaper path points to a directory: %s", state.ResolvedGreeterWallpaperPath)
}
mode := matugen.ColorModeDark
if state.IsLightMode {
mode = matugen.ColorModeLight
}
opts := matugen.Options{
StateDir: greeterOverrideColorsStateDir(homeDir),
ShellDir: dmsPath,
ConfigDir: filepath.Join(homeDir, ".config"),
Kind: "image",
Value: state.ResolvedGreeterWallpaperPath,
Mode: mode,
IconTheme: state.IconTheme,
MatugenType: state.MatugenScheme,
RunUserTemplates: false,
ColorsOnly: true,
}
err = matugen.Run(opts)
switch {
case errors.Is(err, matugen.ErrNoChanges):
logFunc("✓ Greeter dynamic override colors already up to date")
return nil
case err != nil:
return fmt.Errorf("failed to generate greeter dynamic colors from wallpaper override: %w", err)
default:
logFunc("✓ Generated greeter dynamic colors from wallpaper override")
return nil
}
}
func syncGreeterColorSource(homeDir, cacheDir string, state greeterThemeSyncState, logFunc func(string), sudoPassword string) error {
source := state.effectiveColorsSource(homeDir)
if !state.UsesDynamicWallpaperOverride {
if err := ensureGreeterSyncSourceFile(source); err != nil {
return err
}
} else if _, err := os.Stat(source); err != nil {
return fmt.Errorf("expected generated greeter colors at %s: %w", source, err)
}
target := filepath.Join(cacheDir, "colors.json")
_ = runSudoCmd(sudoPassword, "rm", "-f", target)
if err := runSudoCmd(sudoPassword, "ln", "-sf", source, target); err != nil {
return fmt.Errorf("failed to create symlink for wallpaper based theming (%s -> %s): %w", target, source, err)
}
if state.UsesDynamicWallpaperOverride {
logFunc("✓ Synced wallpaper based theming (greeter wallpaper override)")
} else {
logFunc("✓ Synced wallpaper based theming")
}
return nil
}
func SyncDMSConfigs(dmsPath, compositor string, logFunc func(string), sudoPassword string, forceAuth bool) error {
homeDir, err := os.UserHomeDir()
if err != nil {
@@ -1131,11 +1345,6 @@ func SyncDMSConfigs(dmsPath, compositor string, logFunc func(string), sudoPasswo
target: filepath.Join(cacheDir, "session.json"),
desc: "state (wallpaper configuration)",
},
{
source: filepath.Join(homeDir, ".cache", "DankMaterialShell", "dms-colors.json"),
target: filepath.Join(cacheDir, "colors.json"),
desc: "wallpaper based theming",
},
}
for _, link := range symlinks {
@@ -1161,7 +1370,20 @@ func SyncDMSConfigs(dmsPath, compositor string, logFunc func(string), sudoPasswo
logFunc(fmt.Sprintf("✓ Synced %s", link.desc))
}
if err := syncGreeterWallpaperOverride(homeDir, cacheDir, logFunc, sudoPassword); err != nil {
state, err := resolveGreeterThemeSyncState(homeDir)
if err != nil {
return fmt.Errorf("failed to resolve greeter color source: %w", err)
}
if err := syncGreeterDynamicOverrideColors(dmsPath, homeDir, state, logFunc); err != nil {
return err
}
if err := syncGreeterColorSource(homeDir, cacheDir, state, logFunc, sudoPassword); err != nil {
return err
}
if err := syncGreeterWallpaperOverride(cacheDir, logFunc, sudoPassword, state); err != nil {
return fmt.Errorf("greeter wallpaper override sync failed: %w", err)
}
@@ -1180,23 +1402,9 @@ func SyncDMSConfigs(dmsPath, compositor string, logFunc func(string), sudoPasswo
return nil
}
func syncGreeterWallpaperOverride(homeDir, cacheDir string, logFunc func(string), sudoPassword string) error {
settingsPath := filepath.Join(homeDir, ".config", "DankMaterialShell", "settings.json")
data, err := os.ReadFile(settingsPath)
if err != nil {
if os.IsNotExist(err) {
return nil
}
return fmt.Errorf("failed to read settings at %s: %w", settingsPath, err)
}
var settings struct {
GreeterWallpaperPath string `json:"greeterWallpaperPath"`
}
if err := json.Unmarshal(data, &settings); err != nil {
return fmt.Errorf("failed to parse settings at %s: %w", settingsPath, err)
}
func syncGreeterWallpaperOverride(cacheDir string, logFunc func(string), sudoPassword string, state greeterThemeSyncState) error {
destPath := filepath.Join(cacheDir, "greeter_wallpaper_override.jpg")
if settings.GreeterWallpaperPath == "" {
if state.ResolvedGreeterWallpaperPath == "" {
if err := runSudoCmd(sudoPassword, "rm", "-f", destPath); err != nil {
return fmt.Errorf("failed to clear override file %s: %w", destPath, err)
}
@@ -1206,10 +1414,7 @@ func syncGreeterWallpaperOverride(homeDir, cacheDir string, logFunc func(string)
if err := runSudoCmd(sudoPassword, "rm", "-f", destPath); err != nil {
return fmt.Errorf("failed to remove old override file %s: %w", destPath, err)
}
src := settings.GreeterWallpaperPath
if !filepath.IsAbs(src) {
src = filepath.Join(homeDir, src)
}
src := state.ResolvedGreeterWallpaperPath
st, err := os.Stat(src)
if err != nil {
return fmt.Errorf("configured greeter wallpaper not found at %s: %w", src, err)

View File

@@ -0,0 +1,98 @@
package greeter
import (
"os"
"path/filepath"
"testing"
)
func writeTestJSON(t *testing.T, path string, content string) {
t.Helper()
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
t.Fatalf("failed to create parent dir for %s: %v", path, err)
}
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
t.Fatalf("failed to write %s: %v", path, err)
}
}
func TestResolveGreeterThemeSyncState(t *testing.T) {
t.Parallel()
tests := []struct {
name string
settingsJSON string
sessionJSON string
wantSourcePath string
wantResolvedWallpaper string
wantDynamicOverrideUsed bool
}{
{
name: "dynamic theme with greeter wallpaper override uses generated greeter colors",
settingsJSON: `{
"currentThemeName": "dynamic",
"greeterWallpaperPath": "Pictures/blue.jpg",
"matugenScheme": "scheme-tonal-spot",
"iconTheme": "Papirus"
}`,
sessionJSON: `{"isLightMode":true}`,
wantSourcePath: filepath.Join(".cache", "DankMaterialShell", "greeter-colors", "dms-colors.json"),
wantResolvedWallpaper: filepath.Join("Pictures", "blue.jpg"),
wantDynamicOverrideUsed: true,
},
{
name: "dynamic theme without override uses desktop colors",
settingsJSON: `{
"currentThemeName": "dynamic",
"greeterWallpaperPath": ""
}`,
sessionJSON: `{"isLightMode":false}`,
wantSourcePath: filepath.Join(".cache", "DankMaterialShell", "dms-colors.json"),
wantResolvedWallpaper: "",
wantDynamicOverrideUsed: false,
},
{
name: "non-dynamic theme keeps desktop colors even with override wallpaper",
settingsJSON: `{
"currentThemeName": "purple",
"greeterWallpaperPath": "/tmp/blue.jpg"
}`,
sessionJSON: `{"isLightMode":false}`,
wantSourcePath: filepath.Join(".cache", "DankMaterialShell", "dms-colors.json"),
wantResolvedWallpaper: "/tmp/blue.jpg",
wantDynamicOverrideUsed: false,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
homeDir := t.TempDir()
writeTestJSON(t, filepath.Join(homeDir, ".config", "DankMaterialShell", "settings.json"), tt.settingsJSON)
writeTestJSON(t, filepath.Join(homeDir, ".local", "state", "DankMaterialShell", "session.json"), tt.sessionJSON)
state, err := resolveGreeterThemeSyncState(homeDir)
if err != nil {
t.Fatalf("resolveGreeterThemeSyncState returned error: %v", err)
}
if got := state.effectiveColorsSource(homeDir); got != filepath.Join(homeDir, tt.wantSourcePath) {
t.Fatalf("effectiveColorsSource = %q, want %q", got, filepath.Join(homeDir, tt.wantSourcePath))
}
wantResolvedWallpaper := tt.wantResolvedWallpaper
if wantResolvedWallpaper != "" && !filepath.IsAbs(wantResolvedWallpaper) {
wantResolvedWallpaper = filepath.Join(homeDir, wantResolvedWallpaper)
}
if state.ResolvedGreeterWallpaperPath != wantResolvedWallpaper {
t.Fatalf("ResolvedGreeterWallpaperPath = %q, want %q", state.ResolvedGreeterWallpaperPath, wantResolvedWallpaper)
}
if state.UsesDynamicWallpaperOverride != tt.wantDynamicOverrideUsed {
t.Fatalf("UsesDynamicWallpaperOverride = %v, want %v", state.UsesDynamicWallpaperOverride, tt.wantDynamicOverrideUsed)
}
})
}
}

View File

@@ -100,6 +100,7 @@ type Options struct {
IconTheme string
MatugenType string
RunUserTemplates bool
ColorsOnly bool
StockColors string
SyncModeWithPortal bool
TerminalsAlwaysDark bool
@@ -274,6 +275,10 @@ func buildOnce(opts *Options) (bool, error) {
return false, nil
}
if opts.ColorsOnly {
return true, nil
}
if isDMSGTKActive(opts.ConfigDir) {
switch opts.Mode {
case ColorModeLight:
@@ -331,6 +336,10 @@ output_path = '%s'
`, opts.ShellDir, opts.ColorsOutput())
if opts.ColorsOnly {
return nil
}
homeDir, _ := os.UserHomeDir()
for _, tmpl := range templateRegistry {
if opts.ShouldSkipTemplate(tmpl.ID) {
@@ -597,10 +606,10 @@ func detectMatugenVersionLocked() (matugenFlags, error) {
matugenVersionOK = true
if matugenSupportsCOE {
log.Infof("Matugen %s supports --continue-on-error", versionStr)
log.Debugf("Matugen %s detected: continue-on-error support enabled", versionStr)
}
if matugenIsV4 {
log.Infof("Matugen %s: using v4 flags", versionStr)
log.Debugf("Matugen %s detected: using v4 compatibility flags", versionStr)
}
return matugenFlags{matugenSupportsCOE, matugenIsV4}, nil
}

View File

@@ -3,6 +3,7 @@ package matugen
import (
"os"
"path/filepath"
"strings"
"testing"
mocks_utils "github.com/AvengeMedia/DankMaterialShell/core/internal/mocks/utils"
@@ -392,3 +393,51 @@ func TestSubstituteVars(t *testing.T) {
})
}
}
func TestBuildMergedConfigColorsOnly(t *testing.T) {
tempDir := t.TempDir()
shellDir := filepath.Join(tempDir, "shell")
configsDir := filepath.Join(shellDir, "matugen", "configs")
if err := os.MkdirAll(configsDir, 0o755); err != nil {
t.Fatalf("failed to create configs dir: %v", err)
}
baseConfig := "[config]\ncustom_keywords = []\n"
if err := os.WriteFile(filepath.Join(configsDir, "base.toml"), []byte(baseConfig), 0o644); err != nil {
t.Fatalf("failed to write base config: %v", err)
}
cfgFile, err := os.CreateTemp(tempDir, "merged-*.toml")
if err != nil {
t.Fatalf("failed to create temp config: %v", err)
}
defer os.Remove(cfgFile.Name())
defer cfgFile.Close()
opts := &Options{
ShellDir: shellDir,
ConfigDir: filepath.Join(tempDir, "config"),
StateDir: filepath.Join(tempDir, "state"),
ColorsOnly: true,
}
if err := buildMergedConfig(opts, cfgFile, filepath.Join(tempDir, "templates")); err != nil {
t.Fatalf("buildMergedConfig failed: %v", err)
}
if err := cfgFile.Close(); err != nil {
t.Fatalf("failed to close merged config: %v", err)
}
output, err := os.ReadFile(cfgFile.Name())
if err != nil {
t.Fatalf("failed to read merged config: %v", err)
}
content := string(output)
assert.Contains(t, content, "[templates.dank]")
assert.Contains(t, content, "output_path = '"+filepath.Join(opts.StateDir, "dms-colors.json")+"'")
assert.NotContains(t, content, "[templates.gtk]")
assert.False(t, strings.Contains(content, "output_path = 'CONFIG_DIR/"), "colors-only config should not emit app template outputs")
}

View File

@@ -1278,7 +1278,10 @@ Singleton {
}
if (themeData.variants.options && themeData.variants.options.length > 0) {
const selectedVariantId = typeof SettingsData !== "undefined" ? SettingsData.getRegistryThemeVariant(themeId, themeData.variants.default) : themeData.variants.default;
const isGreeterMode = typeof SessionData !== "undefined" && SessionData.isGreeterMode;
const selectedVariantId = isGreeterMode
? (typeof GreetdSettings.registryThemeVariants[themeId] === "string" ? GreetdSettings.registryThemeVariants[themeId] : themeData.variants.default)
: (typeof SettingsData !== "undefined" ? SettingsData.getRegistryThemeVariant(themeId, themeData.variants.default) : themeData.variants.default);
const variant = findVariant(themeData.variants.options, selectedVariantId);
if (variant) {
const variantColors = variant[colorMode] || variant.dark || variant.light || {};
@@ -1650,8 +1653,13 @@ Singleton {
const defaults = customThemeRawData.variants.defaults || {};
const darkDefaults = defaults.dark || {};
const lightDefaults = defaults.light || defaults.dark || {};
const storedDark = typeof SettingsData !== "undefined" ? SettingsData.getRegistryThemeMultiVariant(themeId, darkDefaults, "dark") : darkDefaults;
const storedLight = typeof SettingsData !== "undefined" ? SettingsData.getRegistryThemeMultiVariant(themeId, lightDefaults, "light") : lightDefaults;
const isGreeterMode = typeof SessionData !== "undefined" && SessionData.isGreeterMode;
const storedDark = isGreeterMode
? (GreetdSettings.registryThemeVariants[themeId]?.dark || darkDefaults)
: (typeof SettingsData !== "undefined" ? SettingsData.getRegistryThemeMultiVariant(themeId, darkDefaults, "dark") : darkDefaults);
const storedLight = isGreeterMode
? (GreetdSettings.registryThemeVariants[themeId]?.light || lightDefaults)
: (typeof SettingsData !== "undefined" ? SettingsData.getRegistryThemeMultiVariant(themeId, lightDefaults, "light") : lightDefaults);
const darkFlavorId = storedDark.flavor || darkDefaults.flavor || "";
const lightFlavorId = storedLight.flavor || lightDefaults.flavor || "";
const accentId = storedDark.accent || darkDefaults.accent || "";
@@ -1669,7 +1677,10 @@ Singleton {
lightTheme = mergeColors(lightTheme, accent[lightFlavor.id] || {});
}
} else if (customThemeRawData.variants.options) {
const selectedVariantId = typeof SettingsData !== "undefined" ? SettingsData.getRegistryThemeVariant(themeId, customThemeRawData.variants.default) : customThemeRawData.variants.default;
const isGreeterMode = typeof SessionData !== "undefined" && SessionData.isGreeterMode;
const selectedVariantId = isGreeterMode
? (typeof GreetdSettings.registryThemeVariants[themeId] === "string" ? GreetdSettings.registryThemeVariants[themeId] : customThemeRawData.variants.default)
: (typeof SettingsData !== "undefined" ? SettingsData.getRegistryThemeVariant(themeId, customThemeRawData.variants.default) : customThemeRawData.variants.default);
const variant = findVariant(customThemeRawData.variants.options, selectedVariantId);
if (variant) {
darkTheme = mergeColors(darkTheme, variant.dark || {});
@@ -1997,6 +2008,7 @@ Singleton {
const colorsPath = SessionData.isGreeterMode ? greetCfgDir + "/colors.json" : stateDir + "/dms-colors.json";
return colorsPath;
}
blockLoading: false
watchChanges: !SessionData.isGreeterMode
function parseAndLoadColors() {