1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-24 21:42:51 -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:
bbedward
2026-01-05 11:25:13 -05:00
parent 4005a55bf2
commit 64310854a6
49 changed files with 1017 additions and 207 deletions

View File

@@ -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)