Files
moonset/CLAUDE.md
T
nevaforget 115cfe6bb1 docs: translate CLAUDE.md to English
Per the committed=English rule.
2026-06-16 10:46:13 +02:00

2.4 KiB

Moonset

Project

Moonset is a Wayland session power menu, built with Rust + gtk4-rs + gtk4-layer-shell. Part of the Moonarch ecosystem. A keybind-invoked overlay with 5 actions: Lock, Logout, Hibernate, Reboot, Shutdown.

Tech Stack

  • Rust (edition 2024), gtk4-rs 0.11, glib 0.22
  • gtk4-layer-shell 0.8 for the Wayland Layer Shell (OVERLAY layer)
  • cargo test for unit tests

Project Structure

  • src/ — Rust source code (main.rs, power.rs, i18n.rs, config.rs, users.rs, panel.rs)
  • resources/ — GResource assets (style.css, default-avatar.svg)
  • config/ — example configuration files

Commands

# Run tests
cargo test

# Release build
cargo build --release

# Start the power menu (in a Niri session)
LD_PRELOAD=/usr/lib/libgtk4-layer-shell.so ./target/release/moonset

Architecture

  • main.rs — entry point, GTK app, Layer Shell setup, multi-monitor, systemd journal logging, debug level via the MOONSET_DEBUG env var, central GRESOURCE_PREFIX constant
  • power.rs — 5 power-action wrappers with absolute paths and a 30s timeout (lock, logout, hibernate, reboot, shutdown)
  • i18n.rs — locale detection and string tables (DE/EN)
  • config.rs — TOML config + wallpaper fallback
  • panel.rs — GTK4 UI (action buttons, inline confirmation, WallpaperWindow)
  • users.rs — user detection, avatar loading (AccountsService, ~/.face, GResource fallback)
  • resources/style.css — GTK theme colors for consistency with the active desktop theme

Design Decisions

See DECISIONS.md for the full decision log.

Summary of the most important decisions:

  • OVERLAY instead of TOP layer: Waybar sits on TOP, moonset must be above it
  • Niri-specific logout (niri msg action quit): Moonarch commits firmly to Niri
  • Single launch per keybind: no daemon, the GTK application_id prevents double launch
  • System icons: Adwaita/Catppuccin provide all required symbolic icons
  • Lock without confirmation: lock is immediately reversible, needs no confirm
  • Absolute paths for binaries: /usr/bin/systemctl etc. instead of relative paths (security)
  • GResource bundle: CSS and default avatar are compiled into the binary (the wallpaper comes from the filesystem)
  • Async power actions: glib::spawn_future_local + gio::spawn_blocking with a 30s timeout
  • Journal logging: systemd-journal-logger instead of file logging — journalctl -t moonset, debug level via the MOONSET_DEBUG env var