mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
compositor+matugen: border override, hypr/mango layout overrides, new
templates, respect XDG paths - Add Hyprland and MangoWC templates - Add GUI gaps, window radius, and border thickness overrides for niri, Hyprland, and MangoWC - Add replacement support in matugen templates for DATA_DIR, CACHE_DIR, CONFIG_DIR fixes #1274 fixes #1273
This commit is contained in:
@@ -18,3 +18,4 @@ This file is more of a quick reference so I know what to account for before next
|
||||
- Notification persistence & history
|
||||
- **BREAKING** vscode theme needs re-installed
|
||||
- dms doctor cmd
|
||||
- niri/hypr/mango gaps/window/border overrides
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -29,9 +30,16 @@ var matugenQueueCmd = &cobra.Command{
|
||||
Run: runMatugenQueue,
|
||||
}
|
||||
|
||||
var matugenCheckCmd = &cobra.Command{
|
||||
Use: "check",
|
||||
Short: "Check which template apps are detected",
|
||||
Run: runMatugenCheck,
|
||||
}
|
||||
|
||||
func init() {
|
||||
matugenCmd.AddCommand(matugenGenerateCmd)
|
||||
matugenCmd.AddCommand(matugenQueueCmd)
|
||||
matugenCmd.AddCommand(matugenCheckCmd)
|
||||
|
||||
for _, cmd := range []*cobra.Command{matugenGenerateCmd, matugenQueueCmd} {
|
||||
cmd.Flags().String("state-dir", "", "State directory for cache files")
|
||||
@@ -162,3 +170,12 @@ func runMatugenQueue(cmd *cobra.Command, args []string) {
|
||||
log.Fatalf("Timeout waiting for theme generation")
|
||||
}
|
||||
}
|
||||
|
||||
func runMatugenCheck(cmd *cobra.Command, args []string) {
|
||||
checks := matugen.CheckTemplates(nil)
|
||||
data, err := json.Marshal(checks)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to marshal check results: %v", err)
|
||||
}
|
||||
fmt.Println(string(data))
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ func (cd *ConfigDeployer) deployNiriConfig(terminal deps.Terminal, useSystemd bo
|
||||
}
|
||||
|
||||
if existingConfig != "" {
|
||||
mergedConfig, err := cd.mergeNiriOutputSections(newConfig, existingConfig)
|
||||
mergedConfig, err := cd.mergeNiriOutputSections(newConfig, existingConfig, dmsDir)
|
||||
if err != nil {
|
||||
cd.log(fmt.Sprintf("Warning: Failed to merge output sections: %v", err))
|
||||
} else {
|
||||
@@ -209,6 +209,7 @@ func (cd *ConfigDeployer) deployNiriDmsConfigs(dmsDir, terminalCommand string) e
|
||||
{"layout.kdl", NiriLayoutConfig},
|
||||
{"alttab.kdl", NiriAlttabConfig},
|
||||
{"binds.kdl", strings.ReplaceAll(NiriBindsConfig, "{{TERMINAL_COMMAND}}", terminalCommand)},
|
||||
{"outputs.kdl", ""},
|
||||
}
|
||||
|
||||
for _, cfg := range configs {
|
||||
@@ -421,24 +422,31 @@ func (cd *ConfigDeployer) deployAlacrittyConfig() ([]DeploymentResult, error) {
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// mergeNiriOutputSections extracts output sections from existing config and merges them into the new config
|
||||
func (cd *ConfigDeployer) mergeNiriOutputSections(newConfig, existingConfig string) (string, error) {
|
||||
// Regular expression to match output sections (including commented ones)
|
||||
func (cd *ConfigDeployer) mergeNiriOutputSections(newConfig, existingConfig, dmsDir string) (string, error) {
|
||||
outputRegex := regexp.MustCompile(`(?m)^(/-)?\s*output\s+"[^"]+"\s*\{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}`)
|
||||
|
||||
// Find all output sections in the existing config
|
||||
existingOutputs := outputRegex.FindAllString(existingConfig, -1)
|
||||
|
||||
if len(existingOutputs) == 0 {
|
||||
// No output sections to merge
|
||||
return newConfig, nil
|
||||
}
|
||||
|
||||
// Remove the example output section from the new config
|
||||
outputsPath := filepath.Join(dmsDir, "outputs.kdl")
|
||||
if _, err := os.Stat(outputsPath); err != nil {
|
||||
var outputsContent strings.Builder
|
||||
for _, output := range existingOutputs {
|
||||
outputsContent.WriteString(output)
|
||||
outputsContent.WriteString("\n\n")
|
||||
}
|
||||
if err := os.WriteFile(outputsPath, []byte(outputsContent.String()), 0644); err != nil {
|
||||
cd.log(fmt.Sprintf("Warning: Failed to migrate outputs to %s: %v", outputsPath, err))
|
||||
} else {
|
||||
cd.log("Migrated output sections to dms/outputs.kdl")
|
||||
}
|
||||
}
|
||||
|
||||
exampleOutputRegex := regexp.MustCompile(`(?m)^/-output "eDP-2" \{[^{}]*(?:\{[^{}]*\}[^{}]*)*\}`)
|
||||
mergedConfig := exampleOutputRegex.ReplaceAllString(newConfig, "")
|
||||
|
||||
// Find where to insert the output sections (after the input section)
|
||||
inputEndRegex := regexp.MustCompile(`(?m)^}$`)
|
||||
inputMatches := inputEndRegex.FindAllStringIndex(newConfig, -1)
|
||||
|
||||
@@ -446,7 +454,6 @@ func (cd *ConfigDeployer) mergeNiriOutputSections(newConfig, existingConfig stri
|
||||
return "", fmt.Errorf("could not find insertion point for output sections")
|
||||
}
|
||||
|
||||
// Insert after the first closing brace (end of input section)
|
||||
insertPos := inputMatches[0][1]
|
||||
|
||||
var builder strings.Builder
|
||||
@@ -476,6 +483,12 @@ func (cd *ConfigDeployer) deployHyprlandConfig(terminal deps.Terminal, useSystem
|
||||
return result, result.Error
|
||||
}
|
||||
|
||||
dmsDir := filepath.Join(configDir, "dms")
|
||||
if err := os.MkdirAll(dmsDir, 0755); err != nil {
|
||||
result.Error = fmt.Errorf("failed to create dms directory: %w", err)
|
||||
return result, result.Error
|
||||
}
|
||||
|
||||
var existingConfig string
|
||||
if _, err := os.Stat(result.Path); err == nil {
|
||||
cd.log("Found existing Hyprland configuration")
|
||||
@@ -515,7 +528,7 @@ func (cd *ConfigDeployer) deployHyprlandConfig(terminal deps.Terminal, useSystem
|
||||
}
|
||||
|
||||
if existingConfig != "" {
|
||||
mergedConfig, err := cd.mergeHyprlandMonitorSections(newConfig, existingConfig)
|
||||
mergedConfig, err := cd.mergeHyprlandMonitorSections(newConfig, existingConfig, dmsDir)
|
||||
if err != nil {
|
||||
cd.log(fmt.Sprintf("Warning: Failed to merge monitor sections: %v", err))
|
||||
} else {
|
||||
@@ -529,13 +542,42 @@ func (cd *ConfigDeployer) deployHyprlandConfig(terminal deps.Terminal, useSystem
|
||||
return result, result.Error
|
||||
}
|
||||
|
||||
if err := cd.deployHyprlandDmsConfigs(dmsDir); err != nil {
|
||||
result.Error = fmt.Errorf("failed to deploy dms configs: %w", err)
|
||||
return result, result.Error
|
||||
}
|
||||
|
||||
result.Deployed = true
|
||||
cd.log("Successfully deployed Hyprland configuration")
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// mergeHyprlandMonitorSections extracts monitor sections from existing config and merges them into the new config
|
||||
func (cd *ConfigDeployer) mergeHyprlandMonitorSections(newConfig, existingConfig string) (string, error) {
|
||||
func (cd *ConfigDeployer) deployHyprlandDmsConfigs(dmsDir string) error {
|
||||
configs := []struct {
|
||||
name string
|
||||
content string
|
||||
}{
|
||||
{"colors.conf", HyprColorsConfig},
|
||||
{"layout.conf", HyprLayoutConfig},
|
||||
{"outputs.conf", ""},
|
||||
}
|
||||
|
||||
for _, cfg := range configs {
|
||||
path := filepath.Join(dmsDir, cfg.name)
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
cd.log(fmt.Sprintf("Skipping %s (already exists)", cfg.name))
|
||||
continue
|
||||
}
|
||||
if err := os.WriteFile(path, []byte(cfg.content), 0644); err != nil {
|
||||
return fmt.Errorf("failed to write %s: %w", cfg.name, err)
|
||||
}
|
||||
cd.log(fmt.Sprintf("Deployed %s", cfg.name))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (cd *ConfigDeployer) mergeHyprlandMonitorSections(newConfig, existingConfig, dmsDir string) (string, error) {
|
||||
monitorRegex := regexp.MustCompile(`(?m)^#?\s*monitor\s*=.*$`)
|
||||
existingMonitors := monitorRegex.FindAllString(existingConfig, -1)
|
||||
|
||||
@@ -543,6 +585,20 @@ func (cd *ConfigDeployer) mergeHyprlandMonitorSections(newConfig, existingConfig
|
||||
return newConfig, nil
|
||||
}
|
||||
|
||||
outputsPath := filepath.Join(dmsDir, "outputs.conf")
|
||||
if _, err := os.Stat(outputsPath); err != nil {
|
||||
var outputsContent strings.Builder
|
||||
for _, monitor := range existingMonitors {
|
||||
outputsContent.WriteString(monitor)
|
||||
outputsContent.WriteString("\n")
|
||||
}
|
||||
if err := os.WriteFile(outputsPath, []byte(outputsContent.String()), 0644); err != nil {
|
||||
cd.log(fmt.Sprintf("Warning: Failed to migrate monitors to %s: %v", outputsPath, err))
|
||||
} else {
|
||||
cd.log("Migrated monitor sections to dms/outputs.conf")
|
||||
}
|
||||
}
|
||||
|
||||
exampleMonitorRegex := regexp.MustCompile(`(?m)^# monitor = eDP-2.*$`)
|
||||
mergedConfig := exampleMonitorRegex.ReplaceAllString(newConfig, "")
|
||||
|
||||
|
||||
@@ -161,7 +161,8 @@ layout {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := cd.mergeNiriOutputSections(tt.newConfig, tt.existingConfig)
|
||||
tmpDir := t.TempDir()
|
||||
result, err := cd.mergeNiriOutputSections(tt.newConfig, tt.existingConfig, tmpDir)
|
||||
|
||||
if tt.wantError {
|
||||
assert.Error(t, err)
|
||||
@@ -362,7 +363,8 @@ input {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result, err := cd.mergeHyprlandMonitorSections(tt.newConfig, tt.existingConfig)
|
||||
tmpDir := t.TempDir()
|
||||
result, err := cd.mergeHyprlandMonitorSections(tt.newConfig, tt.existingConfig, tmpDir)
|
||||
|
||||
if tt.wantError {
|
||||
assert.Error(t, err)
|
||||
@@ -462,7 +464,6 @@ func TestHyprlandConfigStructure(t *testing.T) {
|
||||
assert.Contains(t, HyprlandConfig, "# KEYBINDINGS")
|
||||
assert.Contains(t, HyprlandConfig, "bind = $mod, T, exec, {{TERMINAL_COMMAND}}")
|
||||
assert.Contains(t, HyprlandConfig, "bind = $mod, space, exec, dms ipc call spotlight toggle")
|
||||
assert.Contains(t, HyprlandConfig, "windowrule = border_size 0, match:class ^(com\\.mitchellh\\.ghostty)$")
|
||||
}
|
||||
|
||||
func TestGhosttyConfigStructure(t *testing.T) {
|
||||
|
||||
25
core/internal/config/embedded/hypr-colors.conf
Normal file
25
core/internal/config/embedded/hypr-colors.conf
Normal file
@@ -0,0 +1,25 @@
|
||||
# ! Auto-generated file. Do not edit directly.
|
||||
# Remove source = ./dms/colors.conf from your config to override.
|
||||
|
||||
$primary = rgb(d0bcff)
|
||||
$outline = rgb(948f99)
|
||||
$error = rgb(f2b8b5)
|
||||
|
||||
general {
|
||||
col.active_border = $primary
|
||||
col.inactive_border = $outline
|
||||
}
|
||||
|
||||
group {
|
||||
col.border_active = $primary
|
||||
col.border_inactive = $outline
|
||||
col.border_locked_active = $error
|
||||
col.border_locked_inactive = $outline
|
||||
|
||||
groupbar {
|
||||
col.active = $primary
|
||||
col.inactive = $outline
|
||||
col.locked_active = $error
|
||||
col.locked_inactive = $outline
|
||||
}
|
||||
}
|
||||
11
core/internal/config/embedded/hypr-layout.conf
Normal file
11
core/internal/config/embedded/hypr-layout.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
# Auto-generated by DMS - do not edit manually
|
||||
|
||||
general {
|
||||
gaps_in = 4
|
||||
gaps_out = 4
|
||||
border_size = 2
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding = 12
|
||||
}
|
||||
@@ -27,10 +27,7 @@ input {
|
||||
general {
|
||||
gaps_in = 5
|
||||
gaps_out = 5
|
||||
border_size = 0 # off in niri
|
||||
|
||||
col.active_border = rgba(707070ff)
|
||||
col.inactive_border = rgba(d0d0d0ff)
|
||||
border_size = 2
|
||||
|
||||
layout = dwindle
|
||||
}
|
||||
@@ -42,7 +39,7 @@ decoration {
|
||||
rounding = 12
|
||||
|
||||
active_opacity = 1.0
|
||||
inactive_opacity = 0.9
|
||||
inactive_opacity = 1.0
|
||||
|
||||
shadow {
|
||||
enabled = true
|
||||
@@ -93,7 +90,6 @@ misc {
|
||||
windowrule = tile on, match:class ^(org\.wezfurlong\.wezterm)$
|
||||
|
||||
windowrule = rounding 12, match:class ^(org\.gnome\.)
|
||||
windowrule = border_size 0, match:class ^(org\.gnome\.)
|
||||
|
||||
windowrule = tile on, match:class ^(gnome-control-center)$
|
||||
windowrule = tile on, match:class ^(pavucontrol)$
|
||||
@@ -106,12 +102,6 @@ windowrule = float on, match:class ^(org\.gnome\.Nautilus)$
|
||||
windowrule = float on, match:class ^(steam)$
|
||||
windowrule = float on, match:class ^(xdg-desktop-portal)$
|
||||
|
||||
windowrule = border_size 0, match:class ^(org\.wezfurlong\.wezterm)$
|
||||
windowrule = border_size 0, match:class ^(Alacritty)$
|
||||
windowrule = border_size 0, match:class ^(zen)$
|
||||
windowrule = border_size 0, match:class ^(com\.mitchellh\.ghostty)$
|
||||
windowrule = border_size 0, match:class ^(kitty)$
|
||||
|
||||
windowrule = float on, match:class ^(firefox)$, match:title ^(Picture-in-Picture)$
|
||||
windowrule = float on, match:class ^(zoom)$
|
||||
|
||||
@@ -281,3 +271,7 @@ bind = ALT, Print, exec, dms screenshot window
|
||||
|
||||
# === System Controls ===
|
||||
bind = $mod SHIFT, P, dpms, toggle
|
||||
|
||||
source = ./dms/colors.conf
|
||||
source = ./dms/outputs.conf
|
||||
source = ./dms/layout.conf
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
// ! DO NOT EDIT !
|
||||
// ! AUTO-GENERATED BY DMS !
|
||||
// ! CHANGES WILL BE OVERWRITTEN !
|
||||
// ! PLACE YOUR CUSTOM CONFIGURATION ELSEWHERE !
|
||||
// ! Auto-generated file. Do not edit directly.
|
||||
// Remove `include "dms/colors.kdl"` from your config to override.
|
||||
|
||||
layout {
|
||||
background-color "transparent"
|
||||
|
||||
focus-ring {
|
||||
active-color "#9dcbfb"
|
||||
inactive-color "#8c9199"
|
||||
urgent-color "#ffb4ab"
|
||||
active-color "#d0bcff"
|
||||
inactive-color "#948f99"
|
||||
urgent-color "#f2b8b5"
|
||||
}
|
||||
|
||||
border {
|
||||
active-color "#9dcbfb"
|
||||
inactive-color "#8c9199"
|
||||
urgent-color "#ffb4ab"
|
||||
active-color "#d0bcff"
|
||||
inactive-color "#948f99"
|
||||
urgent-color "#f2b8b5"
|
||||
}
|
||||
|
||||
shadow {
|
||||
@@ -23,19 +21,19 @@ layout {
|
||||
}
|
||||
|
||||
tab-indicator {
|
||||
active-color "#9dcbfb"
|
||||
inactive-color "#8c9199"
|
||||
urgent-color "#ffb4ab"
|
||||
active-color "#d0bcff"
|
||||
inactive-color "#948f99"
|
||||
urgent-color "#f2b8b5"
|
||||
}
|
||||
|
||||
insert-hint {
|
||||
color "#9dcbfb80"
|
||||
color "#d0bcff80"
|
||||
}
|
||||
}
|
||||
|
||||
recent-windows {
|
||||
highlight {
|
||||
active-color "#124a73"
|
||||
urgent-color "#ffb4ab"
|
||||
active-color "#4f378b"
|
||||
urgent-color "#f2b8b5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,10 +240,6 @@ window-rule {
|
||||
match app-id="kitty"
|
||||
draw-border-with-background false
|
||||
}
|
||||
window-rule {
|
||||
match is-active=false
|
||||
opacity 0.9
|
||||
}
|
||||
window-rule {
|
||||
match app-id=r#"firefox$"# title="^Picture-in-Picture$"
|
||||
match app-id="zoom"
|
||||
@@ -273,3 +269,4 @@ include "dms/colors.kdl"
|
||||
include "dms/layout.kdl"
|
||||
include "dms/alttab.kdl"
|
||||
include "dms/binds.kdl"
|
||||
include "dms/outputs.kdl"
|
||||
|
||||
@@ -4,3 +4,9 @@ import _ "embed"
|
||||
|
||||
//go:embed embedded/hyprland.conf
|
||||
var HyprlandConfig string
|
||||
|
||||
//go:embed embedded/hypr-colors.conf
|
||||
var HyprColorsConfig string
|
||||
|
||||
//go:embed embedded/hypr-layout.conf
|
||||
var HyprLayoutConfig string
|
||||
|
||||
@@ -23,6 +23,47 @@ const (
|
||||
ColorModeLight ColorMode = "light"
|
||||
)
|
||||
|
||||
type TemplateKind int
|
||||
|
||||
const (
|
||||
TemplateKindNormal TemplateKind = iota
|
||||
TemplateKindTerminal
|
||||
TemplateKindGTK
|
||||
TemplateKindVSCode
|
||||
)
|
||||
|
||||
type TemplateDef struct {
|
||||
ID string
|
||||
Commands []string
|
||||
Flatpaks []string
|
||||
ConfigFile string
|
||||
Kind TemplateKind
|
||||
RunUnconditionally bool
|
||||
}
|
||||
|
||||
var templateRegistry = []TemplateDef{
|
||||
{ID: "gtk", Kind: TemplateKindGTK, RunUnconditionally: true},
|
||||
{ID: "niri", Commands: []string{"niri"}, ConfigFile: "niri.toml"},
|
||||
{ID: "hyprland", Commands: []string{"Hyprland"}, ConfigFile: "hyprland.toml"},
|
||||
{ID: "mangowc", Commands: []string{"mango"}, ConfigFile: "mangowc.toml"},
|
||||
{ID: "qt5ct", Commands: []string{"qt5ct"}, ConfigFile: "qt5ct.toml"},
|
||||
{ID: "qt6ct", Commands: []string{"qt6ct"}, ConfigFile: "qt6ct.toml"},
|
||||
{ID: "firefox", Commands: []string{"firefox"}, ConfigFile: "firefox.toml"},
|
||||
{ID: "pywalfox", Commands: []string{"pywalfox"}, ConfigFile: "pywalfox.toml"},
|
||||
{ID: "zenbrowser", Commands: []string{"zen", "zen-browser"}, Flatpaks: []string{"app.zen_browser.zen"}, ConfigFile: "zenbrowser.toml"},
|
||||
{ID: "vesktop", Commands: []string{"vesktop"}, Flatpaks: []string{"dev.vencord.Vesktop"}, ConfigFile: "vesktop.toml"},
|
||||
{ID: "equibop", Commands: []string{"equibop"}, ConfigFile: "equibop.toml"},
|
||||
{ID: "ghostty", Commands: []string{"ghostty"}, ConfigFile: "ghostty.toml", Kind: TemplateKindTerminal},
|
||||
{ID: "kitty", Commands: []string{"kitty"}, ConfigFile: "kitty.toml", Kind: TemplateKindTerminal},
|
||||
{ID: "foot", Commands: []string{"foot"}, ConfigFile: "foot.toml", Kind: TemplateKindTerminal},
|
||||
{ID: "alacritty", Commands: []string{"alacritty"}, ConfigFile: "alacritty.toml", Kind: TemplateKindTerminal},
|
||||
{ID: "wezterm", Commands: []string{"wezterm"}, ConfigFile: "wezterm.toml", Kind: TemplateKindTerminal},
|
||||
{ID: "nvim", Commands: []string{"nvim"}, ConfigFile: "neovim.toml", Kind: TemplateKindTerminal},
|
||||
{ID: "dgop", Commands: []string{"dgop"}, ConfigFile: "dgop.toml"},
|
||||
{ID: "kcolorscheme", ConfigFile: "kcolorscheme.toml", RunUnconditionally: true},
|
||||
{ID: "vscode", Kind: TemplateKindVSCode},
|
||||
}
|
||||
|
||||
func (c *ColorMode) GTKTheme() string {
|
||||
switch *c {
|
||||
case ColorModeDark:
|
||||
@@ -240,7 +281,7 @@ func buildMergedConfig(opts *Options, cfgFile *os.File, tmpDir string) error {
|
||||
if strings.TrimSpace(line) == "[config]" {
|
||||
continue
|
||||
}
|
||||
cfgFile.WriteString(substituteShellDir(line, opts.ShellDir) + "\n")
|
||||
cfgFile.WriteString(substituteVars(line, opts.ShellDir) + "\n")
|
||||
}
|
||||
cfgFile.WriteString("\n")
|
||||
}
|
||||
@@ -251,73 +292,31 @@ output_path = '%s'
|
||||
|
||||
`, opts.ShellDir, opts.ColorsOutput())
|
||||
|
||||
if !opts.ShouldSkipTemplate("gtk") {
|
||||
homeDir, _ := os.UserHomeDir()
|
||||
for _, tmpl := range templateRegistry {
|
||||
if opts.ShouldSkipTemplate(tmpl.ID) {
|
||||
continue
|
||||
}
|
||||
|
||||
switch tmpl.Kind {
|
||||
case TemplateKindGTK:
|
||||
switch opts.Mode {
|
||||
case "light":
|
||||
case ColorModeLight:
|
||||
appendConfig(opts, cfgFile, nil, nil, "gtk3-light.toml")
|
||||
default:
|
||||
appendConfig(opts, cfgFile, nil, nil, "gtk3-dark.toml")
|
||||
}
|
||||
}
|
||||
|
||||
if !opts.ShouldSkipTemplate("niri") {
|
||||
appendConfig(opts, cfgFile, []string{"niri"}, nil, "niri.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("qt5ct") {
|
||||
appendConfig(opts, cfgFile, []string{"qt5ct"}, nil, "qt5ct.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("qt6ct") {
|
||||
appendConfig(opts, cfgFile, []string{"qt6ct"}, nil, "qt6ct.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("firefox") {
|
||||
appendConfig(opts, cfgFile, []string{"firefox"}, nil, "firefox.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("pywalfox") {
|
||||
appendConfig(opts, cfgFile, []string{"pywalfox"}, nil, "pywalfox.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("zenbrowser") {
|
||||
appendConfig(opts, cfgFile, []string{"zen", "zen-browser"}, []string{"app.zen_browser.zen"}, "zenbrowser.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("vesktop") {
|
||||
appendConfig(opts, cfgFile, []string{"vesktop"}, []string{"dev.vencord.Vesktop"}, "vesktop.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("equibop") {
|
||||
appendConfig(opts, cfgFile, []string{"equibop"}, nil, "equibop.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("ghostty") {
|
||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"ghostty"}, nil, "ghostty.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("kitty") {
|
||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"kitty"}, nil, "kitty.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("foot") {
|
||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"foot"}, nil, "foot.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("alacritty") {
|
||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"alacritty"}, nil, "alacritty.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("wezterm") {
|
||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"wezterm"}, nil, "wezterm.toml")
|
||||
}
|
||||
if !opts.ShouldSkipTemplate("nvim") {
|
||||
appendTerminalConfig(opts, cfgFile, tmpDir, []string{"nvim"}, nil, "neovim.toml")
|
||||
}
|
||||
|
||||
if !opts.ShouldSkipTemplate("dgop") {
|
||||
appendConfig(opts, cfgFile, []string{"dgop"}, nil, "dgop.toml")
|
||||
}
|
||||
|
||||
if !opts.ShouldSkipTemplate("kcolorscheme") {
|
||||
appendConfig(opts, cfgFile, nil, nil, "kcolorscheme.toml")
|
||||
}
|
||||
|
||||
if !opts.ShouldSkipTemplate("vscode") {
|
||||
homeDir, _ := os.UserHomeDir()
|
||||
case TemplateKindTerminal:
|
||||
appendTerminalConfig(opts, cfgFile, tmpDir, tmpl.Commands, tmpl.Flatpaks, tmpl.ConfigFile)
|
||||
case TemplateKindVSCode:
|
||||
appendVSCodeConfig(cfgFile, "vscode", filepath.Join(homeDir, ".vscode/extensions"), opts.ShellDir)
|
||||
appendVSCodeConfig(cfgFile, "codium", filepath.Join(homeDir, ".vscode-oss/extensions"), opts.ShellDir)
|
||||
appendVSCodeConfig(cfgFile, "codeoss", filepath.Join(homeDir, ".config/Code - OSS/extensions"), opts.ShellDir)
|
||||
appendVSCodeConfig(cfgFile, "cursor", filepath.Join(homeDir, ".cursor/extensions"), opts.ShellDir)
|
||||
appendVSCodeConfig(cfgFile, "windsurf", filepath.Join(homeDir, ".windsurf/extensions"), opts.ShellDir)
|
||||
default:
|
||||
appendConfig(opts, cfgFile, tmpl.Commands, tmpl.Flatpaks, tmpl.ConfigFile)
|
||||
}
|
||||
}
|
||||
|
||||
if opts.RunUserTemplates {
|
||||
@@ -364,7 +363,7 @@ func appendConfig(
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
cfgFile.WriteString(substituteShellDir(string(data), opts.ShellDir))
|
||||
cfgFile.WriteString(substituteVars(string(data), opts.ShellDir))
|
||||
cfgFile.WriteString("\n")
|
||||
}
|
||||
|
||||
@@ -384,7 +383,7 @@ func appendTerminalConfig(opts *Options, cfgFile *os.File, tmpDir string, checkC
|
||||
content := string(data)
|
||||
|
||||
if !opts.TerminalsAlwaysDark {
|
||||
cfgFile.WriteString(substituteShellDir(content, opts.ShellDir))
|
||||
cfgFile.WriteString(substituteVars(content, opts.ShellDir))
|
||||
cfgFile.WriteString("\n")
|
||||
return
|
||||
}
|
||||
@@ -422,7 +421,7 @@ func appendTerminalConfig(opts *Options, cfgFile *os.File, tmpDir string, checkC
|
||||
fmt.Sprintf("'%s'", tmpPath))
|
||||
}
|
||||
|
||||
cfgFile.WriteString(substituteShellDir(content, opts.ShellDir))
|
||||
cfgFile.WriteString(substituteVars(content, opts.ShellDir))
|
||||
cfgFile.WriteString("\n")
|
||||
}
|
||||
|
||||
@@ -467,8 +466,12 @@ output_path = '%s/themes/dankshell-light.json'
|
||||
log.Infof("Added %s theme config (extension found at %s)", name, extDir)
|
||||
}
|
||||
|
||||
func substituteShellDir(content, shellDir string) string {
|
||||
return strings.ReplaceAll(content, "'SHELL_DIR/", "'"+shellDir+"/")
|
||||
func substituteVars(content, shellDir string) string {
|
||||
result := strings.ReplaceAll(content, "'SHELL_DIR/", "'"+shellDir+"/")
|
||||
result = strings.ReplaceAll(result, "'CONFIG_DIR/", "'"+utils.XDGConfigHome()+"/")
|
||||
result = strings.ReplaceAll(result, "'DATA_DIR/", "'"+utils.XDGDataHome()+"/")
|
||||
result = strings.ReplaceAll(result, "'CACHE_DIR/", "'"+utils.XDGCacheHome()+"/")
|
||||
return result
|
||||
}
|
||||
|
||||
func extractTOMLSection(content, startMarker, endMarker string) string {
|
||||
@@ -678,3 +681,52 @@ func syncColorScheme(mode ColorMode) {
|
||||
exec.Command("dconf", "write", "/org/gnome/desktop/interface/color-scheme", "'"+scheme+"'").Run()
|
||||
}
|
||||
}
|
||||
|
||||
type TemplateCheck struct {
|
||||
ID string `json:"id"`
|
||||
Detected bool `json:"detected"`
|
||||
}
|
||||
|
||||
func CheckTemplates(checker utils.AppChecker) []TemplateCheck {
|
||||
if checker == nil {
|
||||
checker = utils.DefaultAppChecker{}
|
||||
}
|
||||
|
||||
homeDir, _ := os.UserHomeDir()
|
||||
checks := make([]TemplateCheck, 0, len(templateRegistry))
|
||||
|
||||
for _, tmpl := range templateRegistry {
|
||||
detected := false
|
||||
|
||||
switch {
|
||||
case tmpl.RunUnconditionally:
|
||||
detected = true
|
||||
case tmpl.Kind == TemplateKindVSCode:
|
||||
detected = checkVSCodeExtension(homeDir)
|
||||
default:
|
||||
detected = appExists(checker, tmpl.Commands, tmpl.Flatpaks)
|
||||
}
|
||||
|
||||
checks = append(checks, TemplateCheck{ID: tmpl.ID, Detected: detected})
|
||||
}
|
||||
|
||||
return checks
|
||||
}
|
||||
|
||||
func checkVSCodeExtension(homeDir string) bool {
|
||||
extDirs := []string{
|
||||
filepath.Join(homeDir, ".vscode/extensions"),
|
||||
filepath.Join(homeDir, ".vscode-oss/extensions"),
|
||||
filepath.Join(homeDir, ".config/Code - OSS/extensions"),
|
||||
filepath.Join(homeDir, ".cursor/extensions"),
|
||||
filepath.Join(homeDir, ".windsurf/extensions"),
|
||||
}
|
||||
|
||||
for _, extDir := range extDirs {
|
||||
pattern := filepath.Join(extDir, "danklinux.dms-theme-*")
|
||||
if matches, err := filepath.Glob(pattern); err == nil && len(matches) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import (
|
||||
"testing"
|
||||
|
||||
mocks_utils "github.com/AvengeMedia/DankMaterialShell/core/internal/mocks/utils"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAppendConfigBinaryExists(t *testing.T) {
|
||||
@@ -321,3 +323,72 @@ func TestAppendConfigFileDoesNotExist(t *testing.T) {
|
||||
t.Errorf("expected no config when file doesn't exist, got: %q", string(output))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSubstituteVars(t *testing.T) {
|
||||
configDir := utils.XDGConfigHome()
|
||||
dataDir := utils.XDGDataHome()
|
||||
cacheDir := utils.XDGCacheHome()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
shellDir string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "substitutes SHELL_DIR",
|
||||
input: "input_path = 'SHELL_DIR/matugen/templates/foo.conf'",
|
||||
shellDir: "/home/user/shell",
|
||||
expected: "input_path = '/home/user/shell/matugen/templates/foo.conf'",
|
||||
},
|
||||
{
|
||||
name: "substitutes CONFIG_DIR",
|
||||
input: "output_path = 'CONFIG_DIR/kitty/theme.conf'",
|
||||
shellDir: "/home/user/shell",
|
||||
expected: "output_path = '" + configDir + "/kitty/theme.conf'",
|
||||
},
|
||||
{
|
||||
name: "substitutes DATA_DIR",
|
||||
input: "output_path = 'DATA_DIR/color-schemes/theme.colors'",
|
||||
shellDir: "/home/user/shell",
|
||||
expected: "output_path = '" + dataDir + "/color-schemes/theme.colors'",
|
||||
},
|
||||
{
|
||||
name: "substitutes CACHE_DIR",
|
||||
input: "output_path = 'CACHE_DIR/wal/colors.json'",
|
||||
shellDir: "/home/user/shell",
|
||||
expected: "output_path = '" + cacheDir + "/wal/colors.json'",
|
||||
},
|
||||
{
|
||||
name: "substitutes all dir types",
|
||||
input: "'SHELL_DIR/a' 'CONFIG_DIR/b' 'DATA_DIR/c' 'CACHE_DIR/d'",
|
||||
shellDir: "/shell",
|
||||
expected: "'/shell/a' '" + configDir + "/b' '" + dataDir + "/c' '" + cacheDir + "/d'",
|
||||
},
|
||||
{
|
||||
name: "no substitution when no placeholders",
|
||||
input: "input_path = '/absolute/path/foo.conf'",
|
||||
shellDir: "/home/user/shell",
|
||||
expected: "input_path = '/absolute/path/foo.conf'",
|
||||
},
|
||||
{
|
||||
name: "multiple SHELL_DIR occurrences",
|
||||
input: "'SHELL_DIR/a' and 'SHELL_DIR/b'",
|
||||
shellDir: "/shell",
|
||||
expected: "'/shell/a' and '/shell/b'",
|
||||
},
|
||||
{
|
||||
name: "only substitutes quoted paths",
|
||||
input: "SHELL_DIR/unquoted and 'SHELL_DIR/quoted'",
|
||||
shellDir: "/shell",
|
||||
expected: "SHELL_DIR/unquoted and '/shell/quoted'",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
result := substituteVars(tc.input, tc.shellDir)
|
||||
assert.Equal(t, tc.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,32 @@ func XDGStateHome() string {
|
||||
if dir := os.Getenv("XDG_STATE_HOME"); dir != "" {
|
||||
return dir
|
||||
}
|
||||
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(append([]string{home}, ".local", "state")...)
|
||||
return filepath.Join(home, ".local", "state")
|
||||
}
|
||||
|
||||
func XDGDataHome() string {
|
||||
if dir := os.Getenv("XDG_DATA_HOME"); dir != "" {
|
||||
return dir
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, ".local", "share")
|
||||
}
|
||||
|
||||
func XDGCacheHome() string {
|
||||
if dir, err := os.UserCacheDir(); err == nil {
|
||||
return dir
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, ".cache")
|
||||
}
|
||||
|
||||
func XDGConfigHome() string {
|
||||
if dir, err := os.UserConfigDir(); err == nil {
|
||||
return dir
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
return filepath.Join(home, ".config")
|
||||
}
|
||||
|
||||
func ExpandPath(path string) (string, error) {
|
||||
|
||||
@@ -118,8 +118,56 @@ Singleton {
|
||||
parseSettings(greeterSessionFile.text());
|
||||
return;
|
||||
}
|
||||
parseSettings(settingsFile.text());
|
||||
|
||||
try {
|
||||
const txt = settingsFile.text();
|
||||
let obj = (txt && txt.trim()) ? JSON.parse(txt) : null;
|
||||
|
||||
if (obj?.brightnessLogarithmicDevices && !obj?.brightnessExponentialDevices)
|
||||
obj.brightnessExponentialDevices = obj.brightnessLogarithmicDevices;
|
||||
|
||||
if (obj?.nightModeStartTime !== undefined) {
|
||||
const parts = obj.nightModeStartTime.split(":");
|
||||
obj.nightModeStartHour = parseInt(parts[0]) || 18;
|
||||
obj.nightModeStartMinute = parseInt(parts[1]) || 0;
|
||||
}
|
||||
if (obj?.nightModeEndTime !== undefined) {
|
||||
const parts = obj.nightModeEndTime.split(":");
|
||||
obj.nightModeEndHour = parseInt(parts[0]) || 6;
|
||||
obj.nightModeEndMinute = parseInt(parts[1]) || 0;
|
||||
}
|
||||
|
||||
const oldVersion = obj?.configVersion ?? 0;
|
||||
if (obj && oldVersion === 0)
|
||||
migrateFromUndefinedToV1(obj);
|
||||
|
||||
if (obj && oldVersion < sessionConfigVersion) {
|
||||
const settingsDataRef = (typeof SettingsData !== "undefined") ? SettingsData : null;
|
||||
const migrated = Store.migrateToVersion(obj, sessionConfigVersion, settingsDataRef);
|
||||
if (migrated) {
|
||||
_pendingMigration = migrated;
|
||||
obj = migrated;
|
||||
}
|
||||
}
|
||||
|
||||
Store.parse(root, obj);
|
||||
|
||||
_loadedSessionSnapshot = getCurrentSessionJson();
|
||||
_hasLoaded = true;
|
||||
|
||||
if (!isGreeterMode && typeof Theme !== "undefined")
|
||||
Theme.generateSystemThemesFromCurrentTheme();
|
||||
|
||||
if (typeof WallpaperCyclingService !== "undefined")
|
||||
WallpaperCyclingService.updateCyclingState();
|
||||
|
||||
_checkSessionWritable();
|
||||
} catch (e) {
|
||||
_parseError = true;
|
||||
const msg = e.message;
|
||||
console.error("SessionData: Failed to parse session.json - file will not be overwritten. Error:", msg);
|
||||
Qt.callLater(() => ToastService.showError(I18n.tr("Failed to parse session.json"), msg));
|
||||
}
|
||||
}
|
||||
|
||||
function _checkSessionWritable() {
|
||||
@@ -158,29 +206,27 @@ Singleton {
|
||||
function parseSettings(content) {
|
||||
_parseError = false;
|
||||
try {
|
||||
let obj = (content && content.trim()) ? JSON.parse(content) : {};
|
||||
let obj = (content && content.trim()) ? JSON.parse(content) : null;
|
||||
|
||||
if (obj.brightnessLogarithmicDevices && !obj.brightnessExponentialDevices) {
|
||||
if (obj?.brightnessLogarithmicDevices && !obj?.brightnessExponentialDevices)
|
||||
obj.brightnessExponentialDevices = obj.brightnessLogarithmicDevices;
|
||||
}
|
||||
|
||||
if (obj.nightModeStartTime !== undefined) {
|
||||
if (obj?.nightModeStartTime !== undefined) {
|
||||
const parts = obj.nightModeStartTime.split(":");
|
||||
obj.nightModeStartHour = parseInt(parts[0]) || 18;
|
||||
obj.nightModeStartMinute = parseInt(parts[1]) || 0;
|
||||
}
|
||||
if (obj.nightModeEndTime !== undefined) {
|
||||
if (obj?.nightModeEndTime !== undefined) {
|
||||
const parts = obj.nightModeEndTime.split(":");
|
||||
obj.nightModeEndHour = parseInt(parts[0]) || 6;
|
||||
obj.nightModeEndMinute = parseInt(parts[1]) || 0;
|
||||
}
|
||||
|
||||
const oldVersion = obj.configVersion ?? 0;
|
||||
if (oldVersion === 0) {
|
||||
const oldVersion = obj?.configVersion ?? 0;
|
||||
if (obj && oldVersion === 0)
|
||||
migrateFromUndefinedToV1(obj);
|
||||
}
|
||||
|
||||
if (oldVersion < sessionConfigVersion) {
|
||||
if (obj && oldVersion < sessionConfigVersion) {
|
||||
const settingsDataRef = (typeof SettingsData !== "undefined") ? SettingsData : null;
|
||||
const migrated = Store.migrateToVersion(obj, sessionConfigVersion, settingsDataRef);
|
||||
if (migrated) {
|
||||
@@ -191,22 +237,14 @@ Singleton {
|
||||
|
||||
Store.parse(root, obj);
|
||||
|
||||
if (wallpaperPath && wallpaperPath.startsWith("we:")) {
|
||||
console.warn("WallpaperEngine wallpaper detected, resetting wallpaper");
|
||||
wallpaperPath = "";
|
||||
Quickshell.execDetached(["notify-send", "-u", "critical", "-a", "DMS", "-i", "dialog-warning", "WallpaperEngine Support Moved", "WallpaperEngine support has been moved to a plugin. Please enable the Linux Wallpaper Engine plugin in Settings → Plugins to continue using WallpaperEngine."]);
|
||||
}
|
||||
|
||||
_hasLoaded = true;
|
||||
_loadedSessionSnapshot = getCurrentSessionJson();
|
||||
_hasLoaded = true;
|
||||
|
||||
if (!isGreeterMode && typeof Theme !== "undefined") {
|
||||
if (!isGreeterMode && typeof Theme !== "undefined")
|
||||
Theme.generateSystemThemesFromCurrentTheme();
|
||||
}
|
||||
|
||||
if (typeof WallpaperCyclingService !== "undefined") {
|
||||
if (typeof WallpaperCyclingService !== "undefined")
|
||||
WallpaperCyclingService.updateCyclingState();
|
||||
}
|
||||
} catch (e) {
|
||||
_parseError = true;
|
||||
const msg = e.message;
|
||||
|
||||
@@ -81,6 +81,13 @@ Singleton {
|
||||
property real cornerRadius: 12
|
||||
property int niriLayoutGapsOverride: -1
|
||||
property int niriLayoutRadiusOverride: -1
|
||||
property int niriLayoutBorderSize: -1
|
||||
property int hyprlandLayoutGapsOverride: -1
|
||||
property int hyprlandLayoutRadiusOverride: -1
|
||||
property int hyprlandLayoutBorderSize: -1
|
||||
property int mangoLayoutGapsOverride: -1
|
||||
property int mangoLayoutRadiusOverride: -1
|
||||
property int mangoLayoutBorderSize: -1
|
||||
|
||||
property bool use24HourClock: true
|
||||
property bool showSeconds: false
|
||||
@@ -295,6 +302,8 @@ Singleton {
|
||||
property bool runDmsMatugenTemplates: true
|
||||
property bool matugenTemplateGtk: true
|
||||
property bool matugenTemplateNiri: true
|
||||
property bool matugenTemplateHyprland: true
|
||||
property bool matugenTemplateMangowc: true
|
||||
property bool matugenTemplateQt5ct: true
|
||||
property bool matugenTemplateQt6ct: true
|
||||
property bool matugenTemplateFirefox: true
|
||||
@@ -699,10 +708,15 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
function updateNiriLayout() {
|
||||
if (typeof NiriService !== "undefined" && typeof CompositorService !== "undefined" && CompositorService.isNiri) {
|
||||
function updateCompositorLayout() {
|
||||
if (typeof CompositorService === "undefined")
|
||||
return;
|
||||
if (CompositorService.isNiri && typeof NiriService !== "undefined")
|
||||
NiriService.generateNiriLayoutConfig();
|
||||
}
|
||||
if (CompositorService.isHyprland && typeof HyprlandService !== "undefined")
|
||||
HyprlandService.generateLayoutConfig();
|
||||
if (CompositorService.isDwl && typeof DwlService !== "undefined")
|
||||
DwlService.generateLayoutConfig();
|
||||
}
|
||||
|
||||
function applyStoredIconTheme() {
|
||||
@@ -778,7 +792,7 @@ Singleton {
|
||||
readonly property var _hooks: ({
|
||||
"applyStoredTheme": applyStoredTheme,
|
||||
"regenSystemThemes": regenSystemThemes,
|
||||
"updateNiriLayout": updateNiriLayout,
|
||||
"updateCompositorLayout": updateCompositorLayout,
|
||||
"applyStoredIconTheme": applyStoredIconTheme,
|
||||
"updateBarConfigs": updateBarConfigs
|
||||
})
|
||||
@@ -1459,7 +1473,7 @@ Singleton {
|
||||
|
||||
function setCornerRadius(radius) {
|
||||
set("cornerRadius", radius);
|
||||
NiriService.generateNiriLayoutConfig();
|
||||
updateCompositorLayout();
|
||||
}
|
||||
|
||||
function setWeatherLocation(displayName, coordinates) {
|
||||
@@ -1541,9 +1555,7 @@ Singleton {
|
||||
"spacing": spacing
|
||||
});
|
||||
}
|
||||
if (typeof NiriService !== "undefined" && CompositorService.isNiri) {
|
||||
NiriService.generateNiriLayoutConfig();
|
||||
}
|
||||
updateCompositorLayout();
|
||||
}
|
||||
|
||||
function setDankBarPosition(position) {
|
||||
|
||||
@@ -910,6 +910,10 @@ Singleton {
|
||||
skipTemplates.push("gtk");
|
||||
if (!SettingsData.matugenTemplateNiri)
|
||||
skipTemplates.push("niri");
|
||||
if (!SettingsData.matugenTemplateHyprland)
|
||||
skipTemplates.push("hyprland");
|
||||
if (!SettingsData.matugenTemplateMangowc)
|
||||
skipTemplates.push("mangowc");
|
||||
if (!SettingsData.matugenTemplateQt5ct)
|
||||
skipTemplates.push("qt5ct");
|
||||
if (!SettingsData.matugenTemplateQt6ct)
|
||||
|
||||
@@ -19,9 +19,16 @@ var SPEC = {
|
||||
|
||||
widgetBackgroundColor: { def: "sch" },
|
||||
widgetColorMode: { def: "default" },
|
||||
cornerRadius: { def: 12, onChange: "updateNiriLayout" },
|
||||
niriLayoutGapsOverride: { def: -1, onChange: "updateNiriLayout" },
|
||||
niriLayoutRadiusOverride: { def: -1, onChange: "updateNiriLayout" },
|
||||
cornerRadius: { def: 12, onChange: "updateCompositorLayout" },
|
||||
niriLayoutGapsOverride: { def: -1, onChange: "updateCompositorLayout" },
|
||||
niriLayoutRadiusOverride: { def: -1, onChange: "updateCompositorLayout" },
|
||||
niriLayoutBorderSize: { def: -1, onChange: "updateCompositorLayout" },
|
||||
hyprlandLayoutGapsOverride: { def: -1, onChange: "updateCompositorLayout" },
|
||||
hyprlandLayoutRadiusOverride: { def: -1, onChange: "updateCompositorLayout" },
|
||||
hyprlandLayoutBorderSize: { def: -1, onChange: "updateCompositorLayout" },
|
||||
mangoLayoutGapsOverride: { def: -1, onChange: "updateCompositorLayout" },
|
||||
mangoLayoutRadiusOverride: { def: -1, onChange: "updateCompositorLayout" },
|
||||
mangoLayoutBorderSize: { def: -1, onChange: "updateCompositorLayout" },
|
||||
|
||||
use24HourClock: { def: true },
|
||||
showSeconds: { def: false },
|
||||
@@ -185,6 +192,8 @@ var SPEC = {
|
||||
runDmsMatugenTemplates: { def: true },
|
||||
matugenTemplateGtk: { def: true },
|
||||
matugenTemplateNiri: { def: true },
|
||||
matugenTemplateHyprland: { def: true },
|
||||
matugenTemplateMangowc: { def: true },
|
||||
matugenTemplateQt5ct: { def: true },
|
||||
matugenTemplateQt6ct: { def: true },
|
||||
matugenTemplateFirefox: { def: true },
|
||||
|
||||
@@ -727,7 +727,7 @@ FocusScope {
|
||||
id: gridScrollbar
|
||||
}
|
||||
|
||||
ScrollBar.horizontal: ScrollBar {
|
||||
ScrollBar.horizontal: DankScrollbar {
|
||||
policy: ScrollBar.AlwaysOff
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.Common
|
||||
import qs.Modals.FileBrowser
|
||||
import qs.Services
|
||||
@@ -13,6 +14,27 @@ Item {
|
||||
property var cachedIconThemes: SettingsData.availableIconThemes
|
||||
property var cachedMatugenSchemes: Theme.availableMatugenSchemes.map(option => option.label)
|
||||
property var installedRegistryThemes: []
|
||||
property var templateDetection: ({})
|
||||
|
||||
function isTemplateDetected(templateId) {
|
||||
if (!templateDetection || Object.keys(templateDetection).length === 0)
|
||||
return true;
|
||||
return templateDetection[templateId] !== false;
|
||||
}
|
||||
|
||||
function getTemplateDescription(templateId, baseDescription) {
|
||||
if (isTemplateDetected(templateId))
|
||||
return baseDescription;
|
||||
if (baseDescription)
|
||||
return baseDescription + " · " + I18n.tr("Not detected");
|
||||
return I18n.tr("Not detected");
|
||||
}
|
||||
|
||||
function getTemplateDescriptionColor(templateId) {
|
||||
if (isTemplateDetected(templateId))
|
||||
return Theme.surfaceVariantText;
|
||||
return Theme.warning;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
SettingsData.detectAvailableIconThemes();
|
||||
@@ -20,6 +42,28 @@ Item {
|
||||
DMSService.listInstalledThemes();
|
||||
if (PopoutService.pendingThemeInstall)
|
||||
Qt.callLater(() => themeBrowser.show());
|
||||
templateCheckProcess.running = true;
|
||||
}
|
||||
|
||||
Process {
|
||||
id: templateCheckProcess
|
||||
command: ["dms", "matugen", "check"]
|
||||
running: false
|
||||
|
||||
stdout: StdioCollector {
|
||||
onStreamFinished: {
|
||||
try {
|
||||
const results = JSON.parse(text);
|
||||
const detection = {};
|
||||
for (const item of results) {
|
||||
detection[item.id] = item.detected;
|
||||
}
|
||||
themeColorsTab.templateDetection = detection;
|
||||
} catch (e) {
|
||||
console.warn("ThemeColorsTab: Failed to parse template check:", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
@@ -918,7 +962,7 @@ Item {
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["niri", "layout", "gaps", "radius", "window"]
|
||||
tags: ["niri", "layout", "gaps", "radius", "window", "border"]
|
||||
title: I18n.tr("Niri Layout Overrides")
|
||||
settingKey: "niriLayout"
|
||||
iconName: "crop_square"
|
||||
@@ -986,6 +1030,243 @@ Item {
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("niriLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["niri", "border", "override"]
|
||||
settingKey: "niriLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border/focus-ring width")
|
||||
checked: SettingsData.niriLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("niriLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("niriLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["niri", "border", "override"]
|
||||
settingKey: "niriLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border and focus ring")
|
||||
visible: SettingsData.niriLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.niriLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("niriLayoutBorderSize", newValue)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "layout", "gaps", "radius", "window", "border", "rounding"]
|
||||
title: I18n.tr("Hyprland Layout Overrides")
|
||||
settingKey: "hyprlandLayout"
|
||||
iconName: "crop_square"
|
||||
visible: CompositorService.isHyprland
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "gaps", "override"]
|
||||
settingKey: "hyprlandLayoutGapsOverrideEnabled"
|
||||
text: I18n.tr("Override Gaps")
|
||||
description: I18n.tr("Use custom gaps instead of bar spacing")
|
||||
checked: SettingsData.hyprlandLayoutGapsOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
const currentGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
SettingsData.set("hyprlandLayoutGapsOverride", currentGaps);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutGapsOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "gaps", "override"]
|
||||
settingKey: "hyprlandLayoutGapsOverride"
|
||||
text: I18n.tr("Window Gaps")
|
||||
description: I18n.tr("Space between windows (gaps_in and gaps_out)")
|
||||
visible: SettingsData.hyprlandLayoutGapsOverride >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutGapsOverride)
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
unit: "px"
|
||||
defaultValue: Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4))
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutGapsOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "radius", "override", "rounding"]
|
||||
settingKey: "hyprlandLayoutRadiusOverrideEnabled"
|
||||
text: I18n.tr("Override Corner Radius")
|
||||
description: I18n.tr("Use custom window rounding instead of theme radius")
|
||||
checked: SettingsData.hyprlandLayoutRadiusOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("hyprlandLayoutRadiusOverride", SettingsData.cornerRadius);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutRadiusOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "radius", "override", "rounding"]
|
||||
settingKey: "hyprlandLayoutRadiusOverride"
|
||||
text: I18n.tr("Window Rounding")
|
||||
description: I18n.tr("Rounded corners for windows (decoration.rounding)")
|
||||
visible: SettingsData.hyprlandLayoutRadiusOverride >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutRadiusOverride)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "border", "override"]
|
||||
settingKey: "hyprlandLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border size")
|
||||
checked: SettingsData.hyprlandLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("hyprlandLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("hyprlandLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["hyprland", "border", "override"]
|
||||
settingKey: "hyprlandLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border (general.border_size)")
|
||||
visible: SettingsData.hyprlandLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.hyprlandLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("hyprlandLayoutBorderSize", newValue)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "dwl", "layout", "gaps", "radius", "window", "border"]
|
||||
title: I18n.tr("MangoWC Layout Overrides")
|
||||
settingKey: "mangoLayout"
|
||||
iconName: "crop_square"
|
||||
visible: CompositorService.isDwl
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "gaps", "override"]
|
||||
settingKey: "mangoLayoutGapsOverrideEnabled"
|
||||
text: I18n.tr("Override Gaps")
|
||||
description: I18n.tr("Use custom gaps instead of bar spacing")
|
||||
checked: SettingsData.mangoLayoutGapsOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
const currentGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
SettingsData.set("mangoLayoutGapsOverride", currentGaps);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutGapsOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "gaps", "override"]
|
||||
settingKey: "mangoLayoutGapsOverride"
|
||||
text: I18n.tr("Window Gaps")
|
||||
description: I18n.tr("Space between windows (gappih/gappiv/gappoh/gappov)")
|
||||
visible: SettingsData.mangoLayoutGapsOverride >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutGapsOverride)
|
||||
minimum: 0
|
||||
maximum: 50
|
||||
unit: "px"
|
||||
defaultValue: Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4))
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutGapsOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "radius", "override"]
|
||||
settingKey: "mangoLayoutRadiusOverrideEnabled"
|
||||
text: I18n.tr("Override Corner Radius")
|
||||
description: I18n.tr("Use custom window radius instead of theme radius")
|
||||
checked: SettingsData.mangoLayoutRadiusOverride >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("mangoLayoutRadiusOverride", SettingsData.cornerRadius);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutRadiusOverride", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "radius", "override"]
|
||||
settingKey: "mangoLayoutRadiusOverride"
|
||||
text: I18n.tr("Window Corner Radius")
|
||||
description: I18n.tr("Rounded corners for windows (border_radius)")
|
||||
visible: SettingsData.mangoLayoutRadiusOverride >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutRadiusOverride)
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
unit: "px"
|
||||
defaultValue: SettingsData.cornerRadius
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutRadiusOverride", newValue)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "border", "override"]
|
||||
settingKey: "mangoLayoutBorderSizeEnabled"
|
||||
text: I18n.tr("Override Border Size")
|
||||
description: I18n.tr("Use custom border size")
|
||||
checked: SettingsData.mangoLayoutBorderSize >= 0
|
||||
onToggled: checked => {
|
||||
if (checked) {
|
||||
SettingsData.set("mangoLayoutBorderSize", 2);
|
||||
return;
|
||||
}
|
||||
SettingsData.set("mangoLayoutBorderSize", -1);
|
||||
}
|
||||
}
|
||||
|
||||
SettingsSliderRow {
|
||||
tab: "theme"
|
||||
tags: ["mangowc", "mango", "border", "override"]
|
||||
settingKey: "mangoLayoutBorderSize"
|
||||
text: I18n.tr("Border Size")
|
||||
description: I18n.tr("Width of window border (borderpx)")
|
||||
visible: SettingsData.mangoLayoutBorderSize >= 0
|
||||
value: Math.max(0, SettingsData.mangoLayoutBorderSize)
|
||||
minimum: 0
|
||||
maximum: 10
|
||||
unit: "px"
|
||||
defaultValue: 2
|
||||
onSliderValueChanged: newValue => SettingsData.set("mangoLayoutBorderSize", newValue)
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCard {
|
||||
@@ -1066,7 +1347,8 @@ Item {
|
||||
tags: ["matugen", "gtk", "template"]
|
||||
settingKey: "matugenTemplateGtk"
|
||||
text: "GTK"
|
||||
description: ""
|
||||
description: getTemplateDescription("gtk", "")
|
||||
descriptionColor: getTemplateDescriptionColor("gtk")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateGtk
|
||||
onToggled: checked => SettingsData.set("matugenTemplateGtk", checked)
|
||||
@@ -1077,18 +1359,44 @@ Item {
|
||||
tags: ["matugen", "niri", "template"]
|
||||
settingKey: "matugenTemplateNiri"
|
||||
text: "niri"
|
||||
description: ""
|
||||
description: getTemplateDescription("niri", "")
|
||||
descriptionColor: getTemplateDescriptionColor("niri")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateNiri
|
||||
onToggled: checked => SettingsData.set("matugenTemplateNiri", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["matugen", "hyprland", "template"]
|
||||
settingKey: "matugenTemplateHyprland"
|
||||
text: "Hyprland"
|
||||
description: getTemplateDescription("hyprland", "")
|
||||
descriptionColor: getTemplateDescriptionColor("hyprland")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateHyprland
|
||||
onToggled: checked => SettingsData.set("matugenTemplateHyprland", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["matugen", "mangowc", "template"]
|
||||
settingKey: "matugenTemplateMangowc"
|
||||
text: "mangowc"
|
||||
description: getTemplateDescription("mangowc", "")
|
||||
descriptionColor: getTemplateDescriptionColor("mangowc")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateMangowc
|
||||
onToggled: checked => SettingsData.set("matugenTemplateMangowc", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["matugen", "qt5ct", "template"]
|
||||
settingKey: "matugenTemplateQt5ct"
|
||||
text: "qt5ct"
|
||||
description: ""
|
||||
description: getTemplateDescription("qt5ct", "")
|
||||
descriptionColor: getTemplateDescriptionColor("qt5ct")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateQt5ct
|
||||
onToggled: checked => SettingsData.set("matugenTemplateQt5ct", checked)
|
||||
@@ -1099,7 +1407,8 @@ Item {
|
||||
tags: ["matugen", "qt6ct", "template"]
|
||||
settingKey: "matugenTemplateQt6ct"
|
||||
text: "qt6ct"
|
||||
description: ""
|
||||
description: getTemplateDescription("qt6ct", "")
|
||||
descriptionColor: getTemplateDescriptionColor("qt6ct")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateQt6ct
|
||||
onToggled: checked => SettingsData.set("matugenTemplateQt6ct", checked)
|
||||
@@ -1110,7 +1419,8 @@ Item {
|
||||
tags: ["matugen", "firefox", "template"]
|
||||
settingKey: "matugenTemplateFirefox"
|
||||
text: "Firefox"
|
||||
description: ""
|
||||
description: getTemplateDescription("firefox", "")
|
||||
descriptionColor: getTemplateDescriptionColor("firefox")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateFirefox
|
||||
onToggled: checked => SettingsData.set("matugenTemplateFirefox", checked)
|
||||
@@ -1121,7 +1431,8 @@ Item {
|
||||
tags: ["matugen", "pywalfox", "template"]
|
||||
settingKey: "matugenTemplatePywalfox"
|
||||
text: "pywalfox"
|
||||
description: ""
|
||||
description: getTemplateDescription("pywalfox", "")
|
||||
descriptionColor: getTemplateDescriptionColor("pywalfox")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplatePywalfox
|
||||
onToggled: checked => SettingsData.set("matugenTemplatePywalfox", checked)
|
||||
@@ -1132,7 +1443,8 @@ Item {
|
||||
tags: ["matugen", "zenbrowser", "template"]
|
||||
settingKey: "matugenTemplateZenBrowser"
|
||||
text: "zenbrowser"
|
||||
description: ""
|
||||
description: getTemplateDescription("zenbrowser", "")
|
||||
descriptionColor: getTemplateDescriptionColor("zenbrowser")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateZenBrowser
|
||||
onToggled: checked => SettingsData.set("matugenTemplateZenBrowser", checked)
|
||||
@@ -1143,7 +1455,8 @@ Item {
|
||||
tags: ["matugen", "vesktop", "discord", "template"]
|
||||
settingKey: "matugenTemplateVesktop"
|
||||
text: "vesktop"
|
||||
description: ""
|
||||
description: getTemplateDescription("vesktop", "")
|
||||
descriptionColor: getTemplateDescriptionColor("vesktop")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateVesktop
|
||||
onToggled: checked => SettingsData.set("matugenTemplateVesktop", checked)
|
||||
@@ -1154,7 +1467,8 @@ Item {
|
||||
tags: ["matugen", "equibop", "discord", "template"]
|
||||
settingKey: "matugenTemplateEquibop"
|
||||
text: "equibop"
|
||||
description: ""
|
||||
description: getTemplateDescription("equibop", "")
|
||||
descriptionColor: getTemplateDescriptionColor("equibop")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateEquibop
|
||||
onToggled: checked => SettingsData.set("matugenTemplateEquibop", checked)
|
||||
@@ -1165,7 +1479,8 @@ Item {
|
||||
tags: ["matugen", "ghostty", "terminal", "template"]
|
||||
settingKey: "matugenTemplateGhostty"
|
||||
text: "Ghostty"
|
||||
description: ""
|
||||
description: getTemplateDescription("ghostty", "")
|
||||
descriptionColor: getTemplateDescriptionColor("ghostty")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateGhostty
|
||||
onToggled: checked => SettingsData.set("matugenTemplateGhostty", checked)
|
||||
@@ -1176,7 +1491,8 @@ Item {
|
||||
tags: ["matugen", "kitty", "terminal", "template"]
|
||||
settingKey: "matugenTemplateKitty"
|
||||
text: "kitty"
|
||||
description: ""
|
||||
description: getTemplateDescription("kitty", "")
|
||||
descriptionColor: getTemplateDescriptionColor("kitty")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateKitty
|
||||
onToggled: checked => SettingsData.set("matugenTemplateKitty", checked)
|
||||
@@ -1187,17 +1503,20 @@ Item {
|
||||
tags: ["matugen", "foot", "terminal", "template"]
|
||||
settingKey: "matugenTemplateFoot"
|
||||
text: "foot"
|
||||
description: ""
|
||||
description: getTemplateDescription("foot", "")
|
||||
descriptionColor: getTemplateDescriptionColor("foot")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateFoot
|
||||
onToggled: checked => SettingsData.set("matugenTemplateFoot", checked)
|
||||
}
|
||||
|
||||
SettingsToggleRow {
|
||||
tab: "theme"
|
||||
tags: ["matugen", "neovim", "terminal", "template"]
|
||||
settingKey: "matugenTemplateNeovim"
|
||||
text: "neovim"
|
||||
description: "Requires lazy plugin manager"
|
||||
description: getTemplateDescription("nvim", "Requires lazy plugin manager")
|
||||
descriptionColor: getTemplateDescriptionColor("nvim")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateNeovim
|
||||
onToggled: checked => SettingsData.set("matugenTemplateNeovim", checked)
|
||||
@@ -1208,7 +1527,8 @@ Item {
|
||||
tags: ["matugen", "alacritty", "terminal", "template"]
|
||||
settingKey: "matugenTemplateAlacritty"
|
||||
text: "Alacritty"
|
||||
description: ""
|
||||
description: getTemplateDescription("alacritty", "")
|
||||
descriptionColor: getTemplateDescriptionColor("alacritty")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateAlacritty
|
||||
onToggled: checked => SettingsData.set("matugenTemplateAlacritty", checked)
|
||||
@@ -1219,7 +1539,8 @@ Item {
|
||||
tags: ["matugen", "wezterm", "terminal", "template"]
|
||||
settingKey: "matugenTemplateWezterm"
|
||||
text: "WezTerm"
|
||||
description: ""
|
||||
description: getTemplateDescription("wezterm", "")
|
||||
descriptionColor: getTemplateDescriptionColor("wezterm")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateWezterm
|
||||
onToggled: checked => SettingsData.set("matugenTemplateWezterm", checked)
|
||||
@@ -1230,7 +1551,8 @@ Item {
|
||||
tags: ["matugen", "dgop", "template"]
|
||||
settingKey: "matugenTemplateDgop"
|
||||
text: "dgop"
|
||||
description: ""
|
||||
description: getTemplateDescription("dgop", "")
|
||||
descriptionColor: getTemplateDescriptionColor("dgop")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateDgop
|
||||
onToggled: checked => SettingsData.set("matugenTemplateDgop", checked)
|
||||
@@ -1241,7 +1563,8 @@ Item {
|
||||
tags: ["matugen", "kcolorscheme", "kde", "template"]
|
||||
settingKey: "matugenTemplateKcolorscheme"
|
||||
text: "KColorScheme"
|
||||
description: ""
|
||||
description: getTemplateDescription("kcolorscheme", "")
|
||||
descriptionColor: getTemplateDescriptionColor("kcolorscheme")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateKcolorscheme
|
||||
onToggled: checked => SettingsData.set("matugenTemplateKcolorscheme", checked)
|
||||
@@ -1252,7 +1575,8 @@ Item {
|
||||
tags: ["matugen", "vscode", "code", "template"]
|
||||
settingKey: "matugenTemplateVscode"
|
||||
text: "VS Code"
|
||||
description: ""
|
||||
description: getTemplateDescription("vscode", "")
|
||||
descriptionColor: getTemplateDescriptionColor("vscode")
|
||||
visible: SettingsData.runDmsMatugenTemplates
|
||||
checked: SettingsData.matugenTemplateVscode
|
||||
onToggled: checked => SettingsData.set("matugenTemplateVscode", checked)
|
||||
|
||||
@@ -137,7 +137,11 @@ Singleton {
|
||||
Component.onCompleted: {
|
||||
detectCompositor();
|
||||
scheduleSort();
|
||||
Qt.callLater(() => NiriService.generateNiriLayoutConfig());
|
||||
Qt.callLater(() => {
|
||||
NiriService.generateNiriLayoutConfig();
|
||||
HyprlandService.generateLayoutConfig();
|
||||
DwlService.generateLayoutConfig();
|
||||
});
|
||||
}
|
||||
|
||||
Connections {
|
||||
@@ -396,7 +400,11 @@ Singleton {
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
detectCompositor();
|
||||
Qt.callLater(() => NiriService.generateNiriLayoutConfig());
|
||||
Qt.callLater(() => {
|
||||
NiriService.generateNiriLayoutConfig();
|
||||
HyprlandService.generateLayoutConfig();
|
||||
DwlService.generateLayoutConfig();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ Singleton {
|
||||
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation))
|
||||
readonly property string mangoDmsDir: configDir + "/mango/dms"
|
||||
readonly property string outputsPath: mangoDmsDir + "/outputs.conf"
|
||||
readonly property string layoutPath: mangoDmsDir + "/layout.conf"
|
||||
|
||||
property int _lastGapValue: -1
|
||||
|
||||
property bool dwlAvailable: false
|
||||
property var outputs: ({})
|
||||
@@ -29,6 +32,27 @@ Singleton {
|
||||
|
||||
signal stateChanged
|
||||
|
||||
Connections {
|
||||
target: SettingsData
|
||||
function onBarConfigsChanged() {
|
||||
if (!CompositorService.isDwl)
|
||||
return;
|
||||
const newGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
if (newGaps === root._lastGapValue)
|
||||
return;
|
||||
root._lastGapValue = newGaps;
|
||||
generateLayoutConfig();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CompositorService
|
||||
function onIsDwlChanged() {
|
||||
if (CompositorService.isDwl)
|
||||
generateLayoutConfig();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: DMSService
|
||||
function onCapabilitiesReceived() {
|
||||
@@ -49,12 +73,12 @@ Singleton {
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (DMSService.dmsAvailable) {
|
||||
if (DMSService.dmsAvailable)
|
||||
checkCapabilities();
|
||||
}
|
||||
if (dwlAvailable) {
|
||||
if (dwlAvailable)
|
||||
refreshOutputScales();
|
||||
}
|
||||
if (CompositorService.isDwl)
|
||||
Qt.callLater(generateLayoutConfig);
|
||||
}
|
||||
|
||||
function checkCapabilities() {
|
||||
@@ -323,6 +347,37 @@ Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
function generateLayoutConfig() {
|
||||
if (!CompositorService.isDwl)
|
||||
return;
|
||||
|
||||
const defaultRadius = typeof SettingsData !== "undefined" ? SettingsData.cornerRadius : 12;
|
||||
const defaultGaps = typeof SettingsData !== "undefined" ? Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4)) : 4;
|
||||
const defaultBorderSize = 2;
|
||||
|
||||
const cornerRadius = (typeof SettingsData !== "undefined" && SettingsData.mangoLayoutRadiusOverride >= 0) ? SettingsData.mangoLayoutRadiusOverride : defaultRadius;
|
||||
const gaps = (typeof SettingsData !== "undefined" && SettingsData.mangoLayoutGapsOverride >= 0) ? SettingsData.mangoLayoutGapsOverride : defaultGaps;
|
||||
const borderSize = (typeof SettingsData !== "undefined" && SettingsData.mangoLayoutBorderSize >= 0) ? SettingsData.mangoLayoutBorderSize : defaultBorderSize;
|
||||
|
||||
let content = `# Auto-generated by DMS - do not edit manually
|
||||
border_radius=${cornerRadius}
|
||||
gappih=${gaps}
|
||||
gappiv=${gaps}
|
||||
gappoh=${gaps}
|
||||
gappov=${gaps}
|
||||
borderpx=${borderSize}
|
||||
`;
|
||||
|
||||
Proc.runCommand("mango-write-layout", ["sh", "-c", `mkdir -p "${mangoDmsDir}" && cat > "${layoutPath}" << 'EOF'\n${content}EOF`], (output, exitCode) => {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("DwlService: Failed to write layout config:", output);
|
||||
return;
|
||||
}
|
||||
console.info("DwlService: Generated layout config at", layoutPath);
|
||||
reloadConfig();
|
||||
});
|
||||
}
|
||||
|
||||
function transformToMango(transform) {
|
||||
switch (transform) {
|
||||
case "Normal":
|
||||
|
||||
@@ -12,6 +12,35 @@ Singleton {
|
||||
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation))
|
||||
readonly property string hyprDmsDir: configDir + "/hypr/dms"
|
||||
readonly property string outputsPath: hyprDmsDir + "/outputs.conf"
|
||||
readonly property string layoutPath: hyprDmsDir + "/layout.conf"
|
||||
|
||||
property int _lastGapValue: -1
|
||||
|
||||
Component.onCompleted: {
|
||||
if (CompositorService.isHyprland)
|
||||
Qt.callLater(generateLayoutConfig);
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: SettingsData
|
||||
function onBarConfigsChanged() {
|
||||
if (!CompositorService.isHyprland)
|
||||
return;
|
||||
const newGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
|
||||
if (newGaps === root._lastGapValue)
|
||||
return;
|
||||
root._lastGapValue = newGaps;
|
||||
generateLayoutConfig();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: CompositorService
|
||||
function onIsHyprlandChanged() {
|
||||
if (CompositorService.isHyprland)
|
||||
generateLayoutConfig();
|
||||
}
|
||||
}
|
||||
|
||||
function getOutputIdentifier(output, outputName) {
|
||||
if (SettingsData.displayNameMode === "model" && output.make && output.model)
|
||||
@@ -132,6 +161,41 @@ Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
function generateLayoutConfig() {
|
||||
if (!CompositorService.isHyprland)
|
||||
return;
|
||||
|
||||
const defaultRadius = typeof SettingsData !== "undefined" ? SettingsData.cornerRadius : 12;
|
||||
const defaultGaps = typeof SettingsData !== "undefined" ? Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4)) : 4;
|
||||
const defaultBorderSize = 2;
|
||||
|
||||
const cornerRadius = (typeof SettingsData !== "undefined" && SettingsData.hyprlandLayoutRadiusOverride >= 0) ? SettingsData.hyprlandLayoutRadiusOverride : defaultRadius;
|
||||
const gaps = (typeof SettingsData !== "undefined" && SettingsData.hyprlandLayoutGapsOverride >= 0) ? SettingsData.hyprlandLayoutGapsOverride : defaultGaps;
|
||||
const borderSize = (typeof SettingsData !== "undefined" && SettingsData.hyprlandLayoutBorderSize >= 0) ? SettingsData.hyprlandLayoutBorderSize : defaultBorderSize;
|
||||
|
||||
let content = `# Auto-generated by DMS - do not edit manually
|
||||
|
||||
general {
|
||||
gaps_in = ${gaps}
|
||||
gaps_out = ${gaps}
|
||||
border_size = ${borderSize}
|
||||
}
|
||||
|
||||
decoration {
|
||||
rounding = ${cornerRadius}
|
||||
}
|
||||
`;
|
||||
|
||||
Proc.runCommand("hypr-write-layout", ["sh", "-c", `mkdir -p "${hyprDmsDir}" && cat > "${layoutPath}" << 'EOF'\n${content}EOF`], (output, exitCode) => {
|
||||
if (exitCode !== 0) {
|
||||
console.warn("HyprlandService: Failed to write layout config:", output);
|
||||
return;
|
||||
}
|
||||
console.info("HyprlandService: Generated layout config at", layoutPath);
|
||||
reloadConfig();
|
||||
});
|
||||
}
|
||||
|
||||
function transformToHyprland(transform) {
|
||||
switch (transform) {
|
||||
case "Normal":
|
||||
|
||||
@@ -1012,9 +1012,11 @@ Singleton {
|
||||
|
||||
const defaultRadius = typeof SettingsData !== "undefined" ? SettingsData.cornerRadius : 12;
|
||||
const defaultGaps = typeof SettingsData !== "undefined" ? Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4)) : 4;
|
||||
const defaultBorderSize = 2;
|
||||
|
||||
const cornerRadius = (typeof SettingsData !== "undefined" && SettingsData.niriLayoutRadiusOverride >= 0) ? SettingsData.niriLayoutRadiusOverride : defaultRadius;
|
||||
const gaps = (typeof SettingsData !== "undefined" && SettingsData.niriLayoutGapsOverride >= 0) ? SettingsData.niriLayoutGapsOverride : defaultGaps;
|
||||
const borderSize = (typeof SettingsData !== "undefined" && SettingsData.niriLayoutBorderSize >= 0) ? SettingsData.niriLayoutBorderSize : defaultBorderSize;
|
||||
|
||||
const dmsWarning = `// ! DO NOT EDIT !
|
||||
// ! AUTO-GENERATED BY DMS !
|
||||
@@ -1027,11 +1029,11 @@ Singleton {
|
||||
gaps ${gaps}
|
||||
|
||||
border {
|
||||
width 2
|
||||
width ${borderSize}
|
||||
}
|
||||
|
||||
focus-ring {
|
||||
width 2
|
||||
width ${borderSize}
|
||||
}
|
||||
}
|
||||
window-rule {
|
||||
|
||||
@@ -12,7 +12,7 @@ ScrollBar {
|
||||
|
||||
policy: (parent && parent.contentHeight > parent.height) ? ScrollBar.AsNeeded : ScrollBar.AlwaysOff
|
||||
minimumSize: 0.08
|
||||
implicitWidth: 8
|
||||
implicitWidth: 10
|
||||
interactive: true
|
||||
hoverEnabled: true
|
||||
z: 1000
|
||||
|
||||
@@ -14,6 +14,7 @@ Item {
|
||||
property bool toggling: false
|
||||
property string text: ""
|
||||
property string description: ""
|
||||
property color descriptionColor: Theme.surfaceVariantText
|
||||
property bool hideText: false
|
||||
|
||||
signal clicked
|
||||
@@ -79,7 +80,7 @@ Item {
|
||||
StyledText {
|
||||
text: toggle.description
|
||||
font.pixelSize: Appearance.fontSize.small
|
||||
color: Theme.surfaceVariantText
|
||||
color: toggle.descriptionColor
|
||||
wrapMode: Text.WordWrap
|
||||
width: Math.min(implicitWidth, toggle.width - 120)
|
||||
visible: toggle.description.length > 0
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsalacritty]
|
||||
input_path = 'SHELL_DIR/matugen/templates/alacritty.toml'
|
||||
output_path = '~/.config/alacritty/dank-theme.toml'
|
||||
output_path = 'CONFIG_DIR/alacritty/dank-theme.toml'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsdgop]
|
||||
input_path = 'SHELL_DIR/matugen/templates/dgop.json'
|
||||
output_path = '~/.config/dgop/colors.json'
|
||||
output_path = 'CONFIG_DIR/dgop/colors.json'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsequibop]
|
||||
input_path = 'SHELL_DIR/matugen/templates/vesktop.css'
|
||||
output_path = '~/.config/equibop/themes/dank-discord.css'
|
||||
output_path = 'CONFIG_DIR/equibop/themes/dank-discord.css'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsfirefox]
|
||||
input_path = 'SHELL_DIR/matugen/templates/firefox-userchrome.css'
|
||||
output_path = '~/.config/DankMaterialShell/firefox.css'
|
||||
output_path = 'CONFIG_DIR/DankMaterialShell/firefox.css'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsfoot]
|
||||
input_path = 'SHELL_DIR/matugen/templates/foot.ini'
|
||||
output_path = '~/.config/foot/dank-colors.ini'
|
||||
output_path = 'CONFIG_DIR/foot/dank-colors.ini'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsghostty]
|
||||
input_path = 'SHELL_DIR/matugen/templates/ghostty.conf'
|
||||
output_path = '~/.config/ghostty/themes/dankcolors'
|
||||
output_path = 'CONFIG_DIR/ghostty/themes/dankcolors'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[templates.dmsgtk3]
|
||||
input_path = 'SHELL_DIR/matugen/templates/gtk-colors.css'
|
||||
output_path = '~/.config/gtk-3.0/dank-colors.css'
|
||||
output_path = 'CONFIG_DIR/gtk-3.0/dank-colors.css'
|
||||
|
||||
[templates.dmsgtk4]
|
||||
input_path = 'SHELL_DIR/matugen/templates/gtk-colors.css'
|
||||
output_path = '~/.config/gtk-4.0/dank-colors.css'
|
||||
output_path = 'CONFIG_DIR/gtk-4.0/dank-colors.css'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[templates.dmsgtk3]
|
||||
input_path = 'SHELL_DIR/matugen/templates/gtk-light-colors.css'
|
||||
output_path = '~/.config/gtk-3.0/dank-colors.css'
|
||||
output_path = 'CONFIG_DIR/gtk-3.0/dank-colors.css'
|
||||
|
||||
[templates.dmsgtk4]
|
||||
input_path = 'SHELL_DIR/matugen/templates/gtk-colors.css'
|
||||
output_path = '~/.config/gtk-4.0/dank-colors.css'
|
||||
output_path = 'CONFIG_DIR/gtk-4.0/dank-colors.css'
|
||||
|
||||
3
quickshell/matugen/configs/hyprland.toml
Normal file
3
quickshell/matugen/configs/hyprland.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
[templates.dmshyprland]
|
||||
input_path = 'SHELL_DIR/matugen/templates/hypr-colors.conf'
|
||||
output_path = 'CONFIG_DIR/hypr/dms/colors.conf'
|
||||
@@ -1,11 +1,11 @@
|
||||
[templates.dmskcolorscheme]
|
||||
input_path = 'SHELL_DIR/matugen/templates/kcolorscheme.colors'
|
||||
output_path = '~/.local/share/color-schemes/DankMatugen.colors'
|
||||
output_path = 'DATA_DIR/color-schemes/DankMatugen.colors'
|
||||
|
||||
[templates.dmslightkcolorscheme]
|
||||
input_path = 'SHELL_DIR/matugen/templates/light-kcolorscheme.colors'
|
||||
output_path = '~/.local/share/color-schemes/DankMatugenLight.colors'
|
||||
output_path = 'DATA_DIR/color-schemes/DankMatugenLight.colors'
|
||||
|
||||
[templates.dmsdarkkcolorscheme]
|
||||
input_path = 'SHELL_DIR/matugen/templates/dark-kcolorscheme.colors'
|
||||
output_path = '~/.local/share/color-schemes/DankMatugenDark.colors'
|
||||
output_path = 'DATA_DIR/color-schemes/DankMatugenDark.colors'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[templates.dmskitty]
|
||||
input_path = 'SHELL_DIR/matugen/templates/kitty.conf'
|
||||
output_path = '~/.config/kitty/dank-theme.conf'
|
||||
output_path = 'CONFIG_DIR/kitty/dank-theme.conf'
|
||||
|
||||
[templates.dmskittytabs]
|
||||
input_path = 'SHELL_DIR/matugen/templates/kitty-tabs.conf'
|
||||
output_path = '~/.config/kitty/dank-tabs.conf'
|
||||
output_path = 'CONFIG_DIR/kitty/dank-tabs.conf'
|
||||
|
||||
3
quickshell/matugen/configs/mangowc.toml
Normal file
3
quickshell/matugen/configs/mangowc.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
[templates.dmsmango]
|
||||
input_path = 'SHELL_DIR/matugen/templates/mango-colors.conf'
|
||||
output_path = 'CONFIG_DIR/mango/dms/colors.conf'
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsneovim]
|
||||
input_path = 'SHELL_DIR/matugen/templates/neovim.lua'
|
||||
output_path = '~/.config/nvim/lua/plugins/dankcolors.lua'
|
||||
output_path = 'CONFIG_DIR/nvim/lua/plugins/dankcolors.lua'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsniri]
|
||||
input_path = 'SHELL_DIR/matugen/templates/niri-colors.kdl'
|
||||
output_path = '~/.config/niri/dms/colors.kdl'
|
||||
output_path = 'CONFIG_DIR/niri/dms/colors.kdl'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[templates.dmspywalfox]
|
||||
input_path = 'SHELL_DIR/matugen/templates/pywalfox-colors.json'
|
||||
output_path = '~/.cache/wal/dank-pywalfox.json'
|
||||
output_path = 'CACHE_DIR/wal/dank-pywalfox.json'
|
||||
post_hook = 'sh -c "command -v pywalfox && test -f ~/.cache/wal/colors.json && pywalfox update"'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsqt5ct]
|
||||
input_path = 'SHELL_DIR/matugen/templates/qtct-colors.conf'
|
||||
output_path = '~/.config/qt5ct/colors/matugen.conf'
|
||||
output_path = 'CONFIG_DIR/qt5ct/colors/matugen.conf'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsqt6ct]
|
||||
input_path = 'SHELL_DIR/matugen/templates/qtct-colors.conf'
|
||||
output_path = '~/.config/qt6ct/colors/matugen.conf'
|
||||
output_path = 'CONFIG_DIR/qt6ct/colors/matugen.conf'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmsvesktop]
|
||||
input_path = 'SHELL_DIR/matugen/templates/vesktop.css'
|
||||
output_path = '~/.config/vesktop/themes/dank-discord.css'
|
||||
output_path = 'CONFIG_DIR/vesktop/themes/dank-discord.css'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmswezterm]
|
||||
input_path = 'SHELL_DIR/matugen/templates/wezterm.toml'
|
||||
output_path = '~/.config/wezterm/colors/dank-theme.toml'
|
||||
output_path = 'CONFIG_DIR/wezterm/colors/dank-theme.toml'
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[templates.dmszenbrowser]
|
||||
input_path = 'SHELL_DIR/matugen/templates/zen-userchrome.css'
|
||||
output_path = '~/.config/DankMaterialShell/zen.css'
|
||||
output_path = 'CONFIG_DIR/DankMaterialShell/zen.css'
|
||||
|
||||
25
quickshell/matugen/templates/hypr-colors.conf
Normal file
25
quickshell/matugen/templates/hypr-colors.conf
Normal file
@@ -0,0 +1,25 @@
|
||||
# ! Auto-generated file. Do not edit directly.
|
||||
# Remove source = ./dms/colors.conf from your config to override.
|
||||
|
||||
$primary = rgb({{colors.primary.default.hex_stripped}})
|
||||
$outline = rgb({{colors.outline.default.hex_stripped}})
|
||||
$error = rgb({{colors.error.default.hex_stripped}})
|
||||
|
||||
general {
|
||||
col.active_border = $primary
|
||||
col.inactive_border = $outline
|
||||
}
|
||||
|
||||
group {
|
||||
col.border_active = $primary
|
||||
col.border_inactive = $outline
|
||||
col.border_locked_active = $error
|
||||
col.border_locked_inactive = $outline
|
||||
|
||||
groupbar {
|
||||
col.active = $primary
|
||||
col.inactive = $outline
|
||||
col.locked_active = $error
|
||||
col.locked_inactive = $outline
|
||||
}
|
||||
}
|
||||
6
quickshell/matugen/templates/mango-colors.conf
Normal file
6
quickshell/matugen/templates/mango-colors.conf
Normal file
@@ -0,0 +1,6 @@
|
||||
# ! Auto-generated file. Do not edit directly.
|
||||
# Remove source = ./dms/colors.conf from your config to override.
|
||||
|
||||
bordercolor = 0x{{colors.outline.default.hex_stripped}}ff
|
||||
focuscolor = 0x{{colors.primary.default.hex_stripped}}ff
|
||||
urgentcolor = 0x{{colors.error.default.hex_stripped}}ff
|
||||
@@ -1,3 +1,6 @@
|
||||
// ! Auto-generated file. Do not edit directly.
|
||||
// Remove `include "dms/colors.kdl"` from your config to override.
|
||||
|
||||
layout {
|
||||
background-color "transparent"
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
//@ pragma Env QT_FFMPEG_DECODING_HW_DEVICE_TYPES=vaapi
|
||||
//@ pragma Env QT_FFMPEG_ENCODING_HW_DEVICE_TYPES=vaapi
|
||||
//@ pragma Env QT_WAYLAND_DISABLE_WINDOWDECORATION=1
|
||||
//@ pragma Env QT_QUICK_CONTROLS_STYLE=Material
|
||||
//@ pragma UseQApplication
|
||||
|
||||
import QtQuick
|
||||
|
||||
Reference in New Issue
Block a user