* feat(theme): add a selectable source color mode for wallpaper palettes DMS always seeds the palette from matugen's most dominant candidate (--source-color-index 0, hardcoded at both call sites). When a large muted region outvotes a smaller vivid one, a visibly warm wallpaper produces a cold palette: one image here goes to #8ad0ee where the warm subject is at hue 46. Adds a Source Color setting with seven values. Dominant is the default and is byte-identical to today. Colorful is computed in Go before matugen runs: quantize the image (Wu for the starting clusters, then a weighted k-means in Lab), score the result the way caelestia-cli does, and hand matugen the resulting hex. Its scoring walks a chroma/tone bar down from 20 until something clears it, which biases the pick toward a colorful, well-lit color rather than whichever muted color covers the most pixels. The remaining five map to matugen's --prefer. - core/internal/matugen/sourcecolor.go: extraction, scoring, and the one helper both matugen call sites now share - buildOnce resolves the seed once, before the StockColors branch, so the dry run and the real run cannot disagree about it - extraction failure logs a warning and falls through to matugen's own extraction; it never fails a theme build - --prefer arrived in matugen 4.1, so it is gated separately from the existing isV4 check; on 4.0.x those five modes degrade to the dominant color instead of aborting on an unknown argument - --source-mode on generate and queue, plus sourceMode on the socket handler - Source Color dropdown in Theme & Colors, defaulting to Dominant Adds github.com/Nadim147c/material/v3 (Apache-2.0, no dependencies) for HCT conversions, Wu quantization and the dislike analyzer. Its QuantizeCelebi is not used: it returns after one unconverged iteration and its Lab.DistanceSquared is a dot product rather than a distance, so it collapses most of an image into a single cluster. * fix(theme): address review feedback on source color mode Two points from review on #3020. The quantize comment pointed at a FOLLOWUPS file that does not exist in this repository. Replaced the reference with the measurement it was standing in for, so the claim is self-contained. setMatugenSourceMode called Theme.generateSystemThemesFromCurrentTheme() directly on top of the regenSystemThemes onChange hook that Spec.set already dispatches. Both feed a 100ms debounce so it was one generation either way, but the direct call was redundant and is gone. * fix(theme): keep {{image}} resolvable in colorful mode Colorful resolves the seed itself and calls matugen with a hex source, which leaves matugen's {{image}} unset: the builtin pywalfox template and any user template using the keyword render the literal string "Null". Pass the wallpaper path alongside dank16 in --import-json-string, as suggested in review, so those templates keep working unedited. The path is made absolute to match what matugen renders for {{image}} in the other modes. * fix(theme): cut translator terms on the source color dropdown Per-mode descriptions were seven of the fifteen new terms this branch adds, and five of them differed by a single adjective. Drop them: the dropdown row already describes what the setting does, and the docs cover each mode.
DMS Backend & CLI
Go-based backend for DankMaterialShell providing system integration, IPC, and installation tools.
See root README for project overview and installation.
Components
dms CLI Command-line interface and daemon for shell management and system control.
dankinstall Distribution-aware installer for deploying DMS and compositor configurations on Arch, Fedora, Debian, Ubuntu, openSUSE, Gentoo, and Void. Supports both an interactive TUI and a headless (unattended) mode via CLI flags.
System Integration
Wayland Protocols (Client)
All Wayland protocols are consumed as a client - connecting to the compositor.
| Protocol | Purpose |
|---|---|
wlr-gamma-control-unstable-v1 |
Night mode color temperature control |
wlr-screencopy-unstable-v1 |
Screen capture for color picker/screenshot |
wlr-layer-shell-unstable-v1 |
Overlay surfaces for color picker UI/screenshot |
wlr-output-management-unstable-v1 |
Display configuration |
wlr-output-power-management-unstable-v1 |
DPMS on/off CLI |
wp-viewporter |
Fractional scaling support (color picker/screenshot UIs) |
keyboard-shortcuts-inhibit-unstable-v1 |
Inhibit compositor shortcuts during color picker/screenshot |
ext-data-control-v1 |
Clipboard history and persistence |
ext-workspace-v1 |
Workspace integration |
dwl-ipc-unstable-v2 |
dwl/MangoWC IPC for tags, outputs, etc. |
DBus Interfaces
Client (consuming external services):
| Interface | Purpose |
|---|---|
org.bluez |
Bluetooth management with pairing agent |
org.freedesktop.NetworkManager |
Network management |
net.connman.iwd |
iwd Wi-Fi backend |
org.freedesktop.network1 |
systemd-networkd integration |
org.freedesktop.login1 |
Session control, sleep inhibitors, brightness |
org.freedesktop.Accounts |
User account information |
org.freedesktop.portal.Desktop |
Desktop appearance settings (color scheme) |
| CUPS via IPP + D-Bus | Printer management with job notifications |
Server (implementing interfaces):
| Interface | Purpose |
|---|---|
org.freedesktop.ScreenSaver |
Screensaver inhibit for video playback |
Custom IPC via unix socket (JSON API) for shell communication.
Hardware Control
| Subsystem | Method | Purpose |
|---|---|---|
| DDC/CI | I2C direct | External monitor brightness |
| Backlight | logind or sysfs | Internal display brightness |
| evdev | /dev/input/event* |
Keyboard state (caps lock LED) |
| udev | netlink monitor | Backlight device updates (for OSD) |
Plugin System
- Plugin registry integration
- Plugin lifecycle management
- Settings persistence
CLI Commands
dms run [-d]- Start shell (optionally as daemon)dms restart/dms kill- Manage running processesdms ipc <command>- Send IPC commands (toggle launcher, notifications, etc.)dms plugins [install|browse|search|lock|restore]- Plugin management and portable exact-revision lockfilesdms brightness [list|set]- Control display/monitor brightnessdms color pick- Native color picker (see below)dms update- Update DMS and dependencies (disabled in distro packages)dms greeter- Deprecated; forwards to the standalone dms-greeter binary
Color Picker
Native Wayland color picker with magnifier, no external dependencies. Supports HiDPI and fractional scaling.
dms color pick # Pick color, output hex
dms color pick --rgb # Output as RGB (255 128 64)
dms color pick --hsv # Output as HSV (24 75% 100%)
dms color pick --json # Output all formats as JSON
dms color pick -a # Auto-copy to clipboard
The on-screen preview displays the selected format. JSON output includes hex, RGB, HSL, HSV, and CMYK values.
Building
Requires Go 1.25+
Development build:
make # Build dms CLI
make dankinstall # Build installer
make test # Run tests
Distribution build:
make dist # Build without update features
Produces bin/dms-linux-amd64 and bin/dms-linux-arm64
Installation:
sudo make install # Install to /usr/local/bin/dms
Development
Setup pre-commit hooks:
git config core.hooksPath .githooks
This runs gofmt, golangci-lint, tests, and builds before each commit when core/ files are staged.
Regenerating Wayland Protocol Bindings:
Protocol XML files live in internal/proto/xml/. Bindings are generated with the dankgo go-wayland-scanner:
go run github.com/AvengeMedia/dankgo/cmd/go-wayland-scanner@latest \
-i internal/proto/xml/wlr-gamma-control-unstable-v1.xml \
-pkg wlr_gamma_control -o internal/proto/wlr_gamma_control/gamma_control.go
Module Structure:
cmd/- Binary entrypoints (dms, dankinstall)internal/distros/- Distribution-specific installation logicinternal/proto/- Wayland protocol bindingspkg/- Shared packages
Installation via dankinstall
Interactive (TUI):
curl -fsSL https://install.danklinux.com | sh
Headless (unattended):
Headless mode requires cached credentials or a passwordless rule for your privilege escalation tool (sudo, doas, or run0). With sudo, run sudo -v first:
sudo -v && curl -fsSL https://install.danklinux.com | sh -s -- -c niri -t ghostty -y
sudo -v && curl -fsSL https://install.danklinux.com | sh -s -- -c hyprland -t kitty --dms-greeter -y
sudo -v && curl -fsSL https://install.danklinux.com | sh -s -- -c niri -t ghostty --git-deps niri,quickshell --all-features -y
| Flag | Short | Description |
|---|---|---|
--compositor <niri|hyprland|mango> |
-c |
Compositor/WM to install (required for headless) |
--term <ghostty|kitty|alacritty> |
-t |
Terminal emulator (required for headless) |
--privesc <sudo|doas|run0> |
Privilege escalation tool (default: autodetect) | |
--git |
Install the git version of every dependency that has one | |
--git-deps <name,...> |
Install the git version of specific dependencies (e.g. niri,quickshell) |
|
--all-features |
Enable all optional dependencies (dms-greeter, danksearch, dankcalendar) |
|
--dms-greeter |
Install dms-greeter | |
--danksearch |
Install danksearch and enable its user indexing service | |
--dankcalendar |
Install dankcalendar | |
--include-deps <name,...> |
Enable optional dependencies (e.g. dms-greeter) |
|
--exclude-deps <name,...> |
Skip specific dependencies | |
--replace-configs <name,...> |
Replace specific configuration files (mutually exclusive with --replace-configs-all) |
|
--replace-configs-all |
Replace all configuration files (mutually exclusive with --replace-configs) |
|
--yes |
-y |
Required for headless mode - confirms installation without interactive prompts |
Headless mode requires --yes to proceed; without it, the installer exits with an error.
Configuration files are not replaced by default unless --replace-configs or --replace-configs-all is specified.
Optional packages (dms-greeter, danksearch, dankcalendar) are disabled by default; enable them with their dedicated flags, --include-deps, or --all-features.
When no flags are provided, dankinstall launches the interactive TUI.
Headless mode validation rules
Headless mode activates when --compositor or --term is provided.
- Both
--compositorand--termare required; providing only one results in an error. - Headless-only flags (
--privesc,--git,--git-deps,--all-features,--include-deps,--exclude-deps,--replace-configs,--replace-configs-all,--yes,--danksearch,--dankcalendar,--dms-greeter) are rejected in TUI mode. - Positional arguments are not accepted.
Log file location
dankinstall writes logs to /tmp by default.
Set the DANKINSTALL_LOG_DIR environment variable to override the log directory.
Supported Distributions
Arch, Fedora, Debian, Ubuntu, openSUSE, Gentoo, Void (and derivatives)
Arch Linux
Uses pacman for system packages, builds AUR packages via makepkg, no AUR helper dependency.
Fedora
Uses COPR repositories (avengemedia/danklinux, avengemedia/dms).
Ubuntu Requires PPA support. Most packages built from source (slow first install).
Debian Debian 13+ (Trixie), testing, and sid. Stable quickshell from Debian (trixie-backports on 13). Other companions via OBS.
openSUSE Most packages available in standard repos. Minimal building required.
Gentoo Uses Portage with GURU overlay. Automatically configures USE flags. Variable success depending on system configuration.
Void Linux Uses XBPS with the DMS and DankLinux self-hosted repositories.
See installer output for distribution-specific details during installation.