All checks were successful
Update PKGBUILD version / update-pkgver (push) Successful in 2s
GTK4 under greetd does not honour XCURSOR_THEME reliably — the env-prefix hack in /etc/greetd/config.toml only reached the wlroots pointer in cage, while GTK widgets kept using the default fallback cursor. Mirror the existing gtk-theme handling: new cursor-theme + cursor-size fields in the [appearance] section, applied via gtk::Settings::set_gtk_cursor_theme_*. Keeps the fix scoped to the greeter, no system-wide GTK config changes.
5.4 KiB
5.4 KiB
Moongreet
Projekt
Moongreet ist ein greetd-Greeter für Wayland, gebaut mit Rust + gtk4-rs + gtk4-layer-shell. Teil des Moonarch-Ökosystems.
Tech-Stack
- Rust (Edition 2024), gtk4-rs 0.11, glib 0.22
- gtk4-layer-shell 0.8 für Wayland Layer Shell (TOP Layer)
- greetd IPC über Unix Domain Socket (length-prefixed JSON)
cargo testfür Unit-Tests
Projektstruktur
src/— Rust-Quellcode (main.rs, greeter.rs, ipc.rs, config.rs, users.rs, sessions.rs, i18n.rs, power.rs)resources/— GResource-Assets (style.css, default-avatar.svg)config/— Beispiel-Konfigurationsdateien für/etc/moongreet/und/etc/greetd/pkg/— PKGBUILD für Arch-Linux-Paketierung (makepkg -sf)
Kommandos
# Tests ausführen
cargo test
# Release-Build
cargo build --release
# Greeter im Fenster starten (ohne greetd/Layer Shell)
MOONGREET_NO_LAYER_SHELL=1 ./target/release/moongreet
# Paket bauen und installieren
cd pkg && makepkg -sf && sudo pacman -U moongreet-git-<version>-x86_64.pkg.tar.zst
Architektur
ipc.rs— greetd Socket-Kommunikation (4-byte LE header + JSON)users.rs— Benutzer aus /etc/passwd, Avatare (AccountsService + ~/.face), Symlink-Rejectionsessions.rs— Wayland/X11 Sessions aus .desktop Filespower.rs— Reboot/Shutdown via loginctli18n.rs— Locale-Erkennung (LANG / /etc/locale.conf) und String-Tabellen (DE/EN), alle UI- und Login-Fehlermeldungenfingerprint.rs— fprintd D-Bus Probe (gio::DBusProxy) — Geräteerkennung und Enrollment-Check für UI-Feedbackconfig.rs— TOML-Config ([appearance] background, gtk-theme, cursor-theme, cursor-size, fingerprint-enabled) + Wallpaper-Fallback + Blur-Validierung (finite, clamp 0–200) + Cursor-Size-Validierung (range 1–256)greeter.rs— GTK4 UI (Overlay-Layout), Login-Flow via greetd IPC (Multi-Stage-Auth für fprintd), Faillock-Warnung, Avatar-Cache, Last-User/Last-Session Persistence (0o700 Dirs, 0o600 Files). Zweite Funktioncreate_wallpaper_window()für Sekundär-Monitore (Background only, keine Widgets)main.rs— Entry Point, GTK App, Layer Shell Setup, Multi-Monitor mit Hotplug viaitems-changedauf Monitor-ListModel. Built-in display (viapick_primary_monitor_index) zeigt das Login-Widget mitKeyboardMode::Exclusive, alle anderen Monitore (inkl. Hotplug) zeigen nur Wallpaper mitKeyboardMode::None. Systemd-journal-logger.resources/style.css— Catppuccin-inspiriertes Theme
Design Decisions
- TOP Layer statt OVERLAY: Greeter läuft unter greetd, nicht über Waybar
- GResource-Bundle: CSS, Wallpaper und Default-Avatar sind in die Binary kompiliert
- Async Login:
glib::spawn_future_local+gio::spawn_blockingstatt raw Threads - Socket-Cancellation:
Arc<Mutex<Option<UnixStream>>>+AtomicBoolfür saubere Abbrüche - Avatar-Cache:
HashMap<String, gdk::Texture>inRc<RefCell<GreeterState>> - GPU-Blur via GskBlurNode:
Snapshot::push_blur()+GskRenderer::render_texture()imconnect_realizeCallback — kein CPU-Blur, kein Disk-Cache, keinimage-Crate. Blurred Texture wird perRc<RefCell<Option<gdk::Texture>>>über alle Monitore gecacht (1x GPU-Renderpass statt N). - Fingerprint via greetd Multi-Stage PAM: fprintd D-Bus nur als Probe (Gerät/Enrollment), eigentliche Verifizierung läuft über PAM im greetd-Auth-Loop.
auth_message_type: "secret"→ Passwort, alles andere →None(PAM entscheidet). 60s Socket-Timeout bei fprintd. Device-Proxy inGreeterStategecacht, Generation-Counter gegen Race Conditions bei schnellem User-Switch. - Symmetrie mit moonlock/moonset: Gleiche Patterns (i18n, config, users, power, GResource, GPU-Blur)
- Session-Validierung: Relative Pfade erlaubt (greetd löst PATH auf), nur
../Null-Bytes werden abgelehnt - GTK-Theme-Validierung: Nur alphanumerisch +
_-+.erlaubt, verhindert Path-Traversal über Config - Cursor-Theme via GtkSettings: GTK4 unter greetd liest
XCURSOR_THEMEenv nicht zuverlässig — Cursor wird viagtk::Settings::set_gtk_cursor_theme_name()gesetzt, analog zugtk-theme. Gleiche Validierung (is_valid_gtk_theme) gegen Path-Traversal. - Journal-Logging:
systemd-journal-loggerstatt File-Logging —journalctl -t moongreet, Debug-Level perMOONGREET_DEBUGEnv-Var - File Permissions: Cache-Verzeichnisse 0o700 via
DirBuilder::mode(), Cache-Dateien 0o600 - Testbare Persistence:
save_*_to/load_*_fromVarianten mit konfigurierbarem Pfad für Unit-Tests - Shared Wallpaper Texture:
gdk::Texturewird einmal inload_background_texture()dekodiert und per Ref-Count an alle Fenster geteilt — vermeidet redundante JPEG-Dekodierung pro Monitor - Wallpaper-Validierung: GResource-Zweig via
resources_lookup_data()+from_bytes()(kein Abort bei fehlendem Pfad), Dateigröße-Limit 50 MB, non-UTF-8-Pfade →None - Error-Detail-Filterung: GDK/greetd-Fehlerdetails nur auf
debug!-Level,warn!ohne interne Details — verhindert Systeminfo-Leak ins Journal - Single Greeter UI, Wallpaper auf Sekundären: Login-Widget nur auf dem Built-in-Panel, andere Monitore bekommen
create_wallpaper_window()mitKeyboardMode::None. Grund: Niri (und andere Compositor) scopen Layer-Shell Keyboard-Routing per Output — ein einziges Exclusive-Surface auf dem "falschen" Output verhindert nicht, dass Keys woanders versanden. Compositor-agnostisch, kein Niri-IPC.