# DankMaterialShell (niri) Profile — Design **Date:** 2026-07-24 **Branch:** `feat/dank-material-shell` **Status:** Approved (brainstorming) ## Summary Add a `my.profiles.dank` NixOS profile that provides a complete [DankMaterialShell](https://danklinux.com) (DMS) desktop running on the **niri** Wayland compositor, selectable at the SDDM login screen **alongside** the existing KDE session on **mibook** (user `finn`). DMS's keybind, spawn, and declarative-settings integration is delivered only through home-manager modules, so this work also introduces home-manager into the flake — as its own opt-in profile (`my.profiles.home-manager`) that the `dank` profile enables as a dependency. Everything stays declarative inside the flake; there is no separate home-manager entrypoint. ## Background / Research DMS is a Quickshell-based Wayland desktop **shell** (bar, launcher, control center, lock screen, notifications) — not a compositor. Its repository (`github:AvengeMedia/DankMaterialShell`) ships a flake with: - `nixosModules.dank-material-shell` — system side: installs the `dms-shell` package + `quickshell`, a `dms` systemd **user** service, `dgop` (system monitoring), matugen (dynamic theming), and enables polkit / power-profiles-daemon / accounts-daemon / geoclue2. Configured via `programs.dank-material-shell.*`. - `homeModules.dank-material-shell` — home side: declarative `~/.config/DankMaterialShell/settings.json`, the `dms` user service, plugin management, and the `programs.quickshell` HM program. - `homeModules.niri` — niri-specific integration: generates niri keybinds wired to `dms ipc` (launcher, clipboard, notifications, media/brightness keys, power menu, lock) and `spawn-at-startup` for `dms run`. `homeModules.niri` builds on **niri-flake**'s home-manager API (`programs.niri.settings`, `config.lib.niri.actions`); DMS does **not** bundle niri-flake, so it must be added as its own input. quickshell ≥ 0.3.0 is recommended and is available in nixos-unstable → use `pkgs.unstable.quickshell`. ### Key repo facts - This repo is flake-parts based, pins `nixpkgs/nixos-26.05`, and exposes `pkgs.unstable` via an overlay in `machines/configuration.nix`. - `inputs` and `self` are already threaded into every NixOS module via `_module.args` (set in `machines/configuration.nix`), so `modules/` files may take `inputs` / `self` as arguments and `imports = [ inputs.... ]`. - The repo currently uses **no home-manager**; compositor profiles (e.g. `hyprland`) install packages via `users.users.finn.packages`. - mibook currently runs the KDE desktop (`my.profiles.kde-desktop`). ## Scope - **In:** mibook only; niri+DMS as a session parallel to KDE; home-manager scoped to user `finn`; a reusable `my.profiles.home-manager` module. - **Out:** enabling on jupiter (headless server); Dank Greeter as the login manager (SDDM stays); declarative DMS `settings.json` content (DMS is configured through its own GUI at runtime; the HM `settings` option remains available for later use but is left empty); any change to `configuration.nix`. ## Design ### 1. New flake inputs (`flake.nix`) ```nix home-manager = { url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs"; }; niri.url = "github:sodiboo/niri-flake"; dank.url = "github:AvengeMedia/DankMaterialShell"; ``` Notes: - `dank` tracks nixos-unstable internally (its own `nixpkgs`), which is expected for the DMS package build. - `niri-flake` provides both the compositor session (nixosModule) and the HM `programs.niri.settings` API that DMS's niri module extends. - `home-manager` follows the repo `nixpkgs` (nixos-26.05). `machines/configuration.nix` is **not** modified — the existing `_module.args.inputs = self.inputs` line already makes these inputs reachable from any module. ### 2. Home-manager profile (`modules/environments/home-manager/default.nix`) A new opt-in `my.profiles.home-manager` profile. Because module `imports` cannot be gated on an option value, the home-manager NixOS module is imported unconditionally (harmless — it only adds options and does nothing until `home-manager.users.*` is populated); only the global settings are guarded by `mkIf cfg.enable`: ```nix { config, lib, inputs, self, ... }: let cfg = config.my.profiles.home-manager; in { imports = [ inputs.home-manager.nixosModules.home-manager ]; options.my.profiles.home-manager.enable = lib.mkEnableOption "home-manager integration"; config = lib.mkIf cfg.enable { home-manager.useGlobalPkgs = true; # HM shares the system pkgs (+ unstable overlay) home-manager.useUserPackages = true; home-manager.extraSpecialArgs = { inherit inputs self; }; }; } ``` Registered by adding `./environments/home-manager` to `modules/environments/default.nix`. > Placement note: the profile lives under `modules/environments/` (where > `my.profiles.*` modules live) to match the namespace, even though its function > is infrastructural. ### 3. Dank profile (`modules/environments/dank/default.nix`) Standard profile pattern; enables the home-manager profile as a dependency and splits configuration between the system module (session + daemons) and the home-manager module (keybinds / spawn / settings): ```nix { config, lib, pkgs, inputs, ... }: let cfg = config.my.profiles.dank; in { imports = [ inputs.dank.nixosModules.dank-material-shell ]; options.my.profiles.dank.enable = lib.mkEnableOption "DankMaterialShell on niri"; config = lib.mkIf cfg.enable { # dependency: pull in home-manager integration my.profiles.home-manager.enable = true; # --- system side: niri session + DMS daemons/packages --- programs.niri.enable = true; # niri-flake nixosModule → Wayland session in SDDM programs.dank-material-shell = { enable = true; systemd.enable = true; quickshell.package = pkgs.unstable.quickshell; # >= 0.3.0 from unstable # enableSystemMonitoring / enableVPN / enableDynamicTheming / enableAudioWavelength # / enableCalendarEvents all default true — left on. }; # --- home side: DMS + niri keybinds for finn --- home-manager.users.finn = { imports = [ inputs.niri.homeModules.niri inputs.dank.homeModules.dank-material-shell inputs.dank.homeModules.niri ]; programs.dank-material-shell = { enable = true; systemd.enable = true; quickshell.package = pkgs.unstable.quickshell; niri.enableKeybinds = true; # Mod+Space launcher, Mod+V clipboard, media/brightness, power, lock… niri.enableSpawn = true; # spawn `dms run` at niri startup }; home.stateVersion = "26.05"; # match nixpkgs release; required by HM }; }; } ``` Registered by adding `./environments/dank` to `modules/environments/default.nix`. Open validation point (resolve during implementation, not a blocker): - Confirm the exact HM output name for the niri integration (`homeModules.niri` vs `homeModules.dankMaterialShell.niri`) and that `programs.niri.enable` is the correct niri-flake nixosModule option; adjust to match the pinned input revisions. - Confirm whether `programs.dank-material-shell.quickshell.package` needs to be set on both the system and HM sides or only one; set consistently. ### 4. Enable on mibook (`machines/mibook/environments.nix`) Add to the `my.profiles` block: ```nix dank.enable = true; ``` KDE (`kde-desktop.enable = true`) stays; both sessions are offered by SDDM. ### 5. Documentation No homepage dashboard entry (DMS is not a web service). CLAUDE.md is left unchanged unless, after implementation, the home-manager pattern warrants a short note — decided at the end, not up front (YAGNI). ## Data / control flow 1. `nixos-rebuild` builds the mibook toplevel; niri-flake registers a `niri` Wayland session, DMS nixosModule installs packages + the `dms` user service template, home-manager renders finn's niri config (with DMS keybinds) and DMS config. 2. At login, SDDM lists **KDE** and **niri**. Selecting niri starts the compositor; `spawn-at-startup` launches `dms run`, bringing up the DMS shell. 3. Keybinds invoke `dms ipc …` (launcher, clipboard, notifications, media, brightness, power, lock). DMS is further configured via its own GUI, persisted under `~/.config/DankMaterialShell/`. ## Risks / open questions - **unstable/stable skew:** the repo pins nixos-26.05 while `dank` and `niri-flake` track nixos-unstable, and quickshell comes from `pkgs.unstable`. Qt6/quickshell version mismatch between the DMS package and the stable base is the most likely failure. Mitigation: validate with a full toplevel build and, if it fails, align quickshell/qt sourcing (e.g. take the DMS package's own quickshell) before switching. - **HM output/option names** may differ from the researched revision — pin the inputs first, then read the resolved module options and adjust (see §3 open validation point). - **First HM activation** for finn: ensure `home.stateVersion` is set so the build doesn't error. ## Verification 1. `nix flake check` succeeds. 2. `nix build '.#nixosConfigurations.mibook.config.system.build.toplevel'` succeeds. 3. `sudo nixos-rebuild test --flake '.#mibook'`, then log into the **niri** session: DMS bar appears, `Mod+Space` opens the launcher, KDE session still works.