Compare commits

...

6 Commits

Author SHA1 Message Date
nevaforget ba4f30f254 fix: Niri-Greeter-Config mit Retry-Loop gegen offene Session bei Crash
Wenn moongreet crasht bevor Niri bereit ist, blieb eine offene
Niri-Session als greeter-User zurueck. Retry-Loop stellt sicher,
dass niri sich in jedem Fall beendet. Beispiel-Configs korrigiert
(moongreet braucht Niri als Compositor).
2026-03-26 14:29:49 +01:00
nevaforget e37b273913 fix: Display-Null-Check und File-Logging in main.py
Gdk.Display.get_default() kann None zurueckgeben wenn der Compositor
noch nicht bereit ist. Vorher crashte moongreet mit TypeError, ohne
dass der Fehler irgendwo geloggt wurde. Display wird jetzt einmal
geholt, geprueft und an _register_icons/_load_css durchgereicht.
Logging geht nach /var/cache/moongreet/moongreet.log und stderr.
2026-03-26 14:16:38 +01:00
nevaforget ecd89f5b10 Simplify pkgver() to require tags 2026-03-26 14:02:38 +01:00
nevaforget d089fa201c fix: Build-Artefakte aus Repo entfernt, .gitignore ergänzt
makepkg-Artefakte (pkg/src, pkg/pkg, .pkg.tar.zst) waren
versehentlich committed. Entfernt und per .gitignore geschützt.
2026-03-26 13:44:07 +01:00
nevaforget 6400270a50 fix: PKGBUILD compositor-agnostisch, Beispiel-Configs bereinigt
Moongreet ist ein reiner GTK4-Greeter ohne eigenen Compositor.
niri-greeter.kdl entfernt — der User konfiguriert seinen
Compositor selbst (regreet → moongreet tauschen).
2026-03-26 13:38:27 +01:00
nevaforget 10b613b50b fix: PKGBUILD als -git Paket mit automatischer Versionierung
pkgver() generiert Version aus git describe, makepkg -si
aktualisiert automatisch ohne manuelles Version-Bumpen.
2026-03-26 13:30:36 +01:00
6 changed files with 127 additions and 19 deletions
+6
View File
@@ -8,3 +8,9 @@ build/
.pytest_cache/ .pytest_cache/
.pyright/ .pyright/
*.egg *.egg
# makepkg build artifacts
pkg/src/
pkg/pkg/
pkg/*.pkg.tar*
pkg/greetd-moongreet/
+3 -1
View File
@@ -5,5 +5,7 @@
vt = 1 vt = 1
[default_session] [default_session]
command = "moongreet" # Moongreet braucht einen Wayland-Compositor — niri stellt diesen bereit.
# Siehe niri-greeter.kdl fuer die Compositor-Konfiguration.
command = "niri -c /etc/greetd/niri-greeter.kdl"
user = "greeter" user = "greeter"
+59
View File
@@ -0,0 +1,59 @@
// ABOUTME: Niri-Konfiguration fuer den Moongreet Login-Greeter.
// ABOUTME: Wird von greetd gestartet — minimale Config ohne Keybinds fuer Sicherheit.
input {
keyboard {
xkb {
layout "de"
}
numlock
}
touchpad {
tap
natural-scroll
}
mouse {
accel-profile "flat"
}
}
cursor {
xcursor-theme "Sweet-cursors"
}
layout {
gaps 0
focus-ring {
off
}
border {
off
}
}
// Moongreet starten und niri beenden, sobald moongreet sich schliesst.
// Retry-Loop stellt sicher, dass niri auch bei fruehen Crashes von moongreet beendet wird.
spawn-sh-at-startup "moongreet; while ! niri msg action quit --skip-confirmation 2>/dev/null; do sleep 0.5; done"
// Greeter-Fenster maximiert darstellen
window-rule {
open-maximized true
}
hotkey-overlay {
skip-at-startup
}
prefer-no-csd
animations {
off
}
binds {
// Keine Keybinds — verhindert Zugriff auf Terminals oder andere Aktionen
}
+12 -5
View File
@@ -1,9 +1,9 @@
# ABOUTME: AUR PKGBUILD for Moongreet — greetd greeter for Wayland. # ABOUTME: PKGBUILD for Moongreet — greetd greeter for Wayland.
# ABOUTME: Builds from git source, installs config and cache directory. # ABOUTME: Builds from git source with automatic version detection.
# Maintainer: Dominik Kressler # Maintainer: Dominik Kressler
pkgname=moongreet pkgname=moongreet-git
pkgver=0.1.0 pkgver=0.1.0
pkgrel=1 pkgrel=1
pkgdesc="A greetd greeter for Wayland, built with Python + GTK4 + gtk4-layer-shell" pkgdesc="A greetd greeter for Wayland, built with Python + GTK4 + gtk4-layer-shell"
@@ -23,10 +23,17 @@ makedepends=(
'python-installer' 'python-installer'
'python-hatchling' 'python-hatchling'
) )
provides=('moongreet')
conflicts=('moongreet')
install=moongreet.install install=moongreet.install
source=("git+${url}.git#tag=v${pkgver}") source=("git+${url}.git")
sha256sums=('SKIP') sha256sums=('SKIP')
pkgver() {
cd "$srcdir/greetd-moongreet"
git describe --long --tags | sed 's/^v//;s/-/.r/;s/-/./'
}
build() { build() {
cd "$srcdir/greetd-moongreet" cd "$srcdir/greetd-moongreet"
python -m build --wheel --no-isolation python -m build --wheel --no-isolation
@@ -36,7 +43,7 @@ package() {
cd "$srcdir/greetd-moongreet" cd "$srcdir/greetd-moongreet"
python -m installer --destdir="$pkgdir" dist/*.whl python -m installer --destdir="$pkgdir" dist/*.whl
# Example config # Greeter config
install -Dm644 config/moongreet.toml "$pkgdir/etc/moongreet/moongreet.toml" install -Dm644 config/moongreet.toml "$pkgdir/etc/moongreet/moongreet.toml"
# Cache directory # Cache directory
+4 -6
View File
@@ -1,16 +1,14 @@
# ABOUTME: pacman install hooks for Moongreet. # ABOUTME: pacman install hooks for Moongreet.
# ABOUTME: Sets ownership on cache directory for the greeter user. # ABOUTME: Sets ownership on cache directory and prints setup instructions.
post_install() { post_install() {
if getent passwd greeter > /dev/null 2>&1; then if getent passwd greeter > /dev/null 2>&1; then
chown greeter:greeter /var/cache/moongreet chown greeter:greeter /var/cache/moongreet
fi fi
echo "==> Copy /etc/moongreet/moongreet.toml and adjust the wallpaper path." echo "==> Moongreet installed."
echo "==> Configure greetd to use moongreet:" echo "==> Add moongreet to your greeter compositor command in /etc/greetd/config.toml."
echo " [default_session]" echo "==> Adjust wallpaper: /etc/moongreet/moongreet.toml"
echo " command = \"moongreet\""
echo " user = \"greeter\""
} }
post_upgrade() { post_upgrade() {
+43 -7
View File
@@ -4,6 +4,7 @@
import logging import logging
import sys import sys
from importlib.resources import files from importlib.resources import files
from pathlib import Path
import gi import gi
gi.require_version("Gtk", "4.0") gi.require_version("Gtk", "4.0")
@@ -21,9 +22,38 @@ try:
except (ValueError, ImportError): except (ValueError, ImportError):
HAS_LAYER_SHELL = False HAS_LAYER_SHELL = False
LOG_DIR = Path("/var/cache/moongreet")
LOG_FILE = LOG_DIR / "moongreet.log"
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def _setup_logging() -> None:
"""Configure logging to file and stderr."""
root = logging.getLogger()
root.setLevel(logging.DEBUG)
formatter = logging.Formatter(
"%(asctime)s %(levelname)s %(name)s: %(message)s"
)
# Always log to stderr
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setLevel(logging.DEBUG)
stderr_handler.setFormatter(formatter)
root.addHandler(stderr_handler)
# Log to file if the directory is writable
if LOG_DIR.is_dir():
try:
file_handler = logging.FileHandler(LOG_FILE)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
root.addHandler(file_handler)
except PermissionError:
logger.warning("Cannot write to %s", LOG_FILE)
class MoongreetApp(Gtk.Application): class MoongreetApp(Gtk.Application):
"""GTK Application for the Moongreet greeter.""" """GTK Application for the Moongreet greeter."""
@@ -34,14 +64,18 @@ class MoongreetApp(Gtk.Application):
def do_activate(self) -> None: def do_activate(self) -> None:
"""Create and present greeter windows on all monitors.""" """Create and present greeter windows on all monitors."""
self._register_icons() display = Gdk.Display.get_default()
self._load_css() if display is None:
logger.error("No display available — cannot start greeter UI")
return
self._register_icons(display)
self._load_css(display)
# Resolve wallpaper once, share across all windows # Resolve wallpaper once, share across all windows
config = load_config() config = load_config()
bg_path, self._wallpaper_ctx = resolve_wallpaper_path(config) bg_path, self._wallpaper_ctx = resolve_wallpaper_path(config)
display = Gdk.Display.get_default()
monitors = display.get_monitors() monitors = display.get_monitors()
primary_monitor = None primary_monitor = None
@@ -81,19 +115,19 @@ class MoongreetApp(Gtk.Application):
self._wallpaper_ctx = None self._wallpaper_ctx = None
Gtk.Application.do_shutdown(self) Gtk.Application.do_shutdown(self)
def _register_icons(self) -> None: def _register_icons(self, display: Gdk.Display) -> None:
"""Register custom icons from the package data/icons directory.""" """Register custom icons from the package data/icons directory."""
icons_dir = files("moongreet") / "data" / "icons" icons_dir = files("moongreet") / "data" / "icons"
icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default()) icon_theme = Gtk.IconTheme.get_for_display(display)
icon_theme.add_search_path(str(icons_dir)) icon_theme.add_search_path(str(icons_dir))
def _load_css(self) -> None: def _load_css(self, display: Gdk.Display) -> None:
"""Load the CSS stylesheet for the greeter.""" """Load the CSS stylesheet for the greeter."""
css_provider = Gtk.CssProvider() css_provider = Gtk.CssProvider()
css_path = files("moongreet") / "style.css" css_path = files("moongreet") / "style.css"
css_provider.load_from_path(str(css_path)) css_provider.load_from_path(str(css_path))
Gtk.StyleContext.add_provider_for_display( Gtk.StyleContext.add_provider_for_display(
Gdk.Display.get_default(), display,
css_provider, css_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION,
) )
@@ -118,6 +152,8 @@ class MoongreetApp(Gtk.Application):
def main() -> None: def main() -> None:
"""Run the Moongreet application.""" """Run the Moongreet application."""
_setup_logging()
logger.info("Moongreet starting")
app = MoongreetApp() app = MoongreetApp()
app.run(sys.argv) app.run(sys.argv)