colors: initial commit

This commit is contained in:
Lysec
2026-01-18 14:53:03 +01:00
parent c8f1cbb79e
commit 3c99656888
7 changed files with 1626 additions and 16 deletions
+3 -1
View File
@@ -381,7 +381,9 @@
"schedulingMode": "off",
"manualSunrise": "06:30",
"manualSunset": "18:30",
"matugenSchemeType": "scheme-fruit-salad"
"matugenSchemeType": "scheme-fruit-salad",
"generationBackend": "matugen",
"internalThemerMode": "material"
},
"templates": {
"activeTemplates": [],
+1551
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -603,6 +603,8 @@ Singleton {
property string manualSunrise: "06:30"
property string manualSunset: "18:30"
property string matugenSchemeType: "scheme-fruit-salad"
property string generationBackend: "matugen"
property string internalThemerMode: "material"
}
// templates toggles
@@ -209,11 +209,35 @@ ColumnLayout {
}
}
NToggle {
label: "Use Internal Generator"
description: "Use experimental Python generator instead of Matugen"
enabled: Settings.data.colorSchemes.useWallpaperColors && ProgramCheckerService.pythonAvailable
visible: Settings.data.colorSchemes.useWallpaperColors && ProgramCheckerService.pythonAvailable
checked: Settings.data.colorSchemes.generationBackend === "internal"
onToggled: checked => {
Settings.data.colorSchemes.generationBackend = checked ? "internal" : "matugen";
AppThemeService.generate();
}
}
NToggle {
label: "Use Material Design"
description: "Generate Material Design colors (on) or simpler accents (off)"
enabled: Settings.data.colorSchemes.useWallpaperColors && Settings.data.colorSchemes.generationBackend === "internal"
visible: Settings.data.colorSchemes.useWallpaperColors && Settings.data.colorSchemes.generationBackend === "internal"
checked: Settings.data.colorSchemes.internalThemerMode === "material"
onToggled: checked => {
Settings.data.colorSchemes.internalThemerMode = checked ? "material" : "normal";
AppThemeService.generate();
}
}
NComboBox {
label: I18n.tr("panels.color-scheme.color-source-matugen-scheme-type-label")
description: I18n.tr("panels.color-scheme.color-source-matugen-scheme-type-description")
enabled: Settings.data.colorSchemes.useWallpaperColors
visible: Settings.data.colorSchemes.useWallpaperColors
enabled: Settings.data.colorSchemes.useWallpaperColors && Settings.data.colorSchemes.generationBackend !== "internal"
visible: Settings.data.colorSchemes.useWallpaperColors && Settings.data.colorSchemes.generationBackend !== "internal"
model: [
{
+4 -1
View File
@@ -17,6 +17,7 @@ Singleton {
property bool wlsunsetAvailable: false
property bool app2unitAvailable: false
property bool gnomeCalendarAvailable: false
property bool pythonAvailable: false
property bool wtypeAvailable: false
// Programs to check - maps property names to commands
@@ -26,7 +27,9 @@ Singleton {
"wlsunsetAvailable": ["sh", "-c", "command -v wlsunset"],
"app2unitAvailable": ["sh", "-c", "command -v app2unit"],
"gnomeCalendarAvailable": ["sh", "-c", "command -v gnome-calendar"],
"wtypeAvailable": ["sh", "-c", "command -v wtype"]
"gnomeCalendarAvailable": ["sh", "-c", "command -v gnome-calendar"],
"wtypeAvailable": ["sh", "-c", "command -v wtype"],
"pythonAvailable": ["sh", "-c", "command -v python3"]
})
// Discord client auto-detection
+33 -5
View File
@@ -58,9 +58,19 @@ Singleton {
if (!content)
return;
const wp = wallpaperPath.replace(/'/g, "'\\''");
const script = buildMatugenScript(content, wp, mode);
generateProcess.generator = "matugen";
// Determine backend
let backend = Settings.data.colorSchemes.generationBackend;
if (!backend) backend = "matugen"; // Default
// Fallback if matugen not available but python is
if (backend === "matugen" && !ProgramCheckerService.matugenAvailable && ProgramCheckerService.pythonAvailable) {
backend = "internal";
}
const script = buildMatugenScript(content, wp, mode, backend);
generateProcess.generator = backend;
generateProcess.command = ["sh", "-lc", script];
generateProcess.running = true;
}
@@ -259,7 +269,7 @@ Singleton {
return false;
}
function buildMatugenScript(content, wallpaper, mode) {
function buildMatugenScript(content, wallpaper, mode, backend) {
const delimiter = "MATUGEN_CONFIG_EOF_" + Math.random().toString(36).substr(2, 9);
const pathEsc = dynamicConfigPath.replace(/'/g, "'\\''");
const wpDelimiter = "WALLPAPER_PATH_EOF_" + Math.random().toString(36).substr(2, 9);
@@ -267,13 +277,24 @@ Singleton {
// Use heredoc for wallpaper path to avoid all escaping issues
let script = `cat > '${pathEsc}' << '${delimiter}'\n${content}\n${delimiter}\n`;
script += `NOCTALIA_WP_PATH=$(cat << '${wpDelimiter}'\n${wallpaper}\n${wpDelimiter}\n)\n`;
if (backend === "internal") {
// Use colors.py (Python implementation)
const scriptPath = Quickshell.shellDir + "/Bin/colors.py";
const styleFlag = (Settings.data.colorSchemes.internalThemerMode === "normal") ? "--normal" : "--material";
script += `python3 "${scriptPath}" "$NOCTALIA_WP_PATH" ${styleFlag} --config '${pathEsc}' --mode ${mode} --type ${Settings.data.colorSchemes.matugenSchemeType} `;
// Note: colors.py handles template rendering via --config, effectively mimicking matugen
} else {
// Use Matugen (Rust implementation)
script += 'matugen ';
if (ProgramCheckerService.matugenVersion >= "3.1.0") {
// Matugen 3.1.0+ supports --continue-on-error to process all templates even if some fail
script += '--continue-on-error ';
}
script += `image "$NOCTALIA_WP_PATH" --config '${pathEsc}' --mode ${mode} --type ${Settings.data.colorSchemes.matugenSchemeType}`;
script += buildUserTemplateCommand("$NOCTALIA_WP_PATH", mode);
}
script += buildUserTemplateCommand("$NOCTALIA_WP_PATH", mode, backend);
return script + "\n";
}
@@ -550,7 +571,7 @@ Singleton {
// ================================================================================
// USER TEMPLATES, advanced usage
// ================================================================================
function buildUserTemplateCommand(input, mode) {
function buildUserTemplateCommand(input, mode, backend) {
if (!Settings.data.templates.enableUserTemplates)
return "";
@@ -560,7 +581,14 @@ Singleton {
// If input is a shell variable (starts with $), use double quotes to allow expansion
// Otherwise, use single quotes for safety with file paths
const inputQuoted = input.startsWith("$") ? `"${input}"` : `'${input.replace(/'/g, "'\\''")}'`;
if (backend === "internal") {
const scriptPath = Quickshell.shellDir + "/Bin/colors.py";
const styleFlag = (Settings.data.colorSchemes.internalThemerMode === "normal") ? "--normal" : "--material";
script += ` python3 "${scriptPath}" ${inputQuoted} ${styleFlag} --config '${userConfigPath}' --mode ${mode} --type ${Settings.data.colorSchemes.matugenSchemeType}\n`;
} else {
script += ` matugen image ${inputQuoted} --config '${userConfigPath}' --mode ${mode} --type ${Settings.data.colorSchemes.matugenSchemeType}\n`;
}
script += "fi";
return script;