nevaforget 906109d666 feat(lock): open the lock screen on the focused monitor
gtklock shows its input form on one monitor, chosen from its own -M
priority list, while niri assigns the lock screen's keyboard focus by
cursor position. Locking from any other monitor left form and focus
apart, so typing went nowhere until the mouse was moved.

moonarch-lock resolves the focused output and passes it as -M. All five
call sites go through it; "$@" is forwarded unchanged, so -d stays the
caller's decision.
2026-09-14 18:41:40 +02:00

Moonarch

Reproducible Arch Linux desktop environment — fully automated from bare metal to a configured Niri (scrollable tiling Wayland) system with Catppuccin Mocha theming.

Moonarch combines archinstall for the base system with post-install automation that handles packages, XDG defaults, system services, greeter, idle management, and a a Quickshell bar that carries the launcher, the notifications and the popouts. The result is a complete development/productivity desktop that can be rebuilt from scratch in minutes.

Why These Choices

Component Choice Why
Compositor Niri Scrollable tiling — no fixed grid, infinite horizontal workspace. Purpose-built Wayland compositor, not an X11 port.
Greeter greetd + ReGreet Minimal, Wayland-native login. ReGreet is a GTK4 greeter from the official repos, running inside its own Niri instance and inheriting the system GTK theme.
Lock Screen gtklock ext-session-lock-v1 through gtk-session-lock — compositor guarantees lock on crash. PAM authentication. Modules add the avatar, clock and power buttons swaylock had no way to show. Background is a blurred copy of the default wallpaper, blurred at build time: GTK3 has no blur and gtklock takes no screenshot.
Power Menu Quickshell popout (PowerPopout.qml) Lock, logout, hibernate, reboot, shutdown; every action except lock needs a second click. Part of the bar, so it needs no own package.
Idle Manager stasis + wayland-pipewire-idle-inhibit Separate AC/battery power plans. Brightness dimming, DPMS, lock (via gtklock), and suspend on configurable timeouts. The companion inhibitor holds a Wayland idle-inhibitor while audio plays — keeps the screen awake during windowed browser video, which stasis' pactl detection skips by design.
Bar Quickshell Composable QML bar shipped as a named config. Own widgets and popouts for audio, network, bluetooth, battery, brightness, CPU governor, camera, clipboard, calendar and power. Also the notification daemon.
Launcher Quickshell popout (LauncherPopout.qml) Application launcher over DesktopEntries, bound to Super+Space. Launches through app2unit so each app gets its own systemd scope. Terminal entries go through app2unit-term, which needs xdg-terminal-exec.
Terminal Foot Fast, minimal Wayland-native terminal. Server mode for instant window spawning.
Shell Zsh Programmable completion, FZF integration, syntax highlighting.
Audio PipeWire Drop-in replacement for PulseAudio/JACK with lower latency. RNNoise input denoising configured out of the box.
Display Management kanshi + wdisplays-persistent kanshi auto-switches output profiles on hotplug. wdisplays-persistent saves changes directly to kanshi config.
Notifications Quickshell NotificationServer Owns org.freedesktop.Notifications; toasts plus a notification popout in the bar. swaync was the previous daemon and was dropped on 2026-09-14.
Clipboard cliphist + quickshell Clipboard history stored in runtime dir, wiped on session start. The quickshell bar provides the picker (Super+C) with search, image thumbnails, and per-entry delete.
GTK Theme catppuccin-mocha-lavender-standard+default Catppuccin Mocha with the Lavender accent, matching Kvantum and the lock screen. Catppuccin's GTK theme is Colloid recolored -- it carries vinceliuice's theme as a submodule -- so the widget shapes are unchanged from before.
Icons Colloid-Grey-Catppuccin-Dark Catppuccin-colored icon set matching the GTK theme.
Cursor Sweet-cursors Visible on dark backgrounds without clashing.
Font UbuntuSans Nerd Font Clean sans-serif with full Nerd Font glyph coverage for bar/terminal icons.
Wallpaper waypaper + awww waypaper provides GUI selection, awww handles animated transitions (60 FPS, 2s crossfade).
Night Light wlsunset Wayland-native blue light filter via wlr-gamma-control. Toggleable from the bar's nightlight indicator.
Firewall UFW Simple deny-incoming/allow-outgoing default. Sane baseline without iptables complexity.
AUR Helper paru Rust-based, pacman-compatible. Supports the custom package repo that ships the moonarch package itself.

Quick Start

Fresh Install (Bare Metal)

  1. Boot the Arch ISO and download the config:
    curl -O https://gitea.moonarch.de/nevaforget/moonarch/raw/branch/main/config/user_configuration.json
    archinstall --config user_configuration.json
    
  2. Choose disk and kernel interactively — everything else comes from the config.
  3. Reboot, log in, then:
    /opt/moonarch/scripts/post-install.sh
    
  4. Reboot again — done.

The archinstall config clones this repo to /opt/moonarch via custom-commands. post-install.sh handles the remaining ~95 packages, all configs, themes, services, and user setup.

Update

moonup   # or: moonarch-update

Interactive updater that upgrades system and AUR packages, reconciles package lists against what's installed, and cleans orphaned packages. Config deployment happens automatically via the moonarch-git package on paru -Syu.

Health Check

moondoc   # or: moonarch-doctor

Diagnostic tool that verifies the system state against moonarch defaults: services, configs, packages, helper scripts, firewall, shell and directory permissions. Reports pass/fail/warn per check with a summary at the end.

Project Structure

config/
  user_configuration.json       archinstall config (locale, audio, services, custom-commands)

packages/
  official.txt                  Arch repo packages (~80), one per line
  aur.txt                       AUR packages (~20), one per line

scripts/
  lib.sh                        Shared helpers sourced by post-install.sh
  post-install.sh               Main automation (packages, configs, themes, services)
  moonarch-update               Interactive updater (deployed to /usr/bin/ as moonup)
  moonarch-doctor               System health checker (deployed to /usr/bin/ as moondoc)

defaults/
  xdg/                          System-wide XDG configs (deployed to /etc/xdg/)
    niri/config.kdl               Compositor: layout, keybinds, startup apps
    quickshell/moonarch/          Bar: widgets, popouts, theme (QML component library)
    foot/foot.ini                 Terminal: font, colors, keybinds
    waybar/, walker/, swaync/     Retired — configs kept, packages no longer installed
    kanshi/config                 Display profiles (empty seed, user-configured via wdisplays)
    stasis/stasis.rune            Idle manager: AC/battery power plans
    pipewire/                     Audio: RNNoise input denoising
    waypaper/config.ini           Wallpaper manager: backend, folder, transitions
    fastfetch/config.jsonc        System info display
    gtk-3.0/, gtk-4.0/           GTK theme settings

  bin/                          Helper scripts (deployed to /usr/bin/)
    moonarch-btnote               Bluetooth device battery monitor (upower + notify-send)
    moonarch-capsnote             Caps Lock toggle notification
    moonarch-waybar-updates       Package update checker (repo + AUR); read by the bar's UpdatesIndicator
    moonarch-batsaver-toggle      Toggle battery charge limit (80% ↔ 100%)
    moonarch-nightlight           Toggle wlsunset blue light filter on/off
    moonarch-camera-list          List cameras with their on/off state
    moonarch-camera-toggle        Switch one camera on or off (via pkexec)
    moonarch-camera-boot          Switch all cameras off (run at boot by moonarch-camera.service)
    moonarch-waybar*              Retired with Waybar — wrapper plus the cpugov/gpustat/hidpp/
                                  batsaver/nightlight module scripts (moonarch-waybar-updates excepted)
    moonarch-sink-switcher        Retired with walker — dmenu helpers with no dmenu left
    moonarch-vpn                    (audio sink, VPN, power profile; the bar's popouts cover all three)
    moonarch-cpugov

  shell/zshrc                   Zsh config: prompt, aliases, FZF, completion
  etc/greetd/                   greetd daemon, greeter Niri config, regreet config + CSS
  etc/systemd/user/             Systemd user services (quickshell, cliphist, kanshi, nautilus, wlsunset)
  etc/systemd/system/           System services (battery conservation restore, camera switch-off on boot)
  backgrounds/wallpaper.jpg     Default wallpaper (shared by desktop, greeter, lock screen)

Startup Sequence

greetd ─► niri (greeter instance) ─► regreet ─► user authenticates
                                                         │
                                                         ▼
                                                   niri (user session)
                                                         │
                                      ┌────────┬──────────┬──────────┐
                                      ▼        ▼          ▼          ▼
                                     foot   waypaper   nm-applet   polkit agent
                                   (server) (wallpaper)  (VPN)       (auth)

                        systemd user services (graphical-session.target):
                        quickshell (bar + notifications), kanshi, cliphist, nautilus, wlsunset

Keybinds (Default)

Key Action
Super+Return Open terminal (foot)
Super+Space App launcher (Quickshell popout)
Super+Q Close window
Super+O / Super+Tab Overview
Super+F Maximize column
Super+Shift+F Fullscreen window
Super+V Toggle floating
Super+H/J/K/L Focus left/down/up/right
Super+Ctrl+H/J/K/L Move window
Super+Shift+H/J/K/L Focus monitor
Super+1-9 Switch workspace
Super+C Clipboard history
Super+E File manager
Super+A Audio control (Quickshell popout)
Super+N Network / VPN (Quickshell popout)
Mod+M Media player (Quickshell popout)
Mod+Escape Session menu (Quickshell popout)
Print Screenshot
Ctrl+Print Screenshot screen
Alt+Print Screenshot window

Customization

All system configs live in /etc/xdg/ and can be overridden per-user in ~/.config/:

Component System Default User Override
Niri /etc/xdg/niri/config.kdl ~/.config/niri/config.kdl (includes system config)
Quickshell /etc/xdg/quickshell/moonarch/ ~/.config/quickshell/moonarch/shell.qml (copy and recompose)
Foot /etc/xdg/foot/foot.ini ~/.config/foot/foot.ini
kanshi /etc/xdg/kanshi/config ~/.config/kanshi/config
PipeWire /etc/xdg/pipewire/ ~/.config/pipewire/
Zsh /etc/zsh/zshrc.moonarch ~/.zshrc + ~/.zshrc.d/

Helper scripts in /usr/bin/moonarch-* are not meant to be overridden — they are part of the system and updated via paru -Syu.

System Services

Service Purpose
greetd Login greeter (runs regreet inside Niri)
NetworkManager Network management (WiFi, VPN, Ethernet)
bluetooth Bluetooth stack (bluez)
systemd-timesyncd NTP time synchronization
ufw Firewall (deny incoming, allow outgoing)
power-profiles-daemon Power profiles over D-Bus (EPP + ACPI platform_profile)

User Services (systemd --user)

Service Purpose
quickshell Bar and notification daemon (restarted on crash)
cliphist Clipboard history (wipes on session start, stores in runtime dir)
kanshi Dynamic display configuration (auto-switch output profiles on hotplug)
nautilus File manager preload (faster first launch)
stasis Idle manager (dimming, DPMS, lock, suspend on AC/battery plans)
wayland-pipewire-idle-inhibit Holds a Wayland idle-inhibitor while audio plays (keeps screen awake for windowed browser video that stasis skips)
wlsunset Blue light filter (off by default; enabled per user)

Moonarch Ecosystem

Moonarch is the deployment and configuration layer. It no longer carries companion programs of its own — the session UI comes from the official repos or from the Quickshell config in this repository:

Was Now
moongreet (greetd greeter) ReGreet, greetd-regreet
moonlock (screen locker) gtklock
moonset (power menu) PowerPopout.qml in the Quickshell config

What remains in the custom package repository is moonarch-git itself plus the cursor theme; the retired projects keep their PKGBUILD directories there, unbuilt, so the way back stays open.

License

MIT

S
Description
No description provided
Readme
1.3 MiB
0 Stars 1 Watchers 0 Forks
Languages
QML 73.7%
Shell 21.4%
CSS 4.7%
Dockerfile 0.2%