Desktop (Nixarchy / Omarchy on Hyprland)¶
Last Updated: 2026-09-01
The problem¶
This fleet went through five Wayland compositors — niri, labwc, mango, Hyprland
and COSMIC — plus two shells (Noctalia, DankMaterialShell) and three greeters.
Every one of them needed its own portal wiring, its own theme plumbing and its
own session entry, and each combination broke in a different way. Screen sharing
in particular fails silently whenever XDG_CURRENT_DESKTOP disagrees with the
portal backend actually installed.
The solution¶
One Wayland session, on every host: Omarchy on Hyprland, packaged for NixOS as Nixarchy and consumed as a flake input. GNOME stays installed and selectable as a fallback. Everything else is gone, including the flake inputs.
| Host | Sessions offered | Greeter | Default session |
|---|---|---|---|
| p620 | omarchy, gnome |
SDDM (Omarchy's) | omarchy |
| razer | omarchy, gnome |
SDDM (Omarchy's) | omarchy |
| p510 | omarchy, gnome |
SDDM (Omarchy's) | omarchy |
Each host wires it up in hosts/<host>/nixos/nixarchy.nix, which imports the
Nixarchy module plus a set of shared fragments from hosts/common/nixos/:
imports = [
inputs.nixarchy.nixosModules.nixarchy
../../../nixarchy-apps.nix # app selection, copied in by nixarchy-apply
../../common/nixos/omarchy-input.nix
../../common/nixos/omarchy-sddm.nix
../../common/nixos/omarchy-workspaces.nix
../../common/nixos/omarchy-gog.nix
../../common/nixos/omarchy-sole-hyprland.nix
../../common/nixos/omarchy-stylix-theme.nix
];
programs.nixarchy.enable = true;
programs.nixarchy.user = "olafkfreund"; # puts the user in the `input` group
programs.nixarchy.displayManager = true; # Omarchy's SDDM
programs.nixarchy.bootSplash = "force"; # Omarchy's Plymouth theme
Why two files sit at the flake root¶
A flake cannot read a file outside its own tree. Two Omarchy features therefore
write into the repository itself, and both leave the tree dirty — which matters,
because nhs refuses to run on a dirty tree.
| File | Written by | Read by |
|---|---|---|
nixarchy-apps.nix |
nixarchy-apply (copies ~/.config/nixarchy/apps.nix) |
each host's nixarchy.nix |
nixarchy-theme.nix |
the theme-set.d hook of omarchy theme set X |
modules/desktop/stylix-theme.nix |
Copying is not importing
nixarchy-apply copies apps.nix in and stops there. Importing it is the
host's job. p620 lacked that import until recently, so app selections made
in the menu were copied into the flake and built by nobody.
Only one Hyprland entry at login¶
programs.hyprland is enabled by the Nixarchy module itself, not by this repo.
It supplies the portal, uwsm and the wayland-session basics, so it cannot
simply be turned off — but it also registers its own Hyprland login entry,
giving two indistinguishable choices at the greeter.
There is no option to drop a single session.
hosts/common/nixos/omarchy-sole-hyprland.nix therefore forces the module off
and restates the parts Nixarchy needs. Read that file before touching anything
Hyprland-adjacent; the two obvious workarounds both fail:
- A filtered
mkForceonservices.displayManager.sessionPackageswould have to read the value it defines — infinite recursion. - A session-less repackage of the compositor is rejected by the option's own
type, which asserts
providedSessions != [ ].
The nix eval diff of the whole system config before and after that file is
empty apart from sessionPackages.
Configuration is Lua, not hyprlang¶
Hyprland 0.56 config on these hosts is Lua. Dispatchers are namespaced under
hl.dsp.*, so the string forms found in most documentation silently do nothing:
hyprctl dispatch 'hl.dsp.dpms({ action = "enable" })' # correct
hyprctl dispatch "dpms on" # no-op here
User-facing config lives in ~/.config/hypr/ (hyprland.lua, input.lua,
monitors.lua, bindings.lua), seeded by Nixarchy with cp -rn. Because the
seed does not overwrite, a Home Manager file competing for the same path needs
force = true.
Theming: Omarchy is the source of truth¶
omarchy theme set X retints the 24 files Omarchy owns immediately and
writes X into nixarchy-theme.nix. modules/desktop/stylix-theme.nix reads
that name, loads the theme's colors.toml out of the Nixarchy package, maps its
named roles onto base16 and hands the result to Stylix.
Everything Omarchy cannot reach at runtime — Plymouth, GRUB, the console, GTK,
Qt, fonts and the Home Manager targets — follows at the next rebuild, not
instantly. Because inputs.nixarchy is flake-wide, p510 follows the same palette
as the workstations.
Reach the package through inputs
Use inputs.nixarchy, never config.programs.nixarchy.package. Nixarchy
consumes Stylix, so reading its config from the module that defines
stylix.base16Scheme closes the module fixpoint and evaluation dies with
infinite recursion.
See Theming (Stylix) for the palette itself.
Screen sharing¶
xdg.portal.configPackages carries hyprland-portals.conf, which routes
ScreenCast to the Hyprland backend rather than wlr. Losing it is the classic
screen-sharing failure on this fleet, so
omarchy-sole-hyprland.nix names it explicitly rather than relying on a default.
If a cast fails with "unit is masked", the cause is almost always a stale
XDG_CURRENT_DESKTOP from switching sessions without a clean re-login.
What was removed¶
niri, labwc, mango, Noctalia and DankMaterialShell — modules, sessions, greeters
and flake inputs. Any comment or document describing dms-shell.nix,
"Niri (DMS)", "Hyprland (DMS)" or ${DESK_SHELL:-noctalia} is describing a
tree that no longer exists.
COSMIC is parked, not removed: desktop.cosmic.enable = false on every host,
with the module at modules/desktop/cosmic.nix and the applets under
pkgs/cosmic-applets/ kept for an easy re-enable.