4cd73a430b
- _on_realize implementiert (war nur connected, nicht definiert) - do_unrealize für as_file() Context-Manager-Cleanup - threading.Lock für _greetd_sock Race Condition - TOML-Parsing-Fehler abfangen statt Crash - last-user Datei: Längen- und Zeichenvalidierung - detect_locale: non-alpha LANG-Werte abweisen - exec_cmd Plausibility-Check mit shutil.which - Exception-Details ins Log statt in die UI - subprocess.run Timeout für Power-Actions - Sequence[Path] statt tuple[Path, ...] in get_sessions - Mock-Server _recvall für fragmentierte Reads - [behavior]-Config-Sektion entfernt (unimplementiert) - Design Decisions in CLAUDE.md dokumentiert
64 lines
1.9 KiB
Python
64 lines
1.9 KiB
Python
# ABOUTME: Session detection — discovers available Wayland and X11 sessions.
|
|
# ABOUTME: Parses .desktop files from standard session directories.
|
|
|
|
import configparser
|
|
from collections.abc import Sequence
|
|
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: Sequence[Path] = DEFAULT_WAYLAND_DIRS,
|
|
xsession_dirs: Sequence[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
|