No description
Find a file
Mads Fagerlund ddca4e1d72
hyprland: virtual desktops, and stop OOM kills from killing the session
Workspaces were pinned one-per-monitor, so switching only ever moved one
screen. The virtual-desktops plugin replaces them with vdesks that span
every monitor, and SUPER+1..5 now switches all screens together. Hyprland
plugins are ABI-locked to the compositor, so the input's nixpkgs follows
ours to compile against the hyprland we actually run. cycleworkspaces
stays off: upstream says it breaks above 2 monitors, and pc has 3.

The session had also been dying several times a day, which looked like a
Hyprland crash and was not one. There was no swap at all, and a
nixos-rebuild forks ~60 nix evaluators; stacked on a browser and a few
editor sessions that exhausted all 15G, leaving page cache squeezed to
40M while 13G sat in anon and nothing was reclaimable. The kernel then
OOM-killed 1Password (highest oom_score_adj), and because every GUI app
shares the wayland-wm@hyprland.service cgroup, systemd's default
OOMPolicy=stop tore down the whole unit -- compositor included, with
uwsm's Restart=no meaning nothing came back.

Two independent fixes: zram swap (50% of RAM, zstd) with vm.swappiness
raised to 180, so the kernel compresses anon pages instead of evicting
cache, which raises the ceiling; and OOMPolicy=continue, so that hitting
it costs one app instead of the desktop. zram rather than a swapfile
because root is compress=zstd, and a btrfs swapfile needs its own
nodatacow, uncompressed subvolume.

Also lands the pending work in this tree: hyprshot replaces grimblast for
screenshots (it reads HYPRSHOT_DIR, not XDG_SCREENSHOTS_DIR, so shots were
landing loose in ~/Pictures), hyprlock at boot so login lands on the lock
screen and unlocks the keyring, the battery popup moves to SUPER+R, and
SUPER+W/E open floating wifi and bluetooth panels.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-04 20:19:30 +02:00
config hyprland: virtual desktops, and stop OOM kills from killing the session 2026-10-04 20:19:30 +02:00
firmware update 2026-09-07 23:17:20 +02:00
hosts mbp: move root to btrfs on p8, reclaiming 256G from macOS 2026-10-04 14:35:28 +02:00
.gitignore NixOS flake: mbp (Asahi) + pc (x86), Hyprland/Zen/neovim, README 2026-07-01 18:05:21 +00:00
flake.lock hyprland: virtual desktops, and stop OOM kills from killing the session 2026-10-04 20:19:30 +02:00
flake.nix hyprland: virtual desktops, and stop OOM kills from killing the session 2026-10-04 20:19:30 +02:00
README.md pc: generic hardware profile (no per-machine gen); trim README 2026-07-01 18:09:31 +00:00

nixos

One flake, two machines. Hyprland + greetd autologin, Zen+Tridactyl, neovim, zsh+starship.

host arch build
mbp aarch64 MacBook M1 Pro (Asahi)
pc x86_64 any UEFI x86
flake.nix          all config (common + home modules, both hosts)
config/            raw configs: hypr eww fuzzel nvim
hosts/*/hardware-configuration.nix   mbp: regenerate on Mac · pc: generic, as-is
firmware/          Mac Wi-Fi/BT blobs — git-add at install. KEEP REPO PRIVATE.

Set time.timeZone in common. Rename a host = change the nixosConfigurations.<name> key + its networking.hostName.

Apply

sudo nixos-rebuild switch --flake ~/nixos#mbp   # or #pc
nix flake update && sudo nixos-rebuild switch --flake ~/nixos#mbp   # update

Roll back = pick an older generation at boot.

Install: MacBook (Asahi)

Full/latest guide: https://github.com/nix-community/nixos-apple-silicon/blob/main/docs/uefi-standalone.md. Back up — a bad partition can brick the Mac.

  1. macOS Terminal: curl https://alx.sh | sh → r resize (≥20 GB free) → f install UEFI environment only, name NixOS → recovery: permissive security. Reboots to U-Boot; power off.
  2. Installer USB (on a Linux+Nix box): nix build github:nix-community/nixos-apple-silicon#installer-bootstrap -o installer then dd the ISO to USB.
  3. Boot USB → sudo su:
sgdisk /dev/nvme0n1 -n 0:0 -s && sgdisk /dev/nvme0n1 -p   # note new 8300 part, e.g. p5
mkfs.ext4 -L nixos /dev/nvme0n1p5
mount /dev/disk/by-label/nixos /mnt && mkdir -p /mnt/boot
mount /dev/disk/by-partuuid/$(cat /proc/device-tree/chosen/asahi,efi-system-partition) /mnt/boot
nixos-generate-config --root /mnt
git clone <private-remote> /mnt/root/nixos && cd /mnt/root/nixos
cp /mnt/etc/nixos/hardware-configuration.nix hosts/mbp/
mkdir -p firmware && cp /mnt/boot/asahi/{all_firmware.tar.gz,kernelcache*} firmware/
git add -f hosts/mbp/hardware-configuration.nix firmware/*
nixos-install --flake .#mbp && reboot

Install: x86

No hardware generation — hosts/pc/hardware-configuration.nix is generic (mounts by label). Boot the NixOS ISO, sudo -i:

parted /dev/nvme0n1 -- mklabel gpt \
  mkpart ESP fat32 1MiB 512MiB set 1 esp on \
  mkpart primary 512MiB 100%
mkfs.fat -F32 -n BOOT /dev/nvme0n1p1
mkfs.ext4 -L nixos    /dev/nvme0n1p2
mount /dev/disk/by-label/nixos /mnt && mkdir -p /mnt/boot && mount /dev/disk/by-label/BOOT /mnt/boot
git clone <private-remote> /mnt/root/nixos && cd /mnt/root/nixos
nixos-install --flake .#pc && reboot

Exotic storage controller won't boot? Add its module to availableKernelModules in hosts/pc/hardware-configuration.nix (nixos-generate-config --show-hardware-config lists it).

After first boot

passwd (ships initialPassword = "changeme"). If you land on a tty instead of Hyprland, change greetd's uwsm start hyprland → Hyprland in common.