feat: initial Moongreet greeter implementation
greetd-Greeter für Wayland mit Python + GTK4 + gtk4-layer-shell. Enthält IPC-Protokoll, User/Session-Erkennung, Power-Actions, komplettes UI-Layout und 36 Tests (Unit + Integration).
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# ABOUTME: Session detection — discovers available Wayland and X11 sessions.
|
||||
# ABOUTME: Parses .desktop files from standard session directories.
|
||||
|
||||
import configparser
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
DEFAULT_WAYLAND_DIRS = [Path("/usr/share/wayland-sessions")]
|
||||
DEFAULT_XSESSION_DIRS = [Path("/usr/share/xsessions")]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Session:
|
||||
"""Represents an available login session."""
|
||||
|
||||
name: str
|
||||
exec_cmd: str
|
||||
session_type: str # "wayland" or "x11"
|
||||
|
||||
|
||||
def _parse_desktop_file(path: Path, session_type: str) -> Session | None:
|
||||
"""Parse a .desktop file and return a Session, or None if invalid."""
|
||||
config = configparser.ConfigParser(interpolation=None)
|
||||
config.read(path)
|
||||
|
||||
section = "Desktop Entry"
|
||||
if not config.has_section(section):
|
||||
return None
|
||||
|
||||
name = config.get(section, "Name", fallback=None)
|
||||
exec_cmd = config.get(section, "Exec", fallback=None)
|
||||
|
||||
if not name or not exec_cmd:
|
||||
return None
|
||||
|
||||
return Session(name=name, exec_cmd=exec_cmd, session_type=session_type)
|
||||
|
||||
|
||||
def get_sessions(
|
||||
wayland_dirs: list[Path] = DEFAULT_WAYLAND_DIRS,
|
||||
xsession_dirs: list[Path] = DEFAULT_XSESSION_DIRS,
|
||||
) -> list[Session]:
|
||||
"""Discover available sessions from .desktop files."""
|
||||
sessions: list[Session] = []
|
||||
|
||||
for directory in wayland_dirs:
|
||||
if not directory.exists():
|
||||
continue
|
||||
for desktop_file in sorted(directory.glob("*.desktop")):
|
||||
session = _parse_desktop_file(desktop_file, "wayland")
|
||||
if session:
|
||||
sessions.append(session)
|
||||
|
||||
for directory in xsession_dirs:
|
||||
if not directory.exists():
|
||||
continue
|
||||
for desktop_file in sorted(directory.glob("*.desktop")):
|
||||
session = _parse_desktop_file(desktop_file, "x11")
|
||||
if session:
|
||||
sessions.append(session)
|
||||
|
||||
return sessions
|
||||
Reference in New Issue
Block a user