Add DMS configuration enhancements and new default settings

- Introduced a new private default settings file for Dank Material Shell (DMS) to manage user-specific settings.
- Updated DMS home-manager module to generate a settings seed file, merging extra right-bar widgets into the first-run configuration.
- Added support for dynamic inclusion of DMS window rules based on user configuration.
- Enhanced the Niri configuration with a preference for no client-side decorations and improved keybindings for bar toggling.
This commit is contained in:
2026-06-20 21:20:00 -03:00
parent 1a34db6f22
commit 17337b9675
7 changed files with 205 additions and 509 deletions
@@ -15,7 +15,11 @@
matugenOutputDirs =
lib.optionals hyprlandEnabled [ "${home}/.config/hypr" ]
++ lib.optionals ohMyPoshEnabled [ "${home}/.config/oh-my-posh" ]
++ lib.optionals discordEnabled [ "${home}/.config/vesktop/themes" ];
++ lib.optionals discordEnabled [ "${home}/.config/vesktop/themes" ]
++ [
"${home}/.config/qt6ct/colors"
"${home}/.config/qt5ct/colors"
];
ensureMatugenOutputDirsScript = pkgs.writeShellScript "dms-ensure-matugen-output-dirs" ''
set -euo pipefail
${lib.concatStringsSep "\n" (map (dir: "mkdir -p ${lib.escapeShellArg dir}") matugenOutputDirs)}
@@ -54,6 +58,14 @@
${pkgs.systemd}/bin/systemctl --user try-restart dms.service 2>/dev/null || true
'';
jsonFormat = pkgs.formats.json { };
dmsSeedSettings = import ../_private/default-settings.nix {
inherit lib gpuTempEnabled;
extraRightBarWidgets = cfg.extraRightBarWidgets;
};
dmsSeedFile = jsonFormat.generate "dms-settings-seed.json" dmsSeedSettings;
dmsSettingsPath = "${config.xdg.configHome}/DankMaterialShell/settings.json";
in {
options = {
dms.enable = lib.mkOption {
@@ -104,7 +116,7 @@ in {
{ id = "wvkbdToggle"; enabled = true; }
{ id = "rbwLockToggle"; enabled = true; }
];
description = "Extra `{ id, enabled, }` widgets, merged before defaults.";
description = "Extra `{ id, enabled, }` widgets merged into the first-run settings seed.";
};
dms.enableWvkbdToggle = lib.mkEnableOption ''
@@ -167,6 +179,11 @@ in {
programs.dank-material-shell = {
enable = true;
# homeAssistantMonitor plugin (QtWebSockets) needs QML on DMS's import path, not just home.packages.
package = inputs.dms.packages.${pkgs.stdenv.hostPlatform.system}.dms-shell.override {
extraQtPackages = with pkgs.kdePackages; [ qtwebsockets ];
};
systemd = {
enable = true; # Systemd service for auto-start
restartIfChanged = true; # Auto-restart dms.service when dankMaterialShell changes
@@ -181,391 +198,29 @@ in {
enableCalendarEvents = false; # Disable calendar integration (khal/ikhal)
# Leave `session` at {} — non-empty makes HM rewrite session.json every switch and nukes wallpaper/session state.
settings = {
theme = "dark";
dynamicTheming = true;
currentThemeName = "dynamic";
customThemeFile = "";
matugenScheme = "scheme-tonal-spot";
runUserMatugenTemplates = true;
# Stock DMS vesktop matugen output conflicts with our `templates/dank-discord.css` + config.toml entry.
matugenTemplateVesktop = false;
matugenTargetMonitor = "";
popupTransparency = 1;
dockTransparency = 0.85;
widgetBackgroundColor = "sch";
widgetColorMode = "default";
cornerRadius = 10;
use24HourClock = false;
showSeconds = true;
useFahrenheit = false;
nightModeEnabled = false;
animationSpeed = 1;
customAnimationDuration = 500;
wallpaperFillMode = "Fill";
blurredWallpaperLayer = false;
blurWallpaperOnOverview = false;
showLauncherButton = true;
showWorkspaceSwitcher = true;
showFocusedWindow = true;
showWeather = true;
showMusic = true;
showClipboard = true;
showCpuUsage = true;
showMemUsage = true;
showCpuTemp = true;
showGpuTemp = gpuTempEnabled;
showSystemTray = true;
}
// lib.optionalAttrs gpuTempEnabled {
selectedGpuIndex = 0;
enabledGpuPciIds = [];
}
// {
showClock = true;
showNotificationButton = true;
showBattery = true;
showControlCenterButton = true;
showCapsLockIndicator = true;
controlCenterShowNetworkIcon = true;
controlCenterShowBluetoothIcon = true;
controlCenterShowAudioIcon = true;
controlCenterShowVpnIcon = true;
controlCenterShowBrightnessIcon = false;
controlCenterShowMicIcon = false;
controlCenterShowBatteryIcon = false;
controlCenterShowPrinterIcon = false;
showPrivacyButton = true;
privacyShowMicIcon = false;
privacyShowCameraIcon = false;
privacyShowScreenShareIcon = false;
controlCenterWidgets = [
{
id = "volumeSlider";
enabled = true;
width = 50;
}
{
id = "brightnessSlider";
enabled = true;
width = 50;
}
{
id = "wifi";
enabled = true;
width = 50;
}
{
id = "bluetooth";
enabled = true;
width = 50;
}
{
id = "audioOutput";
enabled = true;
width = 50;
}
{
id = "audioInput";
enabled = true;
width = 50;
}
{
id = "nightMode";
enabled = true;
width = 50;
}
{
id = "darkMode";
enabled = true;
width = 50;
}
];
showWorkspaceIndex = true;
showWorkspacePadding = false;
workspaceScrolling = false;
showWorkspaceApps = true;
maxWorkspaceIcons = 10;
workspaceAppIconSizeOffset = 1;
workspacesPerMonitor = true;
showOccupiedWorkspacesOnly = false;
dwlShowAllTags = false;
workspaceNameIcons = {};
waveProgressEnabled = true;
scrollTitleEnabled = true;
clockCompactMode = false;
focusedWindowCompactMode = false;
runningAppsCompactMode = true;
keyboardLayoutNameCompactMode = false;
runningAppsCurrentWorkspace = false;
runningAppsGroupByApp = true;
centeringMode = "geometric";
clockDateFormat = "yyyy-MM-dd";
lockDateFormat = "";
mediaSize = 1;
appLauncherViewMode = "list";
spotlightModalViewMode = "list";
sortAppsAlphabetically = false;
appLauncherGridColumns = 4;
spotlightCloseNiriOverview = true;
niriOverviewOverlayEnabled = true;
useAutoLocation = true;
weatherEnabled = true;
networkPreference = "auto";
vpnLastConnected = "";
iconTheme = "System Default";
launcherLogoMode = "os";
launcherLogoCustomPath = "";
launcherLogoColorOverride = "";
launcherLogoColorInvertOnMode = false;
launcherLogoBrightness = 0.5;
launcherLogoContrast = 1;
launcherLogoSizeOffset = 0;
fontFamily = "Inter Variable";
monoFontFamily = "Fira Code";
fontWeight = 400;
fontScale = 1;
notepadUseMonospace = true;
notepadFontFamily = "";
notepadFontSize = 14;
notepadShowLineNumbers = false;
notepadTransparencyOverride = -1;
notepadLastCustomTransparency = 0.7;
soundsEnabled = true;
useSystemSoundTheme = false;
soundNewNotification = true;
soundVolumeChanged = true;
soundPluggedIn = true;
acMonitorTimeout = 0;
acLockTimeout = 0;
acSuspendTimeout = 0;
acSuspendBehavior = 0;
acProfileName = "";
batteryMonitorTimeout = 0;
batteryLockTimeout = 0;
batterySuspendTimeout = 0;
batterySuspendBehavior = 0;
batteryProfileName = "";
lockBeforeSuspend = false;
loginctlLockIntegration = true;
fadeToLockEnabled = false;
fadeToLockGracePeriod = 5;
launchPrefix = "";
brightnessDevicePins = {};
wifiNetworkPins = {};
bluetoothDevicePins = {};
audioInputDevicePins = {};
audioOutputDevicePins = {};
gtkThemingEnabled = false;
qtThemingEnabled = false;
syncModeWithPortal = true;
terminalsAlwaysDark = true;
showDock = false;
dockAutoHide = true;
dockGroupByApp = true;
dockOpenOnOverview = false;
dockPosition = 1;
dockSpacing = 3;
dockBottomGap = -16;
dockMargin = 2;
dockIconSize = 45;
dockIndicatorStyle = "circle";
dockBorderEnabled = true;
dockBorderColor = "primary";
dockBorderOpacity = 0.2;
dockBorderThickness = 2;
notificationOverlayEnabled = false;
modalDarkenBackground = true;
lockScreenShowPowerActions = true;
enableFprint = false;
maxFprintTries = 15;
lockScreenActiveMonitor = "all";
lockScreenInactiveColor = "#000000";
hideBrightnessSlider = false;
notificationTimeoutLow = 5000;
notificationTimeoutNormal = 5000;
notificationTimeoutCritical = 0;
notificationPopupPosition = 0;
osdAlwaysShowValue = false;
osdPosition = 5;
osdVolumeEnabled = true;
osdMediaVolumeEnabled = true;
osdBrightnessEnabled = true;
osdIdleInhibitorEnabled = true;
osdMicMuteEnabled = true;
osdCapsLockEnabled = true;
osdPowerProfileEnabled = false;
osdAudioOutputEnabled = true;
powerActionConfirm = true;
powerActionHoldDuration = 0.5;
powerMenuActions = ["reboot" "logout" "poweroff" "lock" "suspend" "restart"];
powerMenuDefaultAction = "logout";
powerMenuGridLayout = false;
customPowerActionLock = "";
customPowerActionLogout = "";
customPowerActionSuspend = "";
customPowerActionHibernate = "";
customPowerActionReboot = "";
customPowerActionPowerOff = "";
updaterUseCustomCommand = false;
updaterCustomCommand = "";
updaterTerminalAdditionalParams = "";
displayNameMode = "model";
showOnLastDisplay = {
dock = true;
};
barConfigs = [
{
id = "default";
name = "Main Bar";
enabled = true;
position = 0;
screenPreferences = ["all"];
showOnLastDisplay = true;
leftWidgets = [
{
id = "launcherButton";
enabled = true;
}
{
id = "nixMonitor";
enabled = true;
}
{
id = "cpuUsage";
enabled = true;
}
{
id = "cpuTemp";
enabled = true;
}
]
++ lib.optionals gpuTempEnabled [
{
id = "gpuTemp";
enabled = true;
selectedGpuIndex = 0;
pciId = "10de:1f07";
}
]
++ [
{
id = "memUsage";
enabled = true;
}
{
id = "music";
enabled = false;
}
{
id = "focusedWindow";
enabled = false;
}
];
centerWidgets = [
{
id = "privacyIndicator";
enabled = false;
}
{
id = "workspaceSwitcher";
enabled = true;
}
{
id = "privacyIndicator";
enabled = true;
}
];
rightWidgets = cfg.extraRightBarWidgets
++ [
{
id = "systemTray";
enabled = true;
}
{
id = "notificationButton";
enabled = true;
}
{
id = "battery";
enabled = true;
}
{
id = "controlCenterButton";
enabled = true;
}
{
id = "clock";
enabled = true;
clockCompactMode = false;
}
];
spacing = 0;
innerPadding = 4;
bottomGap = -4;
transparency = 0;
widgetTransparency = 0.45;
squareCorners = true;
noBackground = false;
gothCornersEnabled = true;
gothCornerRadiusOverride = false;
gothCornerRadiusValue = 12;
borderEnabled = false;
borderColor = "primary";
borderOpacity = 1;
borderThickness = 1;
widgetOutlineEnabled = true;
widgetOutlineColor = "secondary";
widgetOutlineOpacity = 0.25;
widgetOutlineThickness = 2;
fontScale = 1;
autoHide = false;
autoHideDelay = 250;
openOnOverview = false;
visible = true;
popupGapsAuto = true;
popupGapsManual = 22;
maximizeDetection = true;
}
];
configVersion = 2;
};
# Leave `settings` at {} — UI-owned settings.json is seeded once on first run (see home.activation below).
settings = { };
session = { };
};
# Detach store symlink so UI edits survive rebuilds; seed defaults only on a fresh profile.
home.activation.dmsMaterializeSettings = lib.hm.dag.entryBefore [ "writeBoundary" ] ''
settingsFile=${lib.escapeShellArg dmsSettingsPath}
if [ -L "$settingsFile" ]; then
mkdir -p "$(dirname "$settingsFile")"
${pkgs.coreutils}/bin/cp --remove-destination -L "$settingsFile" "$settingsFile"
fi
'';
home.activation.dmsSeedSettings = lib.hm.dag.entryAfter [ "writeBoundary" ] ''
settingsFile=${lib.escapeShellArg dmsSettingsPath}
mkdir -p "$(dirname "$settingsFile")"
if [ ! -e "$settingsFile" ]; then
${pkgs.coreutils}/bin/cp ${lib.escapeShellArg dmsSeedFile} "$settingsFile"
chmod u+w "$settingsFile"
fi
'';
# matugen won't create missing output_path parents; run before DMS theme generation.
systemd.user.services.dms.serviceConfig.ExecStartPre =
lib.mkOrder 100 "${ensureMatugenOutputDirsScript}";
@@ -582,12 +237,6 @@ in {
input_path = '${home}/.config/matugen/templates/hyprland-colors.conf'
output_path = '${home}/.config/hypr/colors.conf'
''
+ ''
[templates.kdeglobals]
input_path = '${home}/.config/matugen/templates/kdeglobals.conf'
output_path = '${home}/.config/kdeglobals'
''
+ lib.optionalString ohMyPoshEnabled ''
[templates.ohmyposh]
@@ -612,10 +261,6 @@ in {
)
;
home.activation.dmsEnsureMatugenOutputDirs = lib.hm.dag.entryAfter ["writeBoundary"] ''
${ensureMatugenOutputDirsScript}
'';
# Obsidian snippet dirs for matugen: mkdir here instead of tmpfiles (no chmod fights on weird mounts).
home.activation.dmsEnsureObsidianSnippetDirs = lib.hm.dag.entryAfter ["writeBoundary"] (
let
@@ -669,97 +314,6 @@ in {
}
'';
# matugen template → KDE globals file used by KDE/Qt apps (e.g. Dolphin).
# Uses DMS-provided matugen color variables; keep `.default` for mode-aware colors.
xdg.configFile."matugen/templates/kdeglobals.conf".text = ''
[General]
ColorScheme=DMSDynamic
TerminalApplication=kitty
TerminalService=kitty.desktop
# Keep Qt/KDE app icons on WhiteSur (this is what Dolphin reads via KDE config)
[Icons]
Theme=WhiteSur-dark
[Colors:Window]
BackgroundNormal=#{{colors.background.default.hex_stripped}}
BackgroundAlternate=#{{colors.surface.default.hex_stripped}}
DecorationFocus=#{{colors.primary.default.hex_stripped}}
DecorationHover=#{{colors.secondary.default.hex_stripped}}
ForegroundNormal=#{{colors.on_surface.default.hex_stripped}}
ForegroundInactive=#{{colors.on_surface_variant.default.hex_stripped}}
ForegroundActive=#{{colors.on_surface.default.hex_stripped}}
ForegroundLink=#{{colors.primary.default.hex_stripped}}
ForegroundVisited=#{{colors.tertiary.default.hex_stripped}}
ForegroundNegative=#{{colors.error.default.hex_stripped}}
ForegroundNeutral=#{{colors.secondary.default.hex_stripped}}
ForegroundPositive=#{{colors.primary.default.hex_stripped}}
[Colors:View]
BackgroundNormal=#{{colors.background.default.hex_stripped}}
BackgroundAlternate=#{{colors.surface.default.hex_stripped}}
DecorationFocus=#{{colors.primary.default.hex_stripped}}
DecorationHover=#{{colors.secondary.default.hex_stripped}}
ForegroundNormal=#{{colors.on_surface.default.hex_stripped}}
ForegroundInactive=#{{colors.on_surface_variant.default.hex_stripped}}
ForegroundActive=#{{colors.on_surface.default.hex_stripped}}
ForegroundLink=#{{colors.primary.default.hex_stripped}}
ForegroundVisited=#{{colors.tertiary.default.hex_stripped}}
ForegroundNegative=#{{colors.error.default.hex_stripped}}
ForegroundNeutral=#{{colors.secondary.default.hex_stripped}}
ForegroundPositive=#{{colors.primary.default.hex_stripped}}
[Colors:Button]
BackgroundNormal=#{{colors.surface.default.hex_stripped}}
BackgroundAlternate=#{{colors.surface_variant.default.hex_stripped}}
DecorationFocus=#{{colors.primary.default.hex_stripped}}
DecorationHover=#{{colors.secondary.default.hex_stripped}}
ForegroundNormal=#{{colors.on_surface.default.hex_stripped}}
ForegroundInactive=#{{colors.on_surface_variant.default.hex_stripped}}
ForegroundActive=#{{colors.on_surface.default.hex_stripped}}
ForegroundLink=#{{colors.primary.default.hex_stripped}}
ForegroundVisited=#{{colors.tertiary.default.hex_stripped}}
ForegroundNegative=#{{colors.error.default.hex_stripped}}
ForegroundNeutral=#{{colors.secondary.default.hex_stripped}}
ForegroundPositive=#{{colors.primary.default.hex_stripped}}
[Colors:Selection]
BackgroundNormal=#{{colors.primary.default.hex_stripped}}
BackgroundAlternate=#{{colors.primary_container.default.hex_stripped}}
DecorationFocus=#{{colors.primary.default.hex_stripped}}
DecorationHover=#{{colors.secondary.default.hex_stripped}}
ForegroundNormal=#{{colors.on_primary.default.hex_stripped}}
ForegroundInactive=#{{colors.on_primary.default.hex_stripped}}
ForegroundActive=#{{colors.on_primary.default.hex_stripped}}
ForegroundLink=#{{colors.on_primary.default.hex_stripped}}
ForegroundVisited=#{{colors.on_primary.default.hex_stripped}}
ForegroundNegative=#{{colors.on_primary.default.hex_stripped}}
ForegroundNeutral=#{{colors.on_primary.default.hex_stripped}}
ForegroundPositive=#{{colors.on_primary.default.hex_stripped}}
[Colors:Tooltip]
BackgroundNormal=#{{colors.surface_variant.default.hex_stripped}}
BackgroundAlternate=#{{colors.surface.default.hex_stripped}}
DecorationFocus=#{{colors.primary.default.hex_stripped}}
DecorationHover=#{{colors.secondary.default.hex_stripped}}
ForegroundNormal=#{{colors.on_surface.default.hex_stripped}}
ForegroundInactive=#{{colors.on_surface_variant.default.hex_stripped}}
ForegroundActive=#{{colors.on_surface.default.hex_stripped}}
ForegroundLink=#{{colors.primary.default.hex_stripped}}
ForegroundVisited=#{{colors.tertiary.default.hex_stripped}}
ForegroundNegative=#{{colors.error.default.hex_stripped}}
ForegroundNeutral=#{{colors.secondary.default.hex_stripped}}
ForegroundPositive=#{{colors.primary.default.hex_stripped}}
[WM]
activeBackground=#{{colors.background.default.hex_stripped}}
activeBlend=#{{colors.background.default.hex_stripped}}
activeForeground=#{{colors.on_surface.default.hex_stripped}}
inactiveBackground=#{{colors.background.default.hex_stripped}}
inactiveBlend=#{{colors.background.default.hex_stripped}}
inactiveForeground=#{{colors.on_surface_variant.default.hex_stripped}}
'';
# matugen → Oh My Posh JSON; hex in the base theme swapped for matugen tokens.
xdg.configFile."matugen/templates/ohmyposh-theme.omp.json".text = ''
{