mirror of
https://github.com/zoriya/noctalia-shell.git
synced 2026-08-15 18:43:59 +00:00
249 lines
8.0 KiB
QML
249 lines
8.0 KiB
QML
pragma Singleton
|
|
|
|
import QtQuick
|
|
import Quickshell
|
|
import Quickshell.Io
|
|
import qs.Commons
|
|
|
|
Singleton {
|
|
id: root
|
|
|
|
readonly property string colorsApplyScript: Quickshell.shellDir + '/Bin/colors-apply.sh'
|
|
|
|
// Terminal configurations (for wallpaper-based matugen templates)
|
|
readonly property var terminals: [{
|
|
"id": "foot",
|
|
"name": "Foot",
|
|
"matugenPath": "Terminal/foot",
|
|
"outputPath": "~/.config/foot/themes/noctalia"
|
|
}, {
|
|
"id": "ghostty",
|
|
"name": "Ghostty",
|
|
"matugenPath": "Terminal/ghostty",
|
|
"outputPath": "~/.config/ghostty/themes/noctalia",
|
|
"postHook": "pgrep -x ghostty >/dev/null && pkill -SIGUSR2 ghostty; true"
|
|
}, {
|
|
"id": "kitty",
|
|
"name": "Kitty",
|
|
"matugenPath": "Terminal/kitty.conf",
|
|
"outputPath": "~/.config/kitty/themes/noctalia.conf"
|
|
}, {
|
|
"id": "alacritty",
|
|
"name": "Alacritty",
|
|
"matugenPath": "Terminal/alacritty.toml",
|
|
"outputPath": "~/.config/alacritty/themes/noctalia.toml"
|
|
}, {
|
|
"id": "wezterm",
|
|
"name": "Wezterm",
|
|
"matugenPath": "Terminal/wezterm.toml",
|
|
"outputPath": "~/.config/wezterm/colors/Noctalia.toml",
|
|
"postHook": "touch ~/.config/wezterm/wezterm.lua"
|
|
}]
|
|
|
|
// Application configurations - consolidated from MatugenTemplates + AppThemeService
|
|
readonly property var applications: [{
|
|
"id": "gtk",
|
|
"name": "GTK",
|
|
"category": "ui",
|
|
"input": "gtk.css",
|
|
"outputs": [{
|
|
"path": "~/.config/gtk-3.0/gtk.css"
|
|
}, {
|
|
"path": "~/.config/gtk-4.0/gtk.css"
|
|
}],
|
|
"postProcess": mode => `gsettings set org.gnome.desktop.interface color-scheme prefer-${mode}`
|
|
}, {
|
|
"id": "qt",
|
|
"name": "Qt",
|
|
"category": "ui",
|
|
"input": "qtct.conf",
|
|
"outputs": [{
|
|
"path": "~/.config/qt5ct/colors/noctalia.conf"
|
|
}, {
|
|
"path": "~/.config/qt6ct/colors/noctalia.conf"
|
|
}]
|
|
}, {
|
|
"id": "kcolorscheme",
|
|
"name": "KColorScheme",
|
|
"category": "ui",
|
|
"input": "kcolorscheme.colors",
|
|
"outputs": [{
|
|
"path": "~/.local/share/color-schemes/noctalia.colors"
|
|
}]
|
|
}, {
|
|
"id": "fuzzel",
|
|
"name": "Fuzzel",
|
|
"category": "launchers",
|
|
"input": "fuzzel.conf",
|
|
"outputs": [{
|
|
"path": "~/.config/fuzzel/themes/noctalia"
|
|
}],
|
|
"postProcess": () => `${colorsApplyScript} fuzzel`
|
|
}, {
|
|
"id": "vicinae",
|
|
"name": "Vicinae",
|
|
"category": "launchers",
|
|
"input": "vicinae.toml",
|
|
"outputs": [{
|
|
"path": "~/.local/share/vicinae/themes/matugen.toml"
|
|
}],
|
|
"postProcess": () => `cp --update=none ${Quickshell.shellDir}/Assets/noctalia.svg ~/.local/share/vicinae/themes/noctalia.svg && ${colorsApplyScript} vicinae`
|
|
}, {
|
|
"id": "walker",
|
|
"name": "Walker",
|
|
"category": "launchers",
|
|
"input": "walker.css",
|
|
"outputs": [{
|
|
"path": "~/.config/walker/themes/noctalia/style.css"
|
|
}],
|
|
"postProcess": () => `${colorsApplyScript} walker`,
|
|
"strict": true // Use strict mode for palette generation (preserves custom surface/outline values)
|
|
}, {
|
|
"id": "pywalfox",
|
|
"name": "Pywalfox",
|
|
"category": "applications",
|
|
"input": "pywalfox.json",
|
|
"outputs": [{
|
|
"path": "~/.cache/wal/colors.json"
|
|
}],
|
|
"postProcess": () => `${colorsApplyScript} pywalfox`
|
|
}, // CONSOLIDATED DISCORD CLIENTS
|
|
{
|
|
"id": "discord",
|
|
"name": "Discord",
|
|
"category": "applications",
|
|
"input": "vesktop.css",
|
|
"clients": [{
|
|
"name": "vesktop",
|
|
"path": "~/.config/vesktop",
|
|
"requiresThemesFolder": false
|
|
}, {
|
|
"name": "webcord",
|
|
"path": "~/.config/webcord",
|
|
"requiresThemesFolder": false
|
|
}, {
|
|
"name": "armcord",
|
|
"path": "~/.config/armcord",
|
|
"requiresThemesFolder": false
|
|
}, {
|
|
"name": "equibop",
|
|
"path": "~/.config/equibop",
|
|
"requiresThemesFolder": false
|
|
}, {
|
|
"name": "lightcord",
|
|
"path": "~/.config/lightcord",
|
|
"requiresThemesFolder": false
|
|
}, {
|
|
"name": "dorion",
|
|
"path": "~/.config/dorion",
|
|
"requiresThemesFolder": false
|
|
}, {
|
|
"name": "vencord",
|
|
"path": "~/.config/discord",
|
|
"requiresThemesFolder": true
|
|
}]
|
|
}, // VSCode with hardcoded path (requirement #5)
|
|
{
|
|
"id": "code",
|
|
"name": "VSCode",
|
|
"category": "applications",
|
|
"input": "code.json",
|
|
"outputs": [{
|
|
"path": "~/.vscode/extensions/hyprluna.hyprluna-theme-1.0.2/themes/hyprluna.json"
|
|
}]
|
|
},
|
|
{
|
|
"id": "spicetify",
|
|
"name": "Spicetify",
|
|
"category": "applications",
|
|
"input": "spicetify.ini",
|
|
"outputs": [{
|
|
"path": "~/.config/spicetify/Themes/Comfy/color.ini"
|
|
}],
|
|
"postProcess": () => `spicetify -q apply --no-restart`
|
|
}]
|
|
|
|
// Extract Discord clients for ProgramCheckerService compatibility
|
|
readonly property var discordClients: {
|
|
var clients = []
|
|
var discordApp = applications.find(app => app.id === "discord")
|
|
if (discordApp && discordApp.clients) {
|
|
discordApp.clients.forEach(client => {
|
|
clients.push({
|
|
"name": client.name,
|
|
"configPath": client.path,
|
|
"themePath": `${client.path}/themes/noctalia.theme.css`,
|
|
"requiresThemesFolder": client.requiresThemesFolder || false
|
|
})
|
|
})
|
|
}
|
|
return clients
|
|
}
|
|
|
|
// Build user templates TOML content
|
|
function buildUserTemplatesToml() {
|
|
var lines = []
|
|
lines.push("[config]")
|
|
lines.push("")
|
|
lines.push("[templates]")
|
|
lines.push("")
|
|
lines.push("# User-defined templates")
|
|
lines.push("# Add your custom templates below")
|
|
lines.push("# Example:")
|
|
lines.push("# [templates.myapp]")
|
|
lines.push("# input_path = \"~/.config/noctalia/templates/myapp.css\"")
|
|
lines.push("# output_path = \"~/.config/myapp/theme.css\"")
|
|
lines.push("# post_hook = \"myapp --reload-theme\"")
|
|
lines.push("")
|
|
lines.push("# Remove this section and add your own templates")
|
|
lines.push("#[templates.placeholder]")
|
|
lines.push("#input_path = \"" + Quickshell.shellDir + "/Assets/MatugenTemplates/noctalia.json\"")
|
|
lines.push("#output_path = \"" + Settings.cacheDir + "placeholder.json\"")
|
|
lines.push("")
|
|
|
|
return lines.join("\n") + "\n"
|
|
}
|
|
|
|
// Write user templates TOML file (moved from MatugenTemplates)
|
|
function writeUserTemplatesToml() {
|
|
var userConfigPath = Settings.configDir + "user-templates.toml"
|
|
|
|
// Check if file already exists
|
|
fileCheckProcess.command = ["test", "-f", userConfigPath]
|
|
fileCheckProcess.running = true
|
|
}
|
|
|
|
function doWriteUserTemplatesToml() {
|
|
var userConfigPath = Settings.configDir + "user-templates.toml"
|
|
var configContent = buildUserTemplatesToml()
|
|
var userConfigPathEsc = userConfigPath.replace(/'/g, "'\\''")
|
|
|
|
// Ensure directory exists (should already exist but just in case)
|
|
Quickshell.execDetached(["mkdir", "-p", Settings.configDir])
|
|
|
|
// Write the config file using heredoc to avoid escaping issues
|
|
var script = `cat > '${userConfigPathEsc}' << 'EOF'\n`
|
|
script += configContent
|
|
script += "EOF\n"
|
|
Quickshell.execDetached(["sh", "-c", script])
|
|
|
|
Logger.d("TemplateRegistry", "User templates config written to:", userConfigPath)
|
|
}
|
|
|
|
// Process for checking if user templates file exists
|
|
Process {
|
|
id: fileCheckProcess
|
|
running: false
|
|
|
|
onExited: function (exitCode) {
|
|
if (exitCode === 0) {
|
|
// File exists, skip creation
|
|
Logger.d("TemplateRegistry", "User templates config already exists, skipping creation")
|
|
} else {
|
|
// File doesn't exist, create it
|
|
doWriteUserTemplatesToml()
|
|
}
|
|
}
|
|
}
|
|
}
|