From d3a3b12e37780355c2ab0426c3d617d28df7f703 Mon Sep 17 00:00:00 2001 From: "Finn@MiBook" Date: Fri, 24 Jul 2026 12:13:49 +0200 Subject: [PATCH] docs: design for DankMaterialShell (niri) profile Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_018Sv2QAunLcLo3tS1YsfLgN --- .../2026-07-24-dank-material-shell-design.md | 234 ++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-24-dank-material-shell-design.md diff --git a/docs/superpowers/specs/2026-07-24-dank-material-shell-design.md b/docs/superpowers/specs/2026-07-24-dank-material-shell-design.md new file mode 100644 index 0000000..23c20e4 --- /dev/null +++ b/docs/superpowers/specs/2026-07-24-dank-material-shell-design.md @@ -0,0 +1,234 @@ +# 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.