From b7af94e460c212e549d0d905f227b6bf6455f2eb Mon Sep 17 00:00:00 2001 From: ItsLemmy Date: Thu, 2 Oct 2025 20:50:01 -0400 Subject: [PATCH] Matugen: implementing proper terminal colors via iTerm2 color schemes. WIP --- .../Matugen/Terminal}/foot.conf | 0 .../Matugen/Terminal}/ghostty.conf | 0 .../Matugen/Terminal}/kitty.conf | 0 .../Matugen}/fuzzel.conf | 0 .../Matugen}/gtk.css | 0 .../Matugen}/noctalia.json | 0 .../Matugen}/pywalfox.json | 0 .../Matugen}/qtct.conf | 0 .../Matugen}/vesktop.css | 0 .../Terminal/kitty/Ayu-dark.conf | 22 +++++ .../Terminal/kitty/Ayu-light.conf | 22 +++++ .../Terminal/kitty/Nord-dark.conf | 22 +++++ .../Terminal/kitty/Nord-light.conf | 22 +++++ .../Terminal/kitty/Rosepine-dark.conf | 22 +++++ .../Terminal/kitty/Rosepine-light.conf | 22 +++++ Assets/Matugen/Matugen.qml | 85 ----------------- Assets/Translations/de.json | 10 +- Assets/Translations/en.json | 4 +- Assets/Translations/es.json | 10 +- Assets/Translations/fr.json | 10 +- Assets/Translations/pt.json | 10 +- Assets/Translations/zh-CN.json | 10 +- Bin/colors-apply.sh | 67 ++++++++++++++ Bin/i18n-json-check.sh | 2 +- Bin/i18n-qml-check.sh | 2 +- Commons/Settings.qml | 5 +- Modules/Settings/Tabs/ColorSchemeTab.qml | 90 +++++++++--------- Services/ColorSchemeService.qml | 4 +- Services/MatugenService.qml | 71 +++++++++++--- Services/MatugenTemplates.qml | 92 +++++++++++++++++++ 30 files changed, 429 insertions(+), 175 deletions(-) rename Assets/{Matugen/templates => ColorTemplates/Matugen/Terminal}/foot.conf (100%) rename Assets/{Matugen/templates => ColorTemplates/Matugen/Terminal}/ghostty.conf (100%) rename Assets/{Matugen/templates => ColorTemplates/Matugen/Terminal}/kitty.conf (100%) rename Assets/{Matugen/templates => ColorTemplates/Matugen}/fuzzel.conf (100%) rename Assets/{Matugen/templates => ColorTemplates/Matugen}/gtk.css (100%) rename Assets/{Matugen/templates => ColorTemplates/Matugen}/noctalia.json (100%) rename Assets/{Matugen/templates => ColorTemplates/Matugen}/pywalfox.json (100%) rename Assets/{Matugen/templates => ColorTemplates/Matugen}/qtct.conf (100%) rename Assets/{Matugen/templates => ColorTemplates/Matugen}/vesktop.css (100%) create mode 100644 Assets/ColorTemplates/Terminal/kitty/Ayu-dark.conf create mode 100644 Assets/ColorTemplates/Terminal/kitty/Ayu-light.conf create mode 100644 Assets/ColorTemplates/Terminal/kitty/Nord-dark.conf create mode 100644 Assets/ColorTemplates/Terminal/kitty/Nord-light.conf create mode 100644 Assets/ColorTemplates/Terminal/kitty/Rosepine-dark.conf create mode 100644 Assets/ColorTemplates/Terminal/kitty/Rosepine-light.conf delete mode 100644 Assets/Matugen/Matugen.qml create mode 100755 Bin/colors-apply.sh create mode 100644 Services/MatugenTemplates.qml diff --git a/Assets/Matugen/templates/foot.conf b/Assets/ColorTemplates/Matugen/Terminal/foot.conf similarity index 100% rename from Assets/Matugen/templates/foot.conf rename to Assets/ColorTemplates/Matugen/Terminal/foot.conf diff --git a/Assets/Matugen/templates/ghostty.conf b/Assets/ColorTemplates/Matugen/Terminal/ghostty.conf similarity index 100% rename from Assets/Matugen/templates/ghostty.conf rename to Assets/ColorTemplates/Matugen/Terminal/ghostty.conf diff --git a/Assets/Matugen/templates/kitty.conf b/Assets/ColorTemplates/Matugen/Terminal/kitty.conf similarity index 100% rename from Assets/Matugen/templates/kitty.conf rename to Assets/ColorTemplates/Matugen/Terminal/kitty.conf diff --git a/Assets/Matugen/templates/fuzzel.conf b/Assets/ColorTemplates/Matugen/fuzzel.conf similarity index 100% rename from Assets/Matugen/templates/fuzzel.conf rename to Assets/ColorTemplates/Matugen/fuzzel.conf diff --git a/Assets/Matugen/templates/gtk.css b/Assets/ColorTemplates/Matugen/gtk.css similarity index 100% rename from Assets/Matugen/templates/gtk.css rename to Assets/ColorTemplates/Matugen/gtk.css diff --git a/Assets/Matugen/templates/noctalia.json b/Assets/ColorTemplates/Matugen/noctalia.json similarity index 100% rename from Assets/Matugen/templates/noctalia.json rename to Assets/ColorTemplates/Matugen/noctalia.json diff --git a/Assets/Matugen/templates/pywalfox.json b/Assets/ColorTemplates/Matugen/pywalfox.json similarity index 100% rename from Assets/Matugen/templates/pywalfox.json rename to Assets/ColorTemplates/Matugen/pywalfox.json diff --git a/Assets/Matugen/templates/qtct.conf b/Assets/ColorTemplates/Matugen/qtct.conf similarity index 100% rename from Assets/Matugen/templates/qtct.conf rename to Assets/ColorTemplates/Matugen/qtct.conf diff --git a/Assets/Matugen/templates/vesktop.css b/Assets/ColorTemplates/Matugen/vesktop.css similarity index 100% rename from Assets/Matugen/templates/vesktop.css rename to Assets/ColorTemplates/Matugen/vesktop.css diff --git a/Assets/ColorTemplates/Terminal/kitty/Ayu-dark.conf b/Assets/ColorTemplates/Terminal/kitty/Ayu-dark.conf new file mode 100644 index 00000000..281ce853 --- /dev/null +++ b/Assets/ColorTemplates/Terminal/kitty/Ayu-dark.conf @@ -0,0 +1,22 @@ +color0 #11151c +color1 #ea6c73 +color2 #7fd962 +color3 #f9af4f +color4 #53bdfa +color5 #cda1fa +color6 #90e1c6 +color7 #c7c7c7 +color8 #686868 +color9 #f07178 +color10 #aad94c +color11 #ffb454 +color12 #59c2ff +color13 #d2a6ff +color14 #95e6cb +color15 #ffffff +background #0b0e14 +selection_foreground #0b0e14 +cursor #e6b450 +cursor_text_color #0b0e14 +foreground #bfbdb6 +selection_background #bfbdb6 diff --git a/Assets/ColorTemplates/Terminal/kitty/Ayu-light.conf b/Assets/ColorTemplates/Terminal/kitty/Ayu-light.conf new file mode 100644 index 00000000..224159b8 --- /dev/null +++ b/Assets/ColorTemplates/Terminal/kitty/Ayu-light.conf @@ -0,0 +1,22 @@ +color0 #000000 +color1 #ea6c6d +color2 #6cbf43 +color3 #eca944 +color4 #3199e1 +color5 #9e75c7 +color6 #46ba94 +color7 #bababa +color8 #686868 +color9 #f07171 +color10 #86b300 +color11 #f2ae49 +color12 #399ee6 +color13 #a37acc +color14 #4cbf99 +color15 #d1d1d1 +background #f8f9fa +selection_foreground #f8f9fa +cursor #ffaa33 +cursor_text_color #f8f9fa +foreground #5c6166 +selection_background #5c6166 diff --git a/Assets/ColorTemplates/Terminal/kitty/Nord-dark.conf b/Assets/ColorTemplates/Terminal/kitty/Nord-dark.conf new file mode 100644 index 00000000..77ced703 --- /dev/null +++ b/Assets/ColorTemplates/Terminal/kitty/Nord-dark.conf @@ -0,0 +1,22 @@ +color0 #3b4252 +color1 #bf616a +color2 #a3be8c +color3 #ebcb8b +color4 #81a1c1 +color5 #b48ead +color6 #88c0d0 +color7 #e5e9f0 +color8 #596377 +color9 #bf616a +color10 #a3be8c +color11 #ebcb8b +color12 #81a1c1 +color13 #b48ead +color14 #8fbcbb +color15 #eceff4 +background #2e3440 +selection_foreground #2e3440 +cursor #eceff4 +cursor_text_color #282828 +foreground #d8dee9 +selection_background #d8dee9 diff --git a/Assets/ColorTemplates/Terminal/kitty/Nord-light.conf b/Assets/ColorTemplates/Terminal/kitty/Nord-light.conf new file mode 100644 index 00000000..e7ec447d --- /dev/null +++ b/Assets/ColorTemplates/Terminal/kitty/Nord-light.conf @@ -0,0 +1,22 @@ +color0 #3b4252 +color1 #bf616a +color2 #96b17f +color3 #c5a565 +color4 #81a1c1 +color5 #b48ead +color6 #7bb3c3 +color7 #a5abb6 +color8 #4c566a +color9 #bf616a +color10 #96b17f +color11 #c5a565 +color12 #81a1c1 +color13 #b48ead +color14 #82afae +color15 #eceff4 +background #e5e9f0 +selection_foreground #e5e9f0 +cursor #7bb3c3 +cursor_text_color #3b4252 +foreground #414858 +selection_background #414858 diff --git a/Assets/ColorTemplates/Terminal/kitty/Rosepine-dark.conf b/Assets/ColorTemplates/Terminal/kitty/Rosepine-dark.conf new file mode 100644 index 00000000..29736b96 --- /dev/null +++ b/Assets/ColorTemplates/Terminal/kitty/Rosepine-dark.conf @@ -0,0 +1,22 @@ +color0 #26233a +color1 #eb6f92 +color2 #31748f +color3 #f6c177 +color4 #9ccfd8 +color5 #c4a7e7 +color6 #ebbcba +color7 #e0def4 +color8 #6e6a86 +color9 #eb6f92 +color10 #31748f +color11 #f6c177 +color12 #9ccfd8 +color13 #c4a7e7 +color14 #ebbcba +color15 #e0def4 +background #191724 +selection_foreground #191724 +cursor #e0def4 +cursor_text_color #191724 +foreground #e0def4 +selection_background #e0def4 diff --git a/Assets/ColorTemplates/Terminal/kitty/Rosepine-light.conf b/Assets/ColorTemplates/Terminal/kitty/Rosepine-light.conf new file mode 100644 index 00000000..08b5f9dc --- /dev/null +++ b/Assets/ColorTemplates/Terminal/kitty/Rosepine-light.conf @@ -0,0 +1,22 @@ +color0 #f2e9e1 +color1 #b4637a +color2 #286983 +color3 #ea9d34 +color4 #56949f +color5 #907aa9 +color6 #d7827e +color7 #575279 +color8 #9893a5 +color9 #b4637a +color10 #286983 +color11 #ea9d34 +color12 #56949f +color13 #907aa9 +color14 #d7827e +color15 #575279 +background #faf4ed +selection_foreground #faf4ed +cursor #575279 +cursor_text_color #faf4ed +foreground #575279 +selection_background #575279 diff --git a/Assets/Matugen/Matugen.qml b/Assets/Matugen/Matugen.qml deleted file mode 100644 index 99fe11cf..00000000 --- a/Assets/Matugen/Matugen.qml +++ /dev/null @@ -1,85 +0,0 @@ -pragma Singleton - -import QtQuick -import Quickshell -import qs.Commons - -// Central place to define which templates we generate and where they write. -// Users can extend it by dropping additional templates into: -// - Assets/Matugen/templates/ -// - ~/.config/matugen/ (when enableUserTemplates is true) -Singleton { - id: root - - // Build the base TOML using current settings - function buildConfigToml() { - var lines = [] - lines.push("[config]") - - if (Settings.data.colorSchemes.useWallpaperColors) { - // Only generate color for Noctalia if the colors are wallpaper based - // or this will conflict with our predefined colors - lines.push("[templates.noctalia]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/noctalia.json"') - lines.push('output_path = "' + Settings.configDir + 'colors.json"') - } - - if (Settings.data.matugen.gtk) { - lines.push("\n[templates.gtk3]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/gtk.css"') - lines.push('output_path = "~/.config/gtk-3.0/gtk.css"') - - lines.push("\n[templates.gtk4]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/gtk.css"') - lines.push('output_path = "~/.config/gtk-4.0/gtk.css"') - } - - if (Settings.data.matugen.qt) { - lines.push("\n[templates.qt5]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/qtct.conf"') - lines.push('output_path = "~/.config/qt5ct/colors/noctalia.conf"') - - lines.push("\n[templates.qt6]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/qtct.conf"') - lines.push('output_path = "~/.config/qt6ct/colors/noctalia.conf"') - } - - if (Settings.data.matugen.kitty) { - lines.push("\n[templates.kitty]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/kitty.conf"') - lines.push('output_path = "~/.config/kitty/themes/noctalia.conf"') - lines.push("post_hook = 'kitty +kitten themes --reload-in=all noctalia'") - } - if (Settings.data.matugen.ghostty) { - lines.push("\n[templates.ghostty]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/ghostty.conf"') - lines.push('output_path = "~/.config/ghostty/themes/noctalia"') - lines.push("post_hook = \"grep -q '^theme *= *' ~/.config/ghostty/config; and sed -i 's/^theme *= *.*/theme = noctalia/' ~/.config/ghostty/config; or echo 'theme = noctalia' >> ~/.config/ghostty/config; and pkill -SIGUSR2 ghostty\"") - } - if (Settings.data.matugen.foot) { - lines.push("\n[templates.foot]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/foot.conf"') - lines.push('output_path = "~/.config/foot/themes/noctalia"') - lines.push('post_hook = "sed -i /themes/d ~/.config/foot/foot.ini && echo include=~/.config/foot/themes/noctalia >> ~/.config/foot/foot.ini"') - } - if (Settings.data.matugen.fuzzel) { - lines.push("\n[templates.fuzzel]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/fuzzel.conf"') - lines.push('output_path = "~/.config/fuzzel/themes/noctalia"') - lines.push('post_hook = "sed -i /themes/d ~/.config/fuzzel/fuzzel.ini && echo include=~/.config/fuzzel/themes/noctalia >> ~/.config/fuzzel/fuzzel.ini"') - } - if (Settings.data.matugen.vesktop) { - lines.push("\n[templates.vesktop]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/vesktop.css"') - lines.push('output_path = "~/.config/vesktop/themes/noctalia.theme.css"') - } - if (Settings.data.matugen.pywalfox) { - lines.push("\n[templates.pywalfox]") - lines.push('input_path = "' + Quickshell.shellDir + '/Assets/Matugen/templates/pywalfox.json"') - lines.push('output_path = "~/.cache/wal/colors.json"') - lines.push('post_hook = "pywalfox update"') - } - - return lines.join("\n") + "\n" - } -} diff --git a/Assets/Translations/de.json b/Assets/Translations/de.json index 8275c47d..ce3cb820 100644 --- a/Assets/Translations/de.json +++ b/Assets/Translations/de.json @@ -511,11 +511,7 @@ "description": "Generiert Matugen-Templates (GTK, Terminal-Themes, etc.) bei der Verwendung vordefinierter Farbschemata." } }, - "matugen": { - "section": { - "label": "Matugen-Vorlagen", - "description": "Farben auf externe Anwendungen anwenden." - }, + "templates": { "ui": { "label": "UI", "description": "Desktop-Umgebung und UI-Toolkit-Theming.", @@ -565,6 +561,10 @@ "label": "Benutzer-Vorlagen", "description": "Benutzerdefinierte Matugen-Konfiguration aus ~/.config/matugen/config.toml aktivieren" } + }, + "section": { + "description": "Farben auf externe Anwendungen anwenden.", + "label": "Vorlagen" } } }, diff --git a/Assets/Translations/en.json b/Assets/Translations/en.json index 4a01ea95..bd8f124b 100644 --- a/Assets/Translations/en.json +++ b/Assets/Translations/en.json @@ -509,9 +509,9 @@ "description": "Generate Matugen templates (GTK, terminal themes, etc.) when using predefined color schemes." } }, - "matugen": { + "templates": { "section": { - "label": "Matugen templates", + "label": "Templates", "description": "Apply colors to external applications." }, "ui": { diff --git a/Assets/Translations/es.json b/Assets/Translations/es.json index a48fed9f..303bf206 100644 --- a/Assets/Translations/es.json +++ b/Assets/Translations/es.json @@ -507,11 +507,7 @@ "description": "Genera plantillas de Matugen (GTK, temas de terminal, etc.) al usar esquemas de colores predefinidos." } }, - "matugen": { - "section": { - "label": "Plantillas de Matugen", - "description": "Aplica colores a aplicaciones externas." - }, + "templates": { "ui": { "label": "UI", "description": "Tematización del entorno de escritorio y de la interfaz de usuario.", @@ -561,6 +557,10 @@ "label": "Plantillas de usuario", "description": "Habilitar configuración de Matugen definida por el usuario desde ~/.config/matugen/config.toml" } + }, + "section": { + "description": "Aplicar colores a aplicaciones externas.", + "label": "Plantillas" } } }, diff --git a/Assets/Translations/fr.json b/Assets/Translations/fr.json index cf4dd992..57698e94 100644 --- a/Assets/Translations/fr.json +++ b/Assets/Translations/fr.json @@ -507,11 +507,7 @@ "description": "Génère des modèles Matugen (GTK, thèmes de terminal, etc.) lors de l'utilisation de schémas de couleurs prédéfinis." } }, - "matugen": { - "section": { - "label": "Modèles Matugen", - "description": "Appliquez des couleurs aux applications externes." - }, + "templates": { "ui": { "label": "UI", "description": "Thématisation de l'environnement de bureau et de la boîte à outils d'interface utilisateur.", @@ -561,6 +557,10 @@ "label": "Modèles utilisateur", "description": "Activer la configuration Matugen définie par l'utilisateur depuis ~/.config/matugen/config.toml" } + }, + "section": { + "description": "Appliquer des couleurs aux applications externes.", + "label": "Modèles" } } }, diff --git a/Assets/Translations/pt.json b/Assets/Translations/pt.json index 103432f5..b9703420 100644 --- a/Assets/Translations/pt.json +++ b/Assets/Translations/pt.json @@ -473,11 +473,7 @@ "description": "Gera modelos Matugen (GTK, temas de terminal, etc.) ao usar esquemas de cores predefinidos." } }, - "matugen": { - "section": { - "label": "Modelos Matugen", - "description": "Aplique cores a aplicativos externos." - }, + "templates": { "ui": { "label": "UI", "description": "Tematização do ambiente de desktop e kit de ferramentas de UI.", @@ -527,6 +523,10 @@ "label": "Modelos do usuário", "description": "Ativa a configuração do Matugen definida pelo usuário em ~/.config/matugen/config.toml" } + }, + "section": { + "description": "Aplicar cores a aplicações externas.", + "label": "Modelos" } } }, diff --git a/Assets/Translations/zh-CN.json b/Assets/Translations/zh-CN.json index 960056fb..76ab1337 100644 --- a/Assets/Translations/zh-CN.json +++ b/Assets/Translations/zh-CN.json @@ -507,11 +507,7 @@ "description": "使用预定义配色方案时生成 Matugen 模板(GTK、终端主题等)。" } }, - "matugen": { - "section": { - "label": "Matugen 模板", - "description": "将颜色应用于外部应用程序。" - }, + "templates": { "ui": { "label": "用户界面", "description": "桌面环境和 UI 工具包主题。", @@ -561,6 +557,10 @@ "label": "用户模板", "description": "启用来自 ~/.config/matugen/config.toml 的用户定义 Matugen 配置" } + }, + "section": { + "description": "将颜色应用于外部应用程序。", + "label": "模板" } } }, diff --git a/Bin/colors-apply.sh b/Bin/colors-apply.sh new file mode 100755 index 00000000..6a6ba6db --- /dev/null +++ b/Bin/colors-apply.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env -S bash + + +# Ensure exactly one argument is provided. +if [ "$#" -ne 1 ]; then + # Print usage information to standard error. + echo "Error: No application specified." >&2 + echo "Usage: $0 {kitty|foot|fuzzell|pywalfox}" >&2 + exit 1 +fi + +APP_NAME="$1" + +# --- Apply theme based on the application name --- +case "$APP_NAME" in + kitty) + echo "🎨 Applying 'noctalia' theme to kitty..." + kitty +kitten themes --reload-in=all noctalia + ;; + + foot) + echo "🎨 Applying 'noctalia' theme to foot..." + CONFIG_FILE="$HOME/.config/foot/foot.ini" + + # Check if the config file exists before trying to modify it. + if [ -f "$CONFIG_FILE" ]; then + # Remove any existing theme include line to prevent duplicates. + sed -i '/themes/d' "$CONFIG_FILE" + # Add the new theme include line to the end of the file. + echo "include=~/.config/foot/themes/noctalia" >> "$CONFIG_FILE" + else + echo "Error: foot config file not found at $CONFIG_FILE" >&2 + exit 1 + fi + ;; + + fuzzell) + echo "🎨 Applying 'noctalia' theme to fuzzell..." + CONFIG_FILE="$HOME/.config/fuzzel/fuzzel.ini" + + # Check if the config file exists. + if [ -f "$CONFIG_FILE" ]; then + # Remove any existing theme include line. + sed -i '/themes/d' "$CONFIG_FILE" + # Add the new theme include line. + echo "include=~/.config/fuzzel/themes/noctalia" >> "$CONFIG_FILE" + else + echo "Error: fuzzell config file not found at $CONFIG_FILE" >&2 + exit 1 + fi + ;; + + pywalfox) + echo "🎨 Updating pywalfox themes..." + pywalfox update + ;; + + *) + # Handle unknown application names. + echo "Error: Unknown application '$APP_NAME'." >&2 + exit 1 + ;; +esac + +echo "✅ Command sent for $APP_NAME." + + # lines.push("post_hook = \"grep -q '^theme *= *' ~/.config/ghostty/config; and sed -i 's/^theme *= *.*/theme = noctalia/' ~/.config/ghostty/config; or echo 'theme = noctalia' >> ~/.config/ghostty/config; and pkill -SIGUSR2 ghostty\"") \ No newline at end of file diff --git a/Bin/i18n-json-check.sh b/Bin/i18n-json-check.sh index 409be0bd..408677b2 100755 --- a/Bin/i18n-json-check.sh +++ b/Bin/i18n-json-check.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env -S bash # JSON Language File Comparison Script # Compares language files against en.json reference and generates a report diff --git a/Bin/i18n-qml-check.sh b/Bin/i18n-qml-check.sh index e86abd7b..fdeb4f8f 100755 --- a/Bin/i18n-qml-check.sh +++ b/Bin/i18n-qml-check.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env -S bash # Comprehensive i18n checker for QML files # Finds hardcoded strings in various QML properties diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 05ace8a7..ee7cbabf 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -313,9 +313,8 @@ Singleton { property bool generateTemplatesForPredefined: true } - // matugen templates toggles - property JsonObject matugen: JsonObject { - // Per-template flags to control dynamic config generation + // templates toggles + property JsonObject templates: JsonObject { property bool gtk: false property bool qt: false property bool kitty: false diff --git a/Modules/Settings/Tabs/ColorSchemeTab.qml b/Modules/Settings/Tabs/ColorSchemeTab.qml index 866e5616..6b9acc1a 100644 --- a/Modules/Settings/Tabs/ColorSchemeTab.qml +++ b/Modules/Settings/Tabs/ColorSchemeTab.qml @@ -418,31 +418,31 @@ ColumnLayout { Layout.bottomMargin: Style.marginXL * scaling } - // Matugen template toggles organized by category + // Template toggles organized by category ColumnLayout { Layout.fillWidth: true spacing: Style.marginL * scaling NHeader { - label: I18n.tr("settings.color-scheme.matugen.section.label") - description: I18n.tr("settings.color-scheme.matugen.section.description") + label: I18n.tr("settings.color-scheme.templates.section.label") + description: I18n.tr("settings.color-scheme.templates.section.description") } // UI Components NCollapsible { Layout.fillWidth: true - label: I18n.tr("settings.color-scheme.matugen.ui.label") - description: I18n.tr("settings.color-scheme.matugen.ui.description") + label: I18n.tr("settings.color-scheme.templates.ui.label") + description: I18n.tr("settings.color-scheme.templates.ui.description") defaultExpanded: false NCheckbox { label: "GTK" - description: I18n.tr("settings.color-scheme.matugen.ui.gtk.description", { + description: I18n.tr("settings.color-scheme.templates.ui.gtk.description", { "filepath": "~/.config/gtk-3.0/gtk.css & ~/.config/gtk-4.0/gtk.css" }) - checked: Settings.data.matugen.gtk + checked: Settings.data.templates.gtk onToggled: checked => { - Settings.data.matugen.gtk = checked + Settings.data.templates.gtk = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } @@ -450,12 +450,12 @@ ColumnLayout { NCheckbox { label: "Qt" - description: I18n.tr("settings.color-scheme.matugen.ui.qt.description", { + description: I18n.tr("settings.color-scheme.templates.ui.qt.description", { "filepath": "~/.config/qt5ct/colors/noctalia.conf & ~/.config/qt6ct/colors/noctalia.conf" }) - checked: Settings.data.matugen.qt + checked: Settings.data.templates.qt onToggled: checked => { - Settings.data.matugen.qt = checked + Settings.data.templates.qt = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } @@ -465,23 +465,23 @@ ColumnLayout { // Terminal Emulators NCollapsible { Layout.fillWidth: true - label: I18n.tr("settings.color-scheme.matugen.terminal.label") - description: I18n.tr("settings.color-scheme.matugen.terminal.description") + label: I18n.tr("settings.color-scheme.templates.terminal.label") + description: I18n.tr("settings.color-scheme.templates.terminal.description") defaultExpanded: false NCheckbox { label: "Kitty" - description: ProgramCheckerService.kittyAvailable ? I18n.tr("settings.color-scheme.matugen.terminal.kitty.description", { + description: ProgramCheckerService.kittyAvailable ? I18n.tr("settings.color-scheme.templates.terminal.kitty.description", { "filepath": "~/.config/kitty/themes/noctalia.conf" - }) : I18n.tr("settings.color-scheme.matugen.terminal.kitty.description-missing", { + }) : I18n.tr("settings.color-scheme.templates.terminal.kitty.description-missing", { "app": "kitty" }) - checked: Settings.data.matugen.kitty + checked: Settings.data.templates.kitty enabled: ProgramCheckerService.kittyAvailable opacity: ProgramCheckerService.kittyAvailable ? 1.0 : 0.6 onToggled: checked => { if (ProgramCheckerService.kittyAvailable) { - Settings.data.matugen.kitty = checked + Settings.data.templates.kitty = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } @@ -490,17 +490,17 @@ ColumnLayout { NCheckbox { label: "Ghostty" - description: ProgramCheckerService.ghosttyAvailable ? I18n.tr("settings.color-scheme.matugen.terminal.ghostty.description", { + description: ProgramCheckerService.ghosttyAvailable ? I18n.tr("settings.color-scheme.templates.terminal.ghostty.description", { "filepath": "~/.config/ghostty/themes/noctalia" - }) : I18n.tr("settings.color-scheme.matugen.terminal.ghostty.description-missing", { + }) : I18n.tr("settings.color-scheme.templates.terminal.ghostty.description-missing", { "app": "ghostty" }) - checked: Settings.data.matugen.ghostty + checked: Settings.data.templates.ghostty enabled: ProgramCheckerService.ghosttyAvailable opacity: ProgramCheckerService.ghosttyAvailable ? 1.0 : 0.6 onToggled: checked => { if (ProgramCheckerService.ghosttyAvailable) { - Settings.data.matugen.ghostty = checked + Settings.data.templates.ghostty = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } @@ -509,17 +509,17 @@ ColumnLayout { NCheckbox { label: "Foot" - description: ProgramCheckerService.footAvailable ? I18n.tr("settings.color-scheme.matugen.terminal.foot.description", { + description: ProgramCheckerService.footAvailable ? I18n.tr("settings.color-scheme.templates.terminal.foot.description", { "filepath": "~/.config/foot/themes/noctalia" - }) : I18n.tr("settings.color-scheme.matugen.terminal.foot.description-missing", { + }) : I18n.tr("settings.color-scheme.templates.terminal.foot.description-missing", { "app": "foot" }) - checked: Settings.data.matugen.foot + checked: Settings.data.templates.foot enabled: ProgramCheckerService.footAvailable opacity: ProgramCheckerService.footAvailable ? 1.0 : 0.6 onToggled: checked => { if (ProgramCheckerService.footAvailable) { - Settings.data.matugen.foot = checked + Settings.data.templates.foot = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } @@ -530,23 +530,23 @@ ColumnLayout { // Applications NCollapsible { Layout.fillWidth: true - label: I18n.tr("settings.color-scheme.matugen.programs.label") - description: I18n.tr("settings.color-scheme.matugen.programs.description") + label: I18n.tr("settings.color-scheme.templates.programs.label") + description: I18n.tr("settings.color-scheme.templates.programs.description") defaultExpanded: false NCheckbox { label: "Fuzzel" - description: ProgramCheckerService.fuzzelAvailable ? I18n.tr("settings.color-scheme.matugen.programs.fuzzel.description", { + description: ProgramCheckerService.fuzzelAvailable ? I18n.tr("settings.color-scheme.templates.programs.fuzzel.description", { "filepath": "~/.config/fuzzel/themes/noctalia" - }) : I18n.tr("settings.color-scheme.matugen.programs.fuzzel.description-missing", { + }) : I18n.tr("settings.color-scheme.templates.programs.fuzzel.description-missing", { "app": "fuzzel" }) - checked: Settings.data.matugen.fuzzel + checked: Settings.data.templates.fuzzel enabled: ProgramCheckerService.fuzzelAvailable opacity: ProgramCheckerService.fuzzelAvailable ? 1.0 : 0.6 onToggled: checked => { if (ProgramCheckerService.fuzzelAvailable) { - Settings.data.matugen.fuzzel = checked + Settings.data.templates.fuzzel = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } @@ -555,17 +555,17 @@ ColumnLayout { NCheckbox { label: "Vesktop" - description: ProgramCheckerService.vesktopAvailable ? I18n.tr("settings.color-scheme.matugen.programs.vesktop.description", { + description: ProgramCheckerService.vesktopAvailable ? I18n.tr("settings.color-scheme.templates.programs.vesktop.description", { "filepath": "~/.config/vesktop/themes/noctalia.theme.css" - }) : I18n.tr("settings.color-scheme.matugen.programs.vesktop.description-missing", { + }) : I18n.tr("settings.color-scheme.templates.programs.vesktop.description-missing", { "app": "vesktop" }) - checked: Settings.data.matugen.vesktop + checked: Settings.data.templates.vesktop enabled: ProgramCheckerService.vesktopAvailable opacity: ProgramCheckerService.vesktopAvailable ? 1.0 : 0.6 onToggled: checked => { if (ProgramCheckerService.vesktopAvailable) { - Settings.data.matugen.vesktop = checked + Settings.data.templates.vesktop = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } @@ -574,17 +574,17 @@ ColumnLayout { NCheckbox { label: "Pywalfox" - description: ProgramCheckerService.pywalfoxAvailable ? I18n.tr("settings.color-scheme.matugen.programs.pywalfox.description", { + description: ProgramCheckerService.pywalfoxAvailable ? I18n.tr("settings.color-scheme.templates.programs.pywalfox.description", { "filepath": "~/.cache/wal/colors.json" - }) : I18n.tr("settings.color-scheme.matugen.programs.pywalfox.description-missing", { + }) : I18n.tr("settings.color-scheme.templates.programs.pywalfox.description-missing", { "app": "pywalfox" }) - checked: Settings.data.matugen.pywalfox + checked: Settings.data.templates.pywalfox enabled: ProgramCheckerService.pywalfoxAvailable opacity: ProgramCheckerService.pywalfoxAvailable ? 1.0 : 0.6 onToggled: checked => { if (ProgramCheckerService.pywalfoxAvailable) { - Settings.data.matugen.pywalfox = checked + Settings.data.templates.pywalfox = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } @@ -595,16 +595,16 @@ ColumnLayout { // Miscellaneous NCollapsible { Layout.fillWidth: true - label: I18n.tr("settings.color-scheme.matugen.misc.label") - description: I18n.tr("settings.color-scheme.matugen.misc.description") + label: I18n.tr("settings.color-scheme.templates.misc.label") + description: I18n.tr("settings.color-scheme.templates.misc.description") defaultExpanded: false NCheckbox { - label: I18n.tr("settings.color-scheme.matugen.misc.user-templates.label") - description: I18n.tr("settings.color-scheme.matugen.misc.user-templates.description") - checked: Settings.data.matugen.enableUserTemplates + label: I18n.tr("settings.color-scheme.templates.misc.user-templates.label") + description: I18n.tr("settings.color-scheme.templates.misc.user-templates.description") + checked: Settings.data.templates.enableUserTemplates onToggled: checked => { - Settings.data.matugen.enableUserTemplates = checked + Settings.data.templates.enableUserTemplates = checked if (Settings.data.colorSchemes.useWallpaperColors) MatugenService.generateFromWallpaper() } diff --git a/Services/ColorSchemeService.qml b/Services/ColorSchemeService.qml index ba541df1..7edbdfae 100644 --- a/Services/ColorSchemeService.qml +++ b/Services/ColorSchemeService.qml @@ -125,14 +125,14 @@ Singleton { MatugenService.generateFromPredefinedScheme(data) } } catch (e) { - Logger.error("ColorScheme", "Failed to parse scheme JSON:", e) + Logger.error("ColorScheme", "Failed to parse scheme JSON:", path, e) } } } // Check if any Matugen templates are enabled function hasEnabledMatugenTemplates() { - return Settings.data.matugen.gtk || Settings.data.matugen.qt || Settings.data.matugen.kitty || Settings.data.matugen.ghostty || Settings.data.matugen.foot || Settings.data.matugen.fuzzel || Settings.data.matugen.vesktop || Settings.data.matugen.pywalfox + return Settings.data.templates.gtk || Settings.data.templates.qt || Settings.data.templates.kitty || Settings.data.templates.ghostty || Settings.data.templates.foot || Settings.data.templates.fuzzel || Settings.data.templates.vesktop || Settings.data.templates.pywalfox } // Writer to colors.json using a JsonAdapter for safety diff --git a/Services/MatugenService.qml b/Services/MatugenService.qml index 40f25dc5..288b1d9e 100644 --- a/Services/MatugenService.qml +++ b/Services/MatugenService.qml @@ -4,15 +4,17 @@ import QtQuick import Quickshell import Quickshell.Io import qs.Commons -import qs.Assets.Matugen import qs.Services import "../Helpers/ColorVariants.js" as ColorVariants Singleton { id: root + readonly property string colorsApplyScript: Quickshell.shellDir + '/Bin/colors-apply.sh'; + property string dynamicConfigPath: Settings.cacheDir + "matugen.dynamic.toml" + // External state management Connections { target: WallpaperService @@ -41,6 +43,7 @@ Singleton { Logger.log("Matugen", "Service started") } + // -------------------------------- // Convert predefined color scheme to Matugen format function convertPredefinedSchemeToMatugen(schemeData) { var variant = schemeData @@ -334,11 +337,10 @@ Singleton { } } - console.log(JSON.stringify(matugenColors)) - return JSON.stringify(matugenColors) } + // -------------------------------- // Generate colors using current wallpaper and settings function generateFromWallpaper() { Logger.log("Matugen", "Generating from wallpaper on screen:", Screen.name) @@ -348,7 +350,7 @@ Singleton { return } - var content = Matugen.buildConfigToml() + var content = MatugenTemplates.buildConfigToml() var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light" var pathEsc = dynamicConfigPath.replace(/'/g, "'\\''") var extraRepo = (Quickshell.shellDir + "/Assets/Matugen/extra").replace(/'/g, "'\\''") @@ -359,7 +361,7 @@ Singleton { + "done\n" + "matugen image '" + wp + "' --config '" + pathEsc + "' --mode " + mode + " --type " + Settings.data.colorSchemes.matugenSchemeType // Add user config execution if enabled - if (Settings.data.matugen.enableUserTemplates) { + if (Settings.data.templates.enableUserTemplates) { var userConfigDir = (Quickshell.env("HOME") + "/.config/matugen/").replace(/'/g, "'\\''") script += "\n# Execute user config if it exists\nif [ -f '" + userConfigDir + "config.toml' ]; then\n" script += " matugen image '" + wp + "' --config '" + userConfigDir + "config.toml' --mode " + mode + " --type " + Settings.data.colorSchemes.matugenSchemeType + "\n" @@ -371,12 +373,12 @@ Singleton { generateProcess.running = true } + // -------------------------------- // Generate templates from predefined color scheme function generateFromPredefinedScheme(schemeData) { Logger.log("Matugen", "Generating templates from predefined color scheme") - var content = Matugen.buildConfigToml() - console.log(content) + var content = MatugenTemplates.buildConfigToml() var mode = Settings.data.colorSchemes.darkMode ? "dark" : "light" var pathEsc = dynamicConfigPath.replace(/'/g, "'\\''") var extraRepo = (Quickshell.shellDir + "/Assets/Matugen/extra").replace(/'/g, "'\\''") @@ -400,7 +402,7 @@ Singleton { script += "matugen image --import-json '" + jsonPathEsc + "' --config '" + pathEsc + "' --mode " + mode + " '" + Quickshell.shellDir + "/Assets/Wallpaper/noctalia.png'" // Add user config execution if enabled - if (Settings.data.matugen.enableUserTemplates) { + if (Settings.data.templates.enableUserTemplates) { var userConfigDir = (Quickshell.env("HOME") + "/.config/matugen/").replace(/'/g, "'\\''") script += "\n# Execute user config if it exists\nif [ -f '" + userConfigDir + "config.toml' ]; then\n" script += " matugen image --import-json '" + jsonPathEsc + "' --config '" + userConfigDir + "config.toml' --mode " + mode + " '" + Quickshell.shellDir + "/Assets/Wallpaper/noctalia.png'\n" @@ -408,16 +410,49 @@ Singleton { } script += "\n" - console.log("------") - console.log(script) generateProcess.command = ["bash", "-lc", script] // Write JSON file with our custom colors // once written matugen will be executed via 'generateProcess' jsonWriter.path = jsonPath jsonWriter.setText(matugenJson) + + // ----- + // For terminals simply copy the full color from theme from iTerm2 so everything looks super nice! + var copyCmd = "" + if (Settings.data.templates.foot) { + if (copyCmd !== "") copyCmd += " ; " + copyCmd += `cp -f ${getTerminalColorsTemplate('foot')} ~/.config/foot/themes/noctalia.conf`; + copyCmd += ` ; ${colorsApplyScript} foot` + } + + if (Settings.data.templates.ghostty) { + if (copyCmd !== "") copyCmd += " ; " + copyCmd += `cp -f ${getTerminalColorsTemplate('ghostty')} ~/.config/ghostty/themes/noctalia.conf`; + copyCmd += ` ; ${colorsApplyScript} ghostty` + } + + if (Settings.data.templates.kitty) { + if (copyCmd !== "") copyCmd += " ; " + copyCmd += `cp -f ${getTerminalColorsTemplate('kitty')} ~/.config/kitty/themes/noctalia.conf`; + copyCmd += ` ; ${colorsApplyScript} kitty` + } + if (copyCmd !== "") { + //console.log(copyCmd) + copyProcess.command = ["bash", "-lc", copyCmd] + copyProcess.running = true + } } + // -------------------------------- + function getTerminalColorsTemplate(terminal) { + const colorTermRoot = "Assets/ColorTemplates/Terminal" + const colorScheme = Settings.data.colorSchemes.predefinedScheme; + const darkLight = Settings.data.colorSchemes.darkMode ? 'dark' : 'light'; + return `${Quickshell.shellDir}/${colorTermRoot}/${terminal}/${colorScheme}-${darkLight}.conf` + } + + // -------------------------------- // File writer for JSON import file FileView { id: jsonWriter @@ -431,6 +466,7 @@ Singleton { } } + // -------------------------------- Process { id: generateProcess workingDirectory: Quickshell.shellDir @@ -438,7 +474,20 @@ Singleton { stderr: StdioCollector { onStreamFinished: { if (this.text !== "") { - Logger.warn("MatugenService", "Matugen stderr:", this.text) + Logger.warn("MatugenService", "GenerateProcess stderr:", this.text) + } + } + } + } + + // -------------------------------- + Process { + id: copyProcess + running: false + stderr: StdioCollector { + onStreamFinished: { + if (this.text !== "") { + Logger.warn("MatugenService", "CopyProcess stderr:", this.text) } } } diff --git a/Services/MatugenTemplates.qml b/Services/MatugenTemplates.qml new file mode 100644 index 00000000..bf1da414 --- /dev/null +++ b/Services/MatugenTemplates.qml @@ -0,0 +1,92 @@ +pragma Singleton + +import QtQuick +import Quickshell +import qs.Commons + +// Central place to define which templates we generate and where they write. +// Users can extend it by dropping additional templates into: +// - Assets/ColorTemplates/Matugen/ +// - ~/.config/matugen/ (when enableUserTemplates is true) +Singleton { + id: root + + // Build the base TOML using current settings + function buildConfigToml() { + var lines = [] + lines.push("[config]") + + if (Settings.data.colorSchemes.useWallpaperColors) { + // Only generate colors for Noctalia if the colors are wallpaper based + // or this will conflict with our predefined colors + lines.push("[templates.noctalia]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/noctalia.json"') + lines.push('output_path = "' + Settings.configDir + 'colors.json"') + + // Only generate colors for terminalk if the colors are wallpaper based + // predefined color schemes use a different approach for better result + if (Settings.data.templates.foot) { + lines.push("\n[templates.foot]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/Terminal/foot.conf"') + lines.push('output_path = "~/.config/foot/themes/noctalia"') + lines.push(`post_hook = "${MatugenService.colorsApplyScript} foot"`) + } + + if (Settings.data.templates.ghostty) { + lines.push("\n[templates.ghostty]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/Terminal/ghostty.conf"') + lines.push('output_path = "~/.config/ghostty/themes/noctalia"') + lines.push(`post_hook = "${MatugenService.colorsApplyScript} ghostty"`) + } + + if (Settings.data.templates.kitty) { + lines.push("\n[templates.kitty]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/Terminal/kitty.conf"') + lines.push('output_path = "~/.config/kitty/themes/noctalia.conf"') + lines.push(`post_hook = "${MatugenService.colorsApplyScript} kitty"`) + } + } + + if (Settings.data.templates.gtk) { + lines.push("\n[templates.gtk3]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/gtk.css"') + lines.push('output_path = "~/.config/gtk-3.0/gtk.css"') + + lines.push("\n[templates.gtk4]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/gtk.css"') + lines.push('output_path = "~/.config/gtk-4.0/gtk.css"') + } + + if (Settings.data.templates.qt) { + lines.push("\n[templates.qt5]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/qtct.conf"') + lines.push('output_path = "~/.config/qt5ct/colors/noctalia.conf"') + + lines.push("\n[templates.qt6]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/qtct.conf"') + lines.push('output_path = "~/.config/qt6ct/colors/noctalia.conf"') + } + + if (Settings.data.templates.fuzzel) { + lines.push("\n[templates.fuzzel]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/fuzzel.conf"') + lines.push('output_path = "~/.config/fuzzel/themes/noctalia"') + lines.push(`post_hook = "${MatugenService.colorsApplyScript} fuzzel"`) + } + + if (Settings.data.templates.pywalfox) { + lines.push("\n[templates.pywalfox]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/pywalfox.json"') + lines.push('output_path = "~/.cache/wal/colors.json"') + lines.push(`post_hook = "${MatugenService.colorsApplyScript} pywalfox"`) + } + + if (Settings.data.templates.vesktop) { + lines.push("\n[templates.vesktop]") + lines.push('input_path = "' + Quickshell.shellDir + '/Assets/ColorTemplates/Matugen/vesktop.css"') + lines.push('output_path = "~/.config/vesktop/themes/noctalia.theme.css"') + } + + return lines.join("\n") + "\n" + } +}