KIDult2226 91f24693b8 fix(icc): keep the config a real snapshot and make the per-output temperature apply
Third review round.

- `Config` is copied by value all over the manager, but `ICCProfiles` and
  `OutputTemps` are maps, so every copy aliased the ones the manager writes under
  `configMutex`. `updateStateFromSchedule` stored such a copy in `m.state` and it
  was marshalled on the connection writer goroutine while `ApplyICC` stored a
  profile from the IPC goroutine (`fatal error: concurrent map iteration and map
  write`, which no `recover()` catches); `SaveConfig` marshalled its copy after
  the unlock, and `loadConfiguredICC`/`attachConfiguredICC` indexed the maps after
  releasing the lock. Every copy that outlives the lock is cloned now
  (`cloneConfig`/`configSnapshot`), so a value copy is a snapshot again.
- `SetOutputTemp` never created the gamma controls. On a default install (night
  light off, gamma 1.0, contrast 1.0, no profile, no override) they do not exist,
  so the `Range` over `m.outputs` matched nothing: the value was written to
  `wayland.json`, no ramp was applied, and the settings slider snapped back to
  "Default" until a daemon restart. It now persists first, creates the controls
  through `ensureOutputControls` (shared with `ApplyICC`), and pushes the state
  from the actor, and the published temperatures report the configured value even
  before an output is known.
- A TRC is not a video card gamma ramp: `rTRC`/`gTRC`/`bTRC` describe the
  display's own transfer function, so a gamma-2.2 profile was written as
  `t^(1/2.2)` — mid gray 0.5 became 47909/65535 — washing the display out instead
  of correcting it. `ApplyICC` refuses a profile without `vcgt`, the attach path
  skips one with a warning, and `GenerateGammaRamp` returns an error instead of
  falling back to the TRC or to an identity ramp. TRC stays profile metadata
  (`dms icc info`, the settings dialog).
- `icc: applied ICC ramp` was logged at Info on every 25 K animation step; it is
  Debug now, which is where a per-step message belongs.
- `I18n.tr("No information available")` in the profile info modal passes its
  translator context, like every other string this PR adds.

Covered by TestManager_ConfigSnapshotOwnsItsMaps,
TestManager_ConfigSnapshotConcurrentMarshal (the previous commit dies with
`fatal error: concurrent map iteration and map write`),
TestManager_SetOutputTempWithoutControlsPublishesValue (the previous commit
reports 0 for the value it just stored), TestGenerateGammaRampRequiresVCGT, and
the updated TestProfileRampWithTemp, whose fixture now carries an identity vcgt
table instead of relying on an empty profile.
2026-09-14 21:45:43 +08:00
2026-09-02 15:07:13 -04:00
2026-09-03 12:20:48 -04:00
2026-08-28 10:21:37 -04:00
2026-09-02 15:07:13 -04:00
2025-11-12 20:34:58 -05:00
2026-08-31 14:20:45 -04:00

DankMaterialShell

DankMaterialShell

A modern desktop shell for Wayland

Built with Quickshell and Go

Documentation GitHub stars GitHub License GitHub release Arch version AUR version (git) Ko-Fi donate

DankMaterialShell is a complete desktop shell for niri, Hyprland, MangoWC, Sway, labwc, Scroll, Miracle WM, and other Wayland compositors. It replaces waybar, swaylock, swayidle, mako, fuzzel, polkit, and everything else you'd normally stitch together to make a desktop.

Repository Structure

This is a monorepo containing both the shell interface and the core backend services:

DankMaterialShell/
├── quickshell/         # QML-based shell interface
│   ├── Modules/        # UI components (panels, widgets, overlays)
│   ├── Services/       # System integration (audio, network, bluetooth)
│   ├── Widgets/        # Reusable UI controls
│   └── Common/         # Shared resources and themes
├── core/               # Go backend and CLI
│   ├── cmd/            # dms CLI and dankinstall binaries
│   ├── internal/       # System integration, IPC, distro support
│   └── pkg/            # Shared packages
├── distro/             # Distribution packaging
│   ├── fedora/         # Fedora RPM specs
│   ├── debian/         # Debian packaging
│   └── nix/            # NixOS/home-manager modules
└── flake.nix           # Nix flake for declarative installation

See it in Action

More Screenshots
Desktop Dashboard Launcher Control Center

Installation

curl -fsSL https://install.danklinux.com | sh

One command installs DMS and all dependencies on Arch, Fedora, Debian, Ubuntu, openSUSE, or Gentoo.

Manual installation guide

Features

Dynamic Theming Wallpaper-based color schemes that automatically theme GTK, Qt, terminals, editors (vscode, vscodium), and more using matugen and dank16.

System Monitoring Real-time CPU, RAM, GPU metrics and temperatures built into the dms daemon (powered by dgop). Process list with search and management.

Powerful Launcher Spotlight-style search for applications, files (dsearch), emojis, running windows, calculator, and commands. Extensible with plugins.

Control Center Unified interface for network, Bluetooth, audio devices, display settings, and night mode.

Smart Notifications Notification center with grouping, rich text support, and keyboard navigation.

Media Integration MPRIS player controls, calendar sync, weather widgets, and clipboard history with image previews.

Session Management Lock screen, idle detection, auto-lock/suspend with separate AC/battery settings, and a settings front-end for dank-greeter.

Plugin System Extend functionality with the plugin registry. DMS keeps ~/.config/DankMaterialShell/plugins.lock.json synchronized with managed plugin installs and their exact Git commits, so the same plugins can be reproduced on another machine.

Supported Compositors

Works best with niri, Hyprland, Sway, MangoWC, labwc, Scroll, and Miracle WM with full workspace switching, overview integration, and monitor management. Other Wayland compositors work with reduced features.

Compositor configuration guide

Command Line Interface

Control the shell from the command line or keybinds:

dms run              # Start the shell
dms ipc call spotlight toggle
dms ipc call audio setvolume 50
dms ipc call wallpaper set /path/to/image.jpg
dms brightness list  # List available displays
dms plugins search   # Browse plugin registry
dms plugins lock     # Refresh the portable plugin lockfile
dms plugins restore ~/plugins.lock.json

Full CLI and IPC documentation

Documentation

Dank Projects

DMS is one piece of the suite. The rest lives in its own repos:

  • dank-greeter - greetd login screen with the Dank Material aesthetic. The Greeter tab in DMS settings is the front-end for it.
  • dankcalendar - Local, Google, Microsoft, and CalDAV calendars for the dank desktop.
  • dgop - System monitoring TUI and Go library; its library powers the process list and dashboard widgets inside the dms daemon.
  • dsearch - Fast file search that powers file results in the launcher.
  • dank-qml-common - Shared QML widgets and components used by DMS, dank-greeter, and dankcalendar.
  • dankgo - Common Go modules behind the single binary apps.

Development

See component-specific documentation:

  • quickshell/ - QML shell development, widgets, and modules
  • core/ - Go backend, CLI tools, and system integration
  • distro/ - Distribution packaging (Fedora, Debian, NixOS)

Building from Source

Core + Dankinstall:

cd core
make              # Build dms CLI
make dankinstall  # Build installer

Shell:

quickshell -p quickshell/

NixOS:

{
  inputs.dms.url = "github:AvengeMedia/DankMaterialShell";

  # Use in home-manager or NixOS configuration
  imports = [ inputs.dms.homeModules.dank-material-shell ];
}

Contributing

Contributions welcome. Bug fixes, widgets, features, documentation, and plugins all help.

  1. Fork the repository
  2. Make your changes
  3. Test thoroughly
  4. Open a pull request

For documentation contributions, see DankLinux-Docs.

Credits

Star History

Star History Chart

License

MIT License - See LICENSE for details.

Languages
QML 57.6%
Go 32.9%
JavaScript 6%
Shell 1.2%
Python 0.9%
Other 1.4%