From cd727c6b8d97e62c288f30bc78bbdab18493104e Mon Sep 17 00:00:00 2001 From: hthienloc Date: Sun, 23 Aug 2026 09:45:34 +0700 Subject: [PATCH 1/2] feat(matugen): add standalone Spicetify theme --- core/internal/matugen/matugen.go | 1 + quickshell/Common/SettingsData.qml | 1 + quickshell/Common/Theme.qml | 4 ++- quickshell/Common/settings/SettingsSpec.js | 1 + .../Modules/Settings/ThemeColorsTab.qml | 20 +++++++++++++ quickshell/matugen/configs/spicetify.toml | 4 +++ quickshell/matugen/templates/spicetify.ini | 28 +++++++++++++++++++ .../translations/settings_search_index.json | 18 ++++++++++++ 8 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 quickshell/matugen/configs/spicetify.toml create mode 100644 quickshell/matugen/templates/spicetify.ini diff --git a/core/internal/matugen/matugen.go b/core/internal/matugen/matugen.go index 54cd95814..53fc5e657 100644 --- a/core/internal/matugen/matugen.go +++ b/core/internal/matugen/matugen.go @@ -63,6 +63,7 @@ var templateRegistry = []TemplateDef{ {ID: "fcitx5", Commands: []string{"fcitx5"}, ConfigDirs: []string{"fcitx5"}, ConfigFile: "fcitx5.toml"}, {ID: "firefox", Commands: []string{"firefox"}, ConfigFile: "firefox.toml"}, {ID: "pywalfox", Commands: []string{"pywalfox"}, ConfigFile: "pywalfox.toml"}, + {ID: "spicetify", Commands: []string{"spicetify"}, ConfigFile: "spicetify.toml"}, {ID: "zenbrowser", Commands: []string{"zen", "zen-browser", "zen-beta", "zen-twilight"}, Flatpaks: []string{"app.zen_browser.zen"}, ConfigFile: "zenbrowser.toml"}, {ID: "vesktop", Commands: []string{"vesktop"}, Flatpaks: []string{"dev.vencord.Vesktop"}, ConfigDirs: []string{"vesktop"}, ConfigFile: "vesktop.toml", FlatpakConfigPath: "dev.vencord.Vesktop/config"}, {ID: "vencord", Commands: []string{"discord", "Discord", "discord-canary", "DiscordCanary"}, Flatpaks: []string{"com.discordapp.Discord", "com.discordapp.DiscordCanary"}, ConfigDirs: []string{"Vencord"}, ConfigFile: "vencord.toml"}, diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 40282e3a8..b08a1a963 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -832,6 +832,7 @@ Singleton { property bool matugenTemplateQtengine: true property bool matugenTemplateFirefox: true property bool matugenTemplatePywalfox: true + property bool matugenTemplateSpicetify: true property bool matugenTemplateZenBrowser: true property bool matugenTemplateVesktop: true property bool matugenTemplateVencord: true diff --git a/quickshell/Common/Theme.qml b/quickshell/Common/Theme.qml index c7c513d77..0045bcccc 100644 --- a/quickshell/Common/Theme.qml +++ b/quickshell/Common/Theme.qml @@ -1525,7 +1525,7 @@ Singleton { if (typeof SettingsData !== "undefined") { const skipTemplates = []; if (!SettingsData.runDmsMatugenTemplates) { - skipTemplates.push("gtk", "nvim", "niri", "qt5ct", "qt6ct", "qtengine", "fcitx5", "firefox", "pywalfox", "zenbrowser", "vesktop", "vencord", "equibop", "ghostty", "kitty", "foot", "alacritty", "wezterm", "dgop", "kcolorscheme", "vscode", "emacs", "zed"); + skipTemplates.push("gtk", "nvim", "niri", "qt5ct", "qt6ct", "qtengine", "fcitx5", "firefox", "pywalfox", "spicetify", "zenbrowser", "vesktop", "vencord", "equibop", "ghostty", "kitty", "foot", "alacritty", "wezterm", "dgop", "kcolorscheme", "vscode", "emacs", "zed"); } else { if (!SettingsData.matugenTemplateGtk) skipTemplates.push("gtk"); @@ -1547,6 +1547,8 @@ Singleton { skipTemplates.push("firefox"); if (!SettingsData.matugenTemplatePywalfox) skipTemplates.push("pywalfox"); + if (!SettingsData.matugenTemplateSpicetify) + skipTemplates.push("spicetify"); if (!SettingsData.matugenTemplateZenBrowser) skipTemplates.push("zenbrowser"); if (!SettingsData.matugenTemplateVesktop) diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index daf8e2882..67c669f02 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -404,6 +404,7 @@ var SPEC = { matugenTemplateQtengine: { def: true }, matugenTemplateFirefox: { def: true }, matugenTemplatePywalfox: { def: true }, + matugenTemplateSpicetify: { def: true }, matugenTemplateZenBrowser: { def: true }, matugenTemplateVesktop: { def: true }, matugenTemplateVencord: { def: true }, diff --git a/quickshell/Modules/Settings/ThemeColorsTab.qml b/quickshell/Modules/Settings/ThemeColorsTab.qml index c57cfb956..c2da45eba 100644 --- a/quickshell/Modules/Settings/ThemeColorsTab.qml +++ b/quickshell/Modules/Settings/ThemeColorsTab.qml @@ -255,6 +255,10 @@ Item { return Theme.warning; } + function disableSpicetify() { + Proc.runCommand("disable-spicetify", ["sh", "-c", "command -v spicetify >/dev/null 2>&1 && spicetify config current_theme marketplace >/dev/null && spicetify apply"], () => {}); + } + function openSurfaceBorderColorPicker() { PopoutService.colorPickerModal.selectedColor = SettingsData.blurBorderCustomColor ?? "#ffffff"; PopoutService.colorPickerModal.pickerTitle = I18n.tr("Surface Border Color"); @@ -2690,6 +2694,22 @@ Item { onToggled: checked => SettingsData.set("matugenTemplatePywalfox", checked) } + SettingsToggleRow { + tab: "theme" + tags: ["matugen", "spicetify", "spotify", "template"] + settingKey: "matugenTemplateSpicetify" + text: "Spicetify" + description: getTemplateDescription("spicetify", "Requires Spicetify Marketplace and reloading Spotify after theme changes") + descriptionColor: getTemplateDescriptionColor("spicetify") + visible: SettingsData.runDmsMatugenTemplates + checked: SettingsData.matugenTemplateSpicetify + onToggled: checked => { + if (!checked) + disableSpicetify(); + SettingsData.set("matugenTemplateSpicetify", checked); + } + } + SettingsToggleRow { tab: "theme" tags: ["matugen", "zenbrowser", "template"] diff --git a/quickshell/matugen/configs/spicetify.toml b/quickshell/matugen/configs/spicetify.toml new file mode 100644 index 000000000..198185d2f --- /dev/null +++ b/quickshell/matugen/configs/spicetify.toml @@ -0,0 +1,4 @@ +[templates.dmspicetify] +input_path = 'SHELL_DIR/matugen/templates/spicetify.ini' +output_path = 'CONFIG_DIR/spicetify/Themes/DMS/color.ini' +post_hook = 'sh -c "command -v spicetify >/dev/null 2>&1 && spicetify config current_theme DMS color_scheme dms >/dev/null && spicetify -q apply --no-restart || true"' diff --git a/quickshell/matugen/templates/spicetify.ini b/quickshell/matugen/templates/spicetify.ini new file mode 100644 index 000000000..c1ad694b6 --- /dev/null +++ b/quickshell/matugen/templates/spicetify.ini @@ -0,0 +1,28 @@ +[dms] +text = {{colors.on_surface.default.hex_stripped}} +subtext = {{colors.on_surface_variant.default.hex_stripped}} +main = {{colors.surface.default.hex_stripped}} +main-elevated = {{colors.surface_container.default.hex_stripped}} +main-transition = {{colors.surface_container_lowest.default.hex_stripped}} +highlight = {{colors.surface_container_high.default.hex_stripped}} +highlight-elevated = {{colors.surface_container_highest.default.hex_stripped}} +sidebar = {{colors.surface_container.default.hex_stripped}} +player = {{colors.surface_container.default.hex_stripped}} +card = {{colors.surface_container_high.default.hex_stripped}} +shadow = {{colors.shadow.default.hex_stripped}} +selected-row = {{colors.primary.default.hex_stripped}} +button = {{colors.primary.default.hex_stripped}} +button-active = {{colors.primary.default.hex_stripped}} +button-secondary = {{colors.on_surface_variant.default.hex_stripped}} +button-disabled = {{colors.outline_variant.default.hex_stripped}} +tab-active = {{colors.primary.default.hex_stripped}} +notification = {{colors.tertiary.default.hex_stripped}} +notification-error = {{colors.error_container.default.hex_stripped}} +misc = {{colors.secondary.default.hex_stripped}} +play-button = {{colors.secondary.default.hex_stripped}} +play-button-active = {{colors.secondary.default.hex_stripped}} +progress-fg = {{colors.primary.default.hex_stripped}} +progress-bg = {{colors.surface_container.default.hex_stripped}} +heart = {{colors.error.default.hex_stripped}} +pagelink-active = {{colors.on_tertiary_container.default.hex_stripped}} +radio-btn-active = {{colors.on_tertiary_container.default.hex_stripped}} diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index d553456f3..0c713378f 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -4645,6 +4645,24 @@ "icon": "layers", "description": "Material inspired shadows and elevation on modals, popouts, and dialogs" }, + { + "section": "matugenTemplateSpicetify", + "label": "Spicetify", + "tabIndex": 10, + "category": "Theme & Colors", + "keywords": [ + "appearance", + "colors", + "look", + "matugen", + "scheme", + "spicetify", + "spotify", + "style", + "template", + "theme" + ] + }, { "section": "blurBorderColor", "label": "Surface Border Color", From 83b58fad412d8448cc8390f2fb871d871eac10b6 Mon Sep 17 00:00:00 2001 From: hthienloc Date: Sun, 23 Aug 2026 10:09:56 +0700 Subject: [PATCH 2/2] fix(matugen): restore Spicetify theme --- .../Modules/Settings/ThemeColorsTab.qml | 21 +++++++++++++++---- quickshell/matugen/configs/spicetify.toml | 2 +- .../translations/settings_search_index.json | 9 +++++++- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/quickshell/Modules/Settings/ThemeColorsTab.qml b/quickshell/Modules/Settings/ThemeColorsTab.qml index c2da45eba..85286d95e 100644 --- a/quickshell/Modules/Settings/ThemeColorsTab.qml +++ b/quickshell/Modules/Settings/ThemeColorsTab.qml @@ -255,8 +255,21 @@ Item { return Theme.warning; } - function disableSpicetify() { - Proc.runCommand("disable-spicetify", ["sh", "-c", "command -v spicetify >/dev/null 2>&1 && spicetify config current_theme marketplace >/dev/null && spicetify apply"], () => {}); + function restoreSpicetifyTheme() { + const statePath = SettingsData._configDir + "/DankMaterialShell/spicetify-theme"; + const script = `if command -v spicetify >/dev/null 2>&1 && [ -e "${statePath}" ]; then + currentTheme=$(spicetify config current_theme) + if [ "$currentTheme" = DMS ]; then + theme=$(sed -n '1p' "${statePath}") + scheme=$(sed -n '2p' "${statePath}") + if spicetify config current_theme "$theme" color_scheme "$scheme" >/dev/null && spicetify -q apply --no-restart; then + rm -f "${statePath}" + fi + else + rm -f "${statePath}" + fi + fi`; + Proc.runCommand("restore-spicetify-theme", ["sh", "-c", script], () => {}); } function openSurfaceBorderColorPicker() { @@ -2699,13 +2712,13 @@ Item { tags: ["matugen", "spicetify", "spotify", "template"] settingKey: "matugenTemplateSpicetify" text: "Spicetify" - description: getTemplateDescription("spicetify", "Requires Spicetify Marketplace and reloading Spotify after theme changes") + description: getTemplateDescription("spicetify", I18n.tr("Restores the previous Spotify theme when disabled; reload Spotify after theme changes", "spicetify matugen template description")) descriptionColor: getTemplateDescriptionColor("spicetify") visible: SettingsData.runDmsMatugenTemplates checked: SettingsData.matugenTemplateSpicetify onToggled: checked => { if (!checked) - disableSpicetify(); + restoreSpicetifyTheme(); SettingsData.set("matugenTemplateSpicetify", checked); } } diff --git a/quickshell/matugen/configs/spicetify.toml b/quickshell/matugen/configs/spicetify.toml index 198185d2f..9a2378334 100644 --- a/quickshell/matugen/configs/spicetify.toml +++ b/quickshell/matugen/configs/spicetify.toml @@ -1,4 +1,4 @@ [templates.dmspicetify] input_path = 'SHELL_DIR/matugen/templates/spicetify.ini' output_path = 'CONFIG_DIR/spicetify/Themes/DMS/color.ini' -post_hook = 'sh -c "command -v spicetify >/dev/null 2>&1 && spicetify config current_theme DMS color_scheme dms >/dev/null && spicetify -q apply --no-restart || true"' +post_hook = '''sh -c "if command -v spicetify >/dev/null 2>&1; then state='CONFIG_DIR/DankMaterialShell/spicetify-theme'; current_theme=\"$(spicetify config current_theme)\"; if [ \"$current_theme\" != DMS ] && [ ! -e \"$state\" ]; then mkdir -p \"$(dirname \"$state\")\"; printf '%s\\n%s\\n' \"$current_theme\" \"$(spicetify config color_scheme)\" > \"$state\"; fi; spicetify config current_theme DMS color_scheme dms >/dev/null && spicetify -q apply --no-restart; fi"''' diff --git a/quickshell/translations/settings_search_index.json b/quickshell/translations/settings_search_index.json index 0c713378f..1e4f00890 100644 --- a/quickshell/translations/settings_search_index.json +++ b/quickshell/translations/settings_search_index.json @@ -4651,17 +4651,24 @@ "tabIndex": 10, "category": "Theme & Colors", "keywords": [ + "after", "appearance", + "changes", "colors", + "colour", "look", "matugen", + "previous", + "reload", + "restores", "scheme", "spicetify", "spotify", "style", "template", "theme" - ] + ], + "description": "Restores the previous Spotify theme when disabled; reload Spotify after theme changes" }, { "section": "blurBorderColor",