home-update rebuilds the desktop against the current flake.lock and never touches it; only sys-update runs `nix flake update`. So pulling a distro change that affects the home layer requires sys-update first (updates the lock), then home-update -- the reverse order rebuilds against stale inputs and silently skips the new home-side changes (hit while testing the mic fix). Also note hyprctl reload after a home-side keybind change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
31 KiB
Nomarchy
The rock-solid reproducibility of NixOS 26.05. The out-of-the-box polish of Omarchy/Omakub. One JSON file rules the look of the entire desktop; every theme change is a Home Manager generation — atomic, rollbackable, never partial.
┌──────────────────────────────────────────────────────────────────────────┐
│ theme-state.json (single source of truth) │
│ lives INSIDE your flake checkout, git-tracked │
└───────────────────────────────────┬──────────────────────────────────────┘
│
nomarchy-theme-sync apply gruvbox
1. merges the preset into the JSON (atomic write)
2. runs `home-manager switch` (no sudo, no system rebuild)
│
▼ pure read (nomarchy.stateFile)
┌──────────────────────────────────────────────────────────────────────────┐
│ Home Manager bakes EVERYTHING into one read-only generation: │
│ Hyprland (colors/gaps/borders) Waybar (palette or whole-swap) │
│ Ghostty (full ANSI palette) btop (asset or generated) │
│ Stylix → GTK, Qt, cursors, fonts │
└───────────────────────────────────┬──────────────────────────────────────┘
▼
wallpaper via awww (the one runtime piece:
applied post-switch + at session start, `bg next` cycles)
1. Layout
Flat on purpose. Two module trees, one options file each, no hidden layers.
.
├── flake.nix # inputs + the downstream API (exports below)
├── lib.nix # nomarchy.lib.mkFlake — one-call downstream wrapper
├── theme-state.json # ★ THE single source of truth (git-tracked!)
├── themes/ # 21 presets: <slug>.json + optional <slug>/ assets
│ ├── nord.json # palette (required, works alone)
│ └── nord/ # assets (optional, fixed filenames)
│ ├── backgrounds/ # wallpapers (auto-picked, SUPER+SHIFT+T cycles)
│ ├── btop.theme # hand-made config drop (else generated)
│ └── waybar.css # whole-swap: replaces the generated bar style
├── modules/
│ ├── nixos/ # the distro, system side
│ │ ├── default.nix # Hyprland session, Pipewire, greetd, fonts
│ │ ├── options.nix # nomarchy.system.* toggles
│ │ ├── plymouth.nix # boot splash, tinted from the JSON
│ │ └── file-manager.nix # Thunar GUI + gvfs/tumbler/udisks2
│ └── home/ # the distro, user side
│ ├── default.nix # entry point
│ ├── options.nix # nomarchy.* option surface
│ ├── theme.nix # JSON ingestion + wallpaper hook
│ ├── stylix.nix # GTK/Qt/cursors/fonts from the same JSON
│ ├── hyprland.nix # all JSON-driven
│ ├── waybar.nix
│ ├── ghostty.nix
│ ├── btop.nix
│ ├── rofi.nix # launcher + nomarchy-menu (power, clip)
│ ├── swaync.nix # notifications, same JSON
│ ├── idle.nix # hyprlock + hypridle, same JSON
│ ├── yazi.nix # flagship TUI file manager + plugins
│ ├── osd.nix # swayosd volume/brightness OSD
│ └── shell.nix # zsh + starship + bat/eza/zoxide
├── hosts/
│ ├── default/ # reference machine (thin: boot, user, hostname)
│ └── live.nix # bootable live ISO (try the distro, no install)
├── pkgs/
│ ├── nomarchy-theme-sync/ # state writer + rebuild dispatcher (Python)
│ └── nomarchy-install/ # live-ISO installer (gum + disko + mkFlake)
├── templates/downstream/ # `nix flake init -t` starter for users
├── docs/TESTING.md # how to verify changes (incl. AI-agent rules)
├── docs/OVERRIDES.md # how downstream users override defaults
└── tools/ # maintainer-only
├── import-palettes.py # converts old-distro themes → JSON + assets
├── test-live-iso.sh # build the ISO + boot it in QEMU
├── test-install.sh # full offline-install regression in QEMU
└── vm/ # headless-VM helpers (QMP keys, VNC shots,
# offline-pin gap analysis)
Rule of thumb: modules/ is the distro (reusable, no machine specifics),
hosts/ is a machine, themes/ is data, pkgs/ is code, tools/ is
maintainer-only. If a new file doesn't obviously belong to one of those, it
probably shouldn't exist.
2. Try it first (live ISO)
Boot the full desktop from a USB stick or VM without installing anything:
nix build .#nixosConfigurations.nomarchy-live.config.system.build.isoImage
# → result/iso/*.iso — dd to a stick, or boot it in QEMU:
tools/test-live-iso.sh
The live session auto-logs-in, seeds the flake at ~/.nomarchy, and pins
the locked inputs into the ISO store — so theme switching (including the
home-manager switch it triggers) works offline, exactly like on an
installed system. Verification checklist: docs/TESTING.md.
Like what you see? nomarchy-install (in a terminal) walks you through
installing to disk: pick a disk, LUKS2 full-disk encryption by default
(in exchange the desktop logs in passwordless — the passphrase already
gates the machine), user + hostname + timezone, hardware autodetection
(DMI → nixos-hardware profile), a hibernation-ready swapfile sized to RAM,
then disko partitions (GPT + ESP + BTRFS subvolumes incl. @snapshots —
snapper timeline snapshots are on) and nixos-install runs — without a
network when the ISO was built from a clean tree (the target's
flake.lock is composed from the rev the ISO carries). The installed
machine gets the standard downstream layout: the flake at ~/.nomarchy
(/etc/nixos symlinks to it), one mkFlake call, your
system.nix/home.nix. First boot lands in the fully themed desktop —
the installer pre-activates the Home Manager generation. UEFI only for now.
3. Using Nomarchy on your machine (downstream)
Nomarchy is consumed as a flake input — you never fork or edit this repo:
mkdir my-machine && cd my-machine
nix flake init -t "git+https://git.bemagri.xyz/bernardo/nomarchy.git?ref=v1"
You own two files day-to-day: system.nix and home.nix (plus
theme-state.json, written by the CLI). Your flake.nix is set up once —
later by the installer — and never hand-edited; it's a single call:
outputs = { nomarchy, ... }:
nomarchy.lib.mkFlake {
src = ./.;
username = "me";
hardwareProfile = "framework-13-7040-amd"; # optional, nixos-hardware name
};
mkFlake arg |
Default | Purpose |
|---|---|---|
src |
— (required) | Your flake directory (./.) |
username |
— (required) | Login name; flows into system.nix and names the HM config |
hardwareProfile |
null |
One nixos-hardware module name, or a list of them (pinned + tested by Nomarchy; unknown names fail with suggestions) |
system |
"x86_64-linux" |
Platform |
(Power users can skip mkFlake and wire nixosModules.nomarchy /
homeModules.nomarchy / overlays.default by hand — the wrapper is sugar.)
Two deliberately separate rebuild paths:
sudo nixos-rebuild switch --flake .#default # system: rare
home-manager switch --flake .#me # desktop: every theme change, no sudo
Day-to-day you'll use the shipped shortcuts instead:
sys-update # nix flake update + system rebuild (BTRFS snapshot first when available)
home-update # home-manager switch (no flake update, no sudo)
Order matters when pulling distro updates. home-update does not
touch the lock — it rebuilds the desktop against the current
flake.lock. A new Nomarchy revision (new keybinds, theming, modules)
arrives only when the lock is updated, which sys-update does
(nix flake update). So to pull an update that affects the desktop layer:
run sys-update first (updates the lock + rebuilds the system), then
home-update (re-applies the desktop against the new lock). Doing them in
the other order rebuilds the desktop against the old inputs and silently
skips the new home-side changes. After a home-side keybind/config change,
also hyprctl reload (or relogin) so the running session re-reads it.
Override anything via the nomarchy.* surface or plain NixOS/HM options:
appearance (gaps/colors/fonts) changes through nomarchy-theme-sync,
behaviour (input/misc/monitor/chrome) is mkDefault so a plain home.nix
assignment wins, and bind/exec-once lists concatenate. Full guide with
examples: docs/OVERRIDES.md.
| Option | Default | Purpose |
|---|---|---|
nomarchy.stateFile |
— (required) | Path to your theme-state.json |
nomarchy.terminal |
"ghostty" |
Terminal for keybinds and $TERMINAL |
nomarchy.keyboard.layout |
"us" |
XKB layout for the Hyprland session (installer writes it; pairs with xkb + console.useXkbConfig in system.nix) |
nomarchy.keyboard.variant |
"" |
XKB variant for the session |
nomarchy.hyprland.enable |
true |
Nomarchy's Hyprland config |
nomarchy.waybar.enable |
true |
Nomarchy's Waybar |
nomarchy.rofi.enable |
true |
Themed rofi launcher + nomarchy-menu dispatcher |
nomarchy.swaync.enable |
true |
swaync notifications, themed |
nomarchy.idle.enable |
true |
hyprlock + hypridle (idle lock 5 min, display off 10, suspend 30) |
nomarchy.yazi.enable |
true |
yazi TUI file manager, themed + curated plugins |
nomarchy.osd.enable |
true |
swayosd on-screen display for volume/brightness/mute |
nomarchy.shell.enable |
true |
zsh + starship prompt + bat/eza/zoxide (zsh is the default login shell) |
nomarchy.ghostty.enable |
true |
Nomarchy's Ghostty |
nomarchy.btop.enable |
true |
btop with per-theme colors |
nomarchy.stylix.enable |
true |
GTK/Qt/cursor theming |
nomarchy.themesDir |
Nomarchy's themes/ |
Where per-theme app overrides are probed |
nomarchy.system.plymouth.enable |
true |
Branded boot splash, background from the theme JSON (recolors on system rebuilds) |
nomarchy.system.fileManager.enable |
true |
Thunar GUI + gvfs/tumbler/udisks2 (the "open folder" handler) |
nomarchy.system.greeter.enable |
true |
greetd/tuigreet |
nomarchy.system.audio.enable |
true |
Pipewire stack |
nomarchy.system.bluetooth.enable |
true |
Bluetooth + blueman |
4. How theming works
Pure JSON ingestion
The trap with "read a mutable file from Nix" is pure evaluation: flakes
cannot read arbitrary $HOME paths without --impure (the old prototype
required it — never again). Nomarchy's convention: the state file lives
inside the consuming flake and is wired via
nomarchy.stateFile = ./theme-state.json;. Reading it is pure — it's flake
source. It must be git-tracked (nomarchy-theme-sync runs
git add --intent-to-add after every write as a safety net).
One change = one generation
nomarchy-theme-sync apply <theme> merges the preset into the JSON and runs
home-manager switch (override the command with $NOMARCHY_REBUILD, or pass
--no-switch to only write). Everything is baked: Hyprland, Waybar, Ghostty,
btop, and — via Stylix, mapped onto base16 roles — GTK, Qt, cursors and
fonts. No runtime patching means no partial states, and home-manager generations is also your theme history. Waybar even restyles in place: it
re-reads style.css when the symlink flips.
The wallpaper is the one runtime piece (awww — nixpkgs' swww — is
imperative; nothing in Nix consumes the path): applied at session start and
after every switch via a tiny activation hook, cycled instantly with
bg next.
Per-theme app assets (themes/<slug>/)
Recoloring covers 95% of theming; the rest is one optional assets directory per theme — a single place to look, unlike the old distro's split:
| Asset | Mechanism |
|---|---|
backgrounds/ |
wallpapers; empty wallpaper in the state means "first one"; bg next cycles |
btop.theme |
baked into the generation (generated from the palette when absent) |
waybar.css |
whole-swap: replaces the generated bar style entirely (probed at eval time, self-contained) |
waybar.jsonc |
whole-swap for the bar layout (must be plain JSON) |
rofi.rasi |
whole-swap: replaces the generated launcher/menu theme entirely |
Six ported themes ship a waybar.css identity (catppuccin, lumon, nord,
retro-82, summer-day, summer-night). Custom user themes can live in
$NOMARCHY_PATH/themes/ (preset lookup) and nomarchy.themesDir (eval-time
asset probe).
5. Day-to-day
nomarchy-theme-sync list # 21 presets (nord, gruvbox, rose-pine, …)
nomarchy-theme-sync apply kanagawa # whole desktop, one generation (~a switch)
nomarchy-theme-sync set ui.gapsOut 16 # tweak one knob (also a switch)
nomarchy-theme-sync bg next # cycle wallpapers — instant, no rebuild
nomarchy-theme-sync bg auto # back to the theme's default wallpaper
nomarchy-theme-sync get colors.accent
sys-update # update inputs + rebuild the system (snapshots first)
home-update # rebuild just the desktop layer
Keybinds: SUPER+Return terminal · SUPER+D launcher · SUPER+T theme
picker · SUPER+SHIFT+T next wallpaper · SUPER+X power menu ·
SUPER+E file manager (yazi) · SUPER+N notifications · SUPER+CTRL+V
clipboard history · SUPER+Q
close · SUPER+1..9 workspaces · Print region screenshot.
6. Extending
- New theme: drop a JSON into
themes/(schema = any existing preset), plus an optionalthemes/<slug>/assets directory. - New themed value: add the key to
theme-state.jsonand consume it in the Nix modules. One place — there is no second renderer to keep in sync. - Importing more old-distro palettes:
tools/import-palettes.py <palettes-dir> themes/.
Roadmap
-
Menu system (apps launcher + theme switching + system actions), built on rofi 2.0 (native Wayland on 26.05) — its
.rasitheme is baked from theme-state.json like every other app, with rich per-element styling:- ✓ shipped:
modules/home/rofi.nix(per-element theme generated from the palette,themes/<slug>/rofi.rasiwhole-swap) and thenomarchy-menudispatcher: root picker (no args) ·power(lock/logout/suspend/hibernate/reboot/shutdown, SUPER+X) ·theme(SUPER+T) ·clipboard(cliphist, SUPER+CTRL+V) ·calc(qalc, copy/chain) ·files(fd → xdg-open) ·web(Google). SUPER+D isrofi -show drun. - ✓ shipped modules:
network(nmtui in$TERMINAL) ·bluetooth(blueman-manager) ·capture(grim/slurp submenu: region/full → clipboard/file, saved to~/Pictures/Screenshots) ·keybinds(the cheatsheet, see below) ·ask(free-text → claude CLI in a terminal; auths via OAuth, no API key; pulled fresh vianpx @anthropic-ai/claude-code@latestrather than the nixpkgs package, which lags model releases —nodejsis bundled for npx; REPL stays open) - ✓ keybindings cheatsheet:
modules/home/keybinds.nixis the single source for both the Hyprland binds and the SUPER+? rofi list, so they can't drift;nomarchy-menu keybindsrenders the padded two-column sheet (generated/mouse binds carried in itsextrarows) - ✓ shipped binds:
SUPER+Space→rofi -show drun(quick launch) ·SUPER+M→nomarchy-menu(main menu) ·SUPER+?→ the cheatsheet;SUPER+Dstays-show drun - launcher icons: ✓
show-iconson, drawing from the theme's icon set (Papirus, via the icon-themes work below) - decision record: resolves the old Walker/Lua question — no GTK4 launcher, no second theming pipeline; the dispatcher owns the menu structure, so the renderer stays swappable (we moved fuzzel → rofi 2.0 once mainline gained native Wayland, for its richer theming)
- ✓ shipped:
-
Calculator module rework: the current
calcflow (modules/home/rofi.nix) is unsatisfying — you commit the expression blind, then the result only appears in the next menu's-mesgline, andqalc -tmisparses common phrasings (e.g.15% of 200→rem(15, 1 B)instead of30). Rework toward live results as you type (rofi-calc-style: each keystroke re-evaluates and the answer is the top entry, Enter copies), a more robust qalc invocation, and graceful handling of parse errors. Decide whether to keep the hand-rolled dmenu loop or adopt a dedicated calc mode/plugin. -
Theme parity with legacy: summer-day/night now carry their legacy bar layouts as
waybar.jsoncwhole-swaps (adapted: dead legacy script modules dropped, Nerd-Fonts-v2 codepoints remapped to FontAwesome/v3, logo button opens nomarchy-menu); the other four identity themes are palette recolors and already match. Remaining: a visual pass over all six on the live ISO -
Per-theme rofi identity: the
themes/<slug>/rofi.rasiwhole-swap ships, and summer-day/night carry their legacy designs (inverted window, green inputbar, yellow bottom-border). Remaining: author.rasiidentities for the other four ported themes if/when they want one (the generated palette theme is the default and looks fine) -
Faster switches: move
backgrounds/out of the flake source (the 86 MB re-copy on every state write is the main eval tax), then pre-built theme variants if still needed -
Greeter (tuigreet/SDDM) theming from the same JSON (Plymouth ships since v1:
nomarchy.system.plymouth.*, background tinted from the state file) -
Installer round 2: multi-disk BTRFS RAID, impermanence, BIOS/legacy boot (v1
nomarchy-installis single-disk UEFI — seepkgs/nomarchy-install) -
launch-or-focus UX scripts (swayosd volume/brightness OSD ships since v1:
nomarchy.osd.*, media keys driveswayosd-client, themed from the JSON) -
Distro branding, round 2:
distroName = "Nomarchy"ships (os-releasePRETTY_NAME, systemd-boot entries, ISO menu label). ✓ tuigreet greeting (Welcome to <distroName>) and a brandedusers.motd(doubling as a helper cheat sheet), both keyed offdistroName. ✓isoImage.splashImage— the vendored vector logo (modules/nixos/branding/logo.svg, from legacy) recolored to the palette accent on the theme base, built at ISO-build time (hosts/live.nix). Remaining:isoImage.grubThemeso UEFI boot matches the isolinux splash (needs a full grub theme dir), and thedistroIdquestion (it changesDEFAULT_HOSTNAMEand upstreamisNixoschecks — needs a test pass; nixos-* CLI names stay regardless) -
✓ fastfetch branding:
modules/home/fastfetch.nix(nomarchy.fastfetch.enable) — the vendored vector logo, recolored to the palette accent and rendered to compact block-art via chafa at build time (tracks the theme), fronting a curated module list. Replaces the oversized legacy ASCII with a themed, sized logo. -
✓ Nomarchy logo font in Waybar: vendored
Nomarchy.ttf(modules/nixos/branding/), installed viafonts.packages, and the summer-day/night menu buttons now use itsU+F000glyph withfont-family: Nomarchypinned in their CSS (Nerd Fonts also occupy U+F000, so the pin is required). The other themes have no logo button. -
Quality-of-life command aliases: assemble a curated collection of shell aliases/abbreviations for common operations (git, nix, navigation, the nomarchy helpers, …), themed into the zsh shell experience (
modules/home/shell.nix). Decide scope and which to ship on by default. -
Theme-switch feedback: ✓ the "rebuilding…" notification is now persistent (timeout 0) and replaced in place by "applied ✓" / failure via a synchronous tag, so a multi-minute switch never reads as a failed selection. (An honest indeterminate indicator — HM gives no % — a literal progress widget would be cosmetic; revisit only if wanted.)
-
Icon themes: ✓ ships
papirus-icon-theme; the resolved name lives onnomarchy.theme.iconTheme(the JSON's optionaliconsfield, else Papirus-Dark/Light bymode) and feeds both Stylix'sgtk.iconTheme(Thunar/GTK apps) and rofi'sshow-icons. Remaining (optional): per-themeiconsoverrides for the presets, or shipping more icon packs. -
Nicer shell out of the box: ✓ zsh is the default login shell, with a starship prompt themed from the JSON, autosuggestions + syntax highlighting, and modern-CLI ergonomics —
cat→bat (theme "ansi", so it tracks the palette),ls→eza,cd→zoxide, pluslt/tree.nomarchy.shell.enable. (Deliberately did NOT alias grep→rg / find→fd: their flags differ enough to surprise;rg/fdship as themselves.) -
Default application suite: install a complete-workstation set (vscode, libreoffice, gimp, inkscape, texlive-full, …) behind a
nomarchy.apps.*option surface so each is individually opt-out for users who want a leaner machine. Watch closure size (texlive-full is multi-GB — likely default-off or a lighter scheme). -
✓ Plymouth logo contrast: the shipped art was a fixed navy that vanished on dark bases.
modules/nixos/plymouth.nixnow recolors every element from the palette at build time (flat fill, alpha kept): logo/lock/bullet → text, entry/progress-box → surface, progress-bar → accent. Reads on light and dark; follows the theme as of the last system rebuild (like the background tint). -
Hibernate double-unlock: on resume from hibernate the LUKS passphrase already gates the machine, but hypridle's
before_sleep_cmdalso locks hyprlock, so the user types a password twice. Lock only on suspend (not hibernate), or skip the hyprlock prompt when resuming from a LUKS-encrypted hibernate — seemodules/home/idle.nix. -
✓ Key agents & pinentry: ships
modules/home/keys.nix(nomarchy.keys.enable): one agent —services.gpg-agentwithenableSshSupportfronts SSH, so a singlepinentry-qt(native-Wayland, Stylix-themed Qt) handles GPG and SSH passphrases alike.SSH_AUTH_SOCKcomes from the agent's zsh integration; cache TTLs (30 min / 2 h) govern re-prompting. gnome-keyring stays the Secret Service (modern versions run no SSH agent, so no socket contention); screen lock doesn't flush the cache. Remaining (optional): a session-levelSSH_AUTH_SOCKexport so GUI clients launched outside a shell also see the agent. -
Sanitize & organize the repo: a housekeeping pass for consistency and clarity. Candidate targets (scope still to be defined): prune now-redundant config (e.g. the installer still writes
console.useXkbConfig/boot.initrd.systemd.enableintosystem.nix, which are distro-wide defaults as of the LUKS-keymap fix); reconcile the README option tables with the actualnomarchy.*surface; audit comments/docs for drift against the code; and re-check that every file still earns its place under themodules/hosts/themes/pkgs/toolsrule of thumb. -
Laptop power / battery management: today the distro does no active power management — only
services.upoweris on, and that's just battery reporting for the Waybar widget; CPU/thermal/charge behaviour is whatever the kernel and the nixos-hardware profile default to. Add a real power story behind anomarchy.system.power.*surface, gated to laptops (the installer already detects chassis):- profiles: ship
power-profiles-daemonby default (the upstream- aligned choice — power-saver/balanced/performance viapowerprofilesctl), with a switcher in the rofi menu and a Waybar indicator. Offer TLP as an opt-in for maximum battery life (note: mutually exclusive with PPD, and more aggressive/opaque). Decision to make: PPD-default vs TLP-default. - thermal:
thermaldon Intel (the Latitude is Intel) to avoid throttling. - longevity: battery charge thresholds (e.g. stop charging at ~80%) where the hardware supports it.
- cohere with
modules/home/idle.nix(idle lock / display-off / suspend) and review logind lid handling so the power behaviours line up.
- profiles: ship
-
Opt-in services & integrations: the counterpart to the opt-out application suite above — heavier or more personal integrations shipped off by default, each a
nomarchy.services.<name>.enabletoggle a downstream flips on in one line. Keeps the base lean while making common additions trivial. Candidates by area:- cloud/sync: Nextcloud client; Syncthing (
services.syncthing) - local AI: LM Studio (
lmstudio); Ollama (services.ollama, optional GPU accel) — pairs with the menu's Ask-Claude philosophy - containers/VMs: Docker/Podman; libvirt + virt-manager
- networking: Tailscale (
services.tailscale); WireGuard - gaming/media: Steam (
programs.steam); OBS Studio - devices: printing (CUPS + Avahi); KDE Connect / phone integration; OpenRGB
- backup: restic/borg (
services.restic) - escape hatch: Flatpak (
services.flatpak) for apps outside nixpkgs
Decisions: the curated set; whether system services and GUI apps share one surface or split (
nomarchy.services.*system-side vs home-side packages); and how it relates tonomarchy.apps.*(opt-out suite). Unfree entries are already covered (allowUnfree = true). - cloud/sync: Nextcloud client; Syncthing (
-
Display / monitor management: today Hyprland just uses
monitor = ,preferred,auto,1(mkDefault). Add a real external-monitor/dock story: declarative per-output config, hotplug profiles (kanshi-style, or Hyprland's own monitor rules), and optionally a GUI arranger (nwg-displays writes Hyprland monitor config). Decide declarative-only vs GUI, and the option shape (nomarchy.monitorsvs plain Hyprlandmonitorlists). -
Night light / blue-light filter: schedulable colour-temperature shift via
hyprsunset(Hyprland-native; wlsunset/gammastep are alternatives) — sunset/sunrise or a fixed schedule, with a menu + Waybar toggle. -
Runtime keyboard-layout switching: the session layout is a single
nomarchy.keyboard.layouttoday. Support a list of layouts with a toggle bind (hyprctl switchxkblayout/ xkbgrp:options) and a Waybar indicator for the active layout. Natural follow-on to the LUKS-keymap work — keep the system (console/initrd) and session layouts in sync. -
Do-Not-Disturb: a swaync DND toggle (
swaync-client -dn) wired into the menu and a Waybar indicator, to silence notifications for presentations/focus. -
Snapshot browse/restore UX: snapper already takes BTRFS timeline snapshots (
nomarchy.system.snapper); surface them from the desktop — a rofi menu (or btrfs-assistant) to browse/diff/restore and boot-from- snapshot — so rollback isn't CLI-only. -
Update awareness: updates are manual today (
sys-update/home-update); add a Waybar indicator / notification when flake inputs are stale or a new nixpkgs rev is available (optionally with a pending-change count). Augments, never replaces, the explicit rebuild flow. -
"nomarchy" control center: a single TUI/GUI front-end over the common toggles — theme, power profile, opt-in services, display, DND — built on the same
nomarchy-theme-sync/nomarchy.*surface the menu already uses. Plus a first-boot welcome that lands new installs in a guided "pick your theme / essentials" flow (ties into the branding work).
Known issues & follow-ups
- ✓ Yazi TOML parse error on startup: yazi 26.x made fetchers'
groupfield required, so[[plugin.prepend_fetchers]]failed to parse and yazi fell back to presets. Fixed by addinggroup = "git"to both git fetcher entries inmodules/home/yazi.nix(the git plugin'ssetup()only renders the linemode; the fetcher still needs registering). - ✓ Starship prompt styling: dropped the powerline look (the
[]separator glyph +bg:fills) for a flat prompt — bold-accent directory, warn git branch, subtext status/duration,❯character, all plain colored text (modules/home/shell.nix). Also wired incmd_duration, which was configured but never referenced informat. - ✓ xfce deprecation warnings: moved
xfce.exo→pkgs.xfce4-exoand the three Thunar plugins to their new top-level names inmodules/nixos/file-manager.nix; the eval warnings are gone. - ✓ Rofi function keybindings: direct
SUPER+CTRL+<mnemonic>binds jump straight to eachnomarchy-menumodule — V clipboard · C calc · W web · F files · N network · B bluetooth · S capture · A ask — added tomodules/home/keybinds.nix, so they also show in the SUPER+? cheatsheet. - ✓ Enable nix-ld by default:
programs.nix-ld.enableis on distro-wide (modules/nixos/default.nix), so prebuilt/foreign dynamically-linked binaries run out of the box. - ✓ Hyprland border colors off for some themes: the cause was v1
forcing an
accent→accentAltgradient on every theme; legacy used a solid border (accent for nord/retro-82/lumon, the text tone for kanagawa/summer-day/summer-night). Added a palette-resolvedborderfield ({active, inactive}) to the theme schema (theme.nix), consumed solid inhyprland.nix, and declared it in every preset so a switch always replaces it. All six identity themes now match legacy exactly. - ✓ Waybar shows non-existent workspaces: the v1 summer port "fixed"
legacy's deprecated
persistent_workspaces(underscore — silently ignored by current Waybar, so legacy only ever showed existing workspaces) into the modernpersistent-workspaces(hyphen), which Waybar honours → all 10 rendered as phantoms. Dropped the block fromthemes/summer-{day,night}/waybar.jsonc; the other themes use the generatedwaybar.nix, which never had it, so they already match. - ✓ GTK/Qt ignore the theme's light/dark mode: Stylix set
polaritybut not theorg.freedesktop.appearance color-schemethat GTK4/libadwaita and Qt6 read via the portal, so a light theme could still render apps dark.stylix.nixnow setsdconforg/gnome/desktop/interface color-scheme=prefer-light/prefer-darkfromt.mode(xdg-desktop-portal-gtk already ships, andprograms.dconfis on system-side), so libadwaita/Qt follow the palette. Needs a live session to confirm the portal picks it up for all apps.