# Moonarch Reproduzierbares Arch-Linux-Setup basierend auf archinstall + Post-Install-Automatisierung. ## Projektstruktur - `config/` — archinstall-Konfiguration (inkl. custom-commands die das Repo nach /opt/moonarch klonen, root-owned) - `scripts/` — Post-Install- und Helper-Scripts - `packages/` — Paketlisten (offiziell + AUR), getrennt gepflegt - `defaults/` — XDG-Configs, Shell-Config, Helper-Binaries, systemd Services, udev-Regeln, greetd/moongreet-Config, Wallpaper ## Battery Conservation Mode Laptops mit `charge_control_end_threshold`-Support (ThinkPad, Framework, etc.) erhalten einen Waybar-Toggle: - Klick auf das Battery-Modul schaltet zwischen 80% und 100% Ladegrenze um - Bei aktiver Conservation erscheint ein ♥-Icon neben der Battery-Anzeige - Zustand wird in `/var/lib/moonarch/batsaver-threshold` persistiert und beim Boot via systemd-Service (`moonarch-batsaver-restore`) wiederhergestellt - Toggle-Flow: `moonarch-batsaver-toggle` (User-Script) liest sysfs, entscheidet 80↔100, ruft `pkexec /usr/bin/moonarch-batsaver-apply $NEW` für den privilegierten sysfs+state-Schreibschritt. Standard-pkexec-Prompt (Passwort einmal pro Session-Cache) - Auf Desktops ohne Battery-Support versteckt sich das Feature komplett ## Nightlight (Blaufilter) Waybar-Toggle für wlsunset (Wayland-nativer Blaufilter), persistenter Zustand via systemd: - `wlsunset.service` (systemd User-Service) mit `After=kanshi.service` — startet erst wenn alle Outputs konfiguriert sind - **Default OFF** — frische Installs starten ohne Filter. PKGBUILD legt für `wlsunset` bewusst KEINEN Symlink in `/etc/systemd/user/graphical-session.target.wants/` an, post-install.sh enabled den Service nicht. - Klick auf das Nightlight-Modul in `group/brightness` toggled wlsunset an/aus (`enable --now` / `disable --now`) - Zustand überlebt Reboots (User-Scope-Symlink in `~/.config/systemd/user/...wants/`) - Aktiver Zustand zeigt 󰌵 in Catppuccin Yellow, inaktiv 󰌶 in Standard-Textfarbe - Signal SIGRTMIN+11 für sofortiges Waybar-Refresh - Scripts: `moonarch-nightlight` (Toggle), `moonarch-waybar-nightlight` (Status-JSON) - **Wichtig**: Auf gar keinen Fall einen Global-Scope-Symlink in `/etc/systemd/user/...wants/wlsunset.service` anlegen — der überstimmt jedes User-`disable` und macht den Filter de-facto unausschaltbar. ## Waybar Config Merger (moonarch-waybar) Waybar wird über `moonarch-waybar` gestartet (nicht direkt). Der Wrapper merged eine optionale User-Config (`~/.config/waybar/userconfig`) mit der System-Config (`/etc/xdg/waybar/config`): - `prepend`/`append`-Keys in der userconfig erweitern `modules-left`/`modules-center`/`modules-right` Arrays - Alle anderen Top-Level-Keys werden als Modul-Definitionen per Object-Merge eingefügt - Merge wird nur bei Änderungen ausgeführt (Timestamp-Vergleich) - Bei Fehler: `notify-send` + `logger`, Waybar startet mit System-Config - Generiert `~/.config/waybar/style.css` mit `@import` der System-Styles falls nicht vorhanden - Benötigt `jq` (in PKGBUILD als Dependency) - System-Config muss valides JSON sein (kein JSONC) ## mpv + ModernZ OSC Videoplayer ist `mpv` mit [ModernZ](https://github.com/Samillion/ModernZ) als OSC, Thumbnails via thumbfast: - `mpv-modernz-git` liefert `modernz.lua` + Font + Default-Config nach `/etc/mpv/` - `mpv-thumbfast-git` liefert `thumbfast.lua` nach `/etc/mpv/scripts/` (wird von ModernZ automatisch erkannt) - `defaults/etc/mpv/mpv.conf` wird von moonarch-git direkt nach `/etc/mpv/mpv.conf` installiert (owned) - Stock-OSC + Titelleiste deaktiviert, `autofit-larger=80%x80%` cappt übergroße Fenster - ModernZ-Overrides per `script-opts-append` in mpv.conf: Orange-Akzent → Catppuccin Lavender (`#b4befe`), OSC-Scale 0.75, `window_title_font_size=18`, `ontop_button=no` - **Wichtig**: mpv behandelt `#` als Mid-Line-Kommentar; Hex-Farben müssen gequotet werden: `script-opts-append="modernz-seekbarfg_color=#b4befe"` (nicht `\#`, das escaped nur und verschluckt den Rest) - Niri öffnet mpv floating (`window-rule` in `defaults/xdg/niri/config.kdl`) ## System Health Check (moonarch-doctor / moondoc) Diagnose-Script das den Systemzustand gegen moonarch-Defaults prüft: - Pakete (official.txt + aur.txt installiert? Orphans?) - System-Services (NetworkManager, bluetooth, greetd, ufw, auto-cpufreq, etc.) - User-Services (kanshi, wlsunset, stasis, walker, nautilus, cliphist-text, cliphist-image) - Config-Dateien (SHA256-Vergleich deployed vs. moonarch-Default) - Helper-Scripts + Symlinks (moonup, moondoc) - System-Config (UFW, Pacman/Paru Repos, Default Shell) - Verzeichnisse + Permissions ## Fontconfig Defaults Systemweite generic-family Defaults via `defaults/etc/fonts/conf.d/65-moonarch-fonts.conf` (owned by moonarch-git): - `sans-serif` → UbuntuSans Nerd Font, `monospace` → UbuntuSansMono Nerd Font - Nummer **65**: lädt nach `60-latin.conf`, sodass die moonarch-Prefs den Stock-Default (Noto/DejaVu) schlagen. `local.conf` (bei 51 via `51-local.conf`) lädt zu früh und wird von 60-latin überstimmt — daher **nicht** verwenden (außerdem für lokale User-Overrides reserviert). - Aliases brauchen `binding="strong"` — ein weak `` (fontconfig-Default) rankt hinter dem effektiven generischen Fallback und greift nicht. - Greift nur für Apps die generische Familien nutzen (z.B. Firefox-Web-Fallback). moonarch-Apps (Waybar, foot, GTK, walker, swaync) setzen den Font explizit. ## Browser Idle-Inhibit (xdg-desktop-portal) Damit Fenster-Browservideo (Firefox/Waterfox) den Screen wachhält, via `defaults/etc/xdg-desktop-portal/niri-portals.conf` (owned by moonarch-git, höhere Priorität als niris `/usr/share/xdg-desktop-portal/niri-portals.conf`): - `xdg-desktop-portal-gtk` meldet das `Inhibit`-Interface als success, obwohl es unter Niri niemand implementiert → Firefox glaubt, der Idle-Inhibit lief über den Portal, und nutzt den nativen Wayland-`idle-inhibit` nicht. Ergebnis: kein Inhibitor, Screen schläft. - Fix: `org.freedesktop.impl.portal.Inhibit=none` → Firefox fällt auf `zwp_idle_inhibit` zurück, den Niri honoriert. Die übrigen `[preferred]`-Zeilen sind 1:1 von niris Default übernommen (portals.conf wird nicht gemerged — die höchstpriore Datei gilt komplett). - stasis ist hier unbeteiligt: `monitor_media` (pactl) erfasst Browser-Audio per Design nicht (nur Non-Browser-Player); Browser laufen über den Inhibit-Pfad. - **Aktivierung:** xdg-desktop-portal + Browser neu starten — Firefox fragt den Portal-Support beim Start ab. ## Konventionen - Paketlisten sind einfache Textdateien, ein Paket pro Zeile, Kommentare mit `#` - Shell-Scripts müssen POSIX-kompatibel oder explizit bash/zsh sein - Alle Pfade im archinstall-Config relativ zum Installationsziel