# 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