cpugov, sink-switcher and nightlight were referenced solely by the waybar config; the Quickshell popouts cover all three. btnote, capsnote, vpn and waybar-hidpp are unreferenced anywhere. Adds the two system units for battery threshold restore and camera shutoff, which had been missed.
moonix
NixOS configuration for a scrollable-tiling Wayland desktop: niri as the compositor, Quickshell as the bar and launcher, moongreet as the login greeter, moonlock as the screen locker, Catppuccin Mocha throughout.
Ships Nix packages for the components that are not in nixpkgs — moonlock, moongreet, moonset, stasis, sweet-cursors — and NixOS modules that assemble them into a working session.
The XDG configuration files (niri, Quickshell, foot, GTK, Qt) come from the
moonarch repository, which is consumed as a flake input. One set of config
files therefore stays valid on both NixOS and Arch.
Layout
flake.nix Inputs and outputs
pkgs/ Build recipes
moonlock.nix screen locker (GTK4, PAM, fingerprint)
moongreet.nix greetd greeter
moonset.nix session power menu
stasis.nix idle manager
sweet-cursors.nix cursor theme
modules/
desktop.nix /etc deployment, package set, theme
greetd.nix greetd + moongreet
services.nix systemd system and user services
hosts/
testvm/ QEMU test VM
thinkpad/ ThinkPad T14 Gen 3 (AMD)
nixosModules.moonarch is the entry point: it imports all three modules and
hands them the packages and the config source.
Usage
Build a single package:
nix build .#moonlock
Build a whole system without activating it:
nix build .#nixosConfigurations.testvm.config.system.build.toplevel
Activate:
sudo nixos-rebuild switch --flake .#testvm
Installing on a machine
The disk layout is not declared here. The graphical installer handles
partitioning, encryption and hardware detection, and produces the one file that
cannot be written in advance: hardware-configuration.nix with the machine's
UUIDs, LUKS devices and kernel modules.
-
Boot the NixOS ISO and run the installer. Choose
dkressleras the user name — that is whathosts/thinkpad/default.nixdeclares. Pick btrfs, snapper expects it. -
Reboot into the fresh system. It runs on the generated configuration, without this repo.
-
Enable flakes and install git — neither is available yet:
sudo nano /etc/nixos/configuration.nix # nix.settings.experimental-features = [ "nix-command" "flakes" ]; # environment.systemPackages = with pkgs; [ git ]; sudo nixos-rebuild switch -
Clone this repo and take over the hardware file:
git clone https://gitea.moonarch.de/nevaforget/moonix.git cp /etc/nixos/hardware-configuration.nix moonix/hosts/thinkpad/ -
Add the import to
hosts/thinkpad/default.nix:imports = [ ./hardware-configuration.nix ]; -
Switch and reboot:
sudo nixos-rebuild switch --flake ~/moonix#thinkpad
If step 6 breaks the system, pick the previous generation in the boot menu — the installer's configuration stays available as generation 1.
The nixos-hardware profile for the T14 Gen 3 (AMD) is already wired up:
firmware, power management and graphics quirks come with it.
Until step 5 is done, nixosConfigurations.thinkpad does not evaluate:
error: Failed assertions:
- The 'fileSystems' option does not specify your root file system.
That is expected — the filesystems live in hardware-configuration.nix.
Version bumps
The application repos are pinned to release tags. After tagging a new version:
# adjust the tag in flake.nix, then
nix flake update moonlock
Configuration files
Config files are deployed unchanged wherever possible. Three are generated instead, because they contain a path that does not exist under Nix:
| File | Reason |
|---|---|
moongreet.toml |
wallpaper path, rewritten to the store path |
waypaper/config.ini |
wallpaper path, rewritten and seeded into $HOME |
| fontconfig defaults | /etc/fonts/conf.d is owned by the NixOS module |
kanshi/config is not deployed: the file is empty, kanshi rejects it and
restarts in a loop. Monitor profiles are machine specific and belong in
~/.config/kanshi/config; the service starts only when that file exists.
Programs that read only from $HOME and have no system-wide fallback get a
copy seeded through systemd.user.tmpfiles with the C directive, which never
overwrites later edits.
Test VM
hosts/testvm targets a QEMU guest. The launcher script lives outside this
repo at ~/VMs/moonix-vm.sh.
It deliberately contains no testing shortcuts — no passwordless sudo, no SSH
password authentication. Set those at runtime when needed, for example through
a drop-in under /run/systemd/system/, so they do not end up in version
control.
The guest needs a 3D capable virtio GPU: niri's TTY backend fails every buffer
import with Error::DeviceMissing otherwise, and software rendering is not a
workaround. On the current host that path has twice triggered an amdgpu hard
recovery, killing the QEMU process — shut the VM down when not testing.
Known gaps
Four entry points from the niri config and the helper scripts call a launcher that is not installed here, and therefore do nothing:
| Entry point | Function |
|---|---|
Super+C |
clipboard history |
moonarch-sink-switcher |
audio sink picker |
moonarch-vpn |
VPN picker |
moonarch-cpugov |
CPU governor picker |
cliphist records the clipboard, so only the picker front-end is missing.