moonset/DECISIONS.md
nevaforget 71670eb263 feat: switch to systemd-journal-logger, add debug logging (v0.6.0)
Replace env_logger with systemd-journal-logger for consistent logging
across moonset/moonlock/moongreet. Add MOONSET_DEBUG env var and debug
statements across all modules. Also includes shared blur cache for
multi-monitor and detached moonlock spawn for lock action.
2026-03-28 22:58:25 +01:00

5.1 KiB
Raw Blame History

Decisions

Architectural and design decisions for Moonset, in reverse chronological order.

2026-03-28 Switch from env_logger to systemd-journal-logger

  • Who: Ragnar, Dom
  • Why: moonlock and moongreet already use systemd-journal-logger. moonset used env_logger which writes to stderr — not useful for a GUI app launched via keybind. Journal integration enables journalctl -t moonset and consistent troubleshooting across all three Moon projects.
  • Tradeoffs: Requires systemd at runtime. Graceful fallback to eprintln if journal logger fails. Acceptable since Moonarch targets systemd-based Arch Linux.
  • How: Replace env_logger dep with systemd-journal-logger, add setup_logging() with MOONSET_DEBUG env var for debug-level output. Same pattern as moonlock/moongreet.

2026-03-28 Replace action name dispatch with quit_after field

  • Who: Hekate, Dom
  • Why: Post-action behavior (quit the app or not) was controlled by comparing action_name == "lock" — a magic string duplicated from the action definition. Renaming an action would silently break the dispatch.
  • Tradeoffs: Adds a field to ActionDef that most actions set to false. Acceptable because it makes the contract explicit and testable.
  • How: ActionDef.quit_after: booltrue for lock and logout, false for hibernate/reboot/shutdown.

2026-03-28 GPU blur via GskBlurNode replaces CPU blur

  • Who: Ragnar, Dom
  • Why: CPU-side Gaussian blur (image crate) blocked startup and added caching complexity. moonlock already migrated to GPU blur.
  • Tradeoffs: GPU blur quality is slightly different (box-blur approximation vs true Gaussian), acceptable for wallpaper backgrounds. Removes image crate dependency entirely. No disk cache needed.
  • How: Snapshot::push_blur() + GskRenderer::render_texture() on connect_realize. Blur happens once on the GPU when the widget gets its renderer. Symmetric with moonlock and moongreet.

2026-03-28 Use absolute paths for system binaries

  • Who: Hekate, Dom
  • Why: Security audit flagged PATH hijacking risk — relative binary names allow a malicious $PATH entry to intercept systemctl, loginctl, etc.
  • Tradeoffs: Hardcoded paths reduce portability to non-Arch distros where binaries may live elsewhere (e.g. /sbin/). Acceptable because Moonarch targets Arch Linux exclusively.
  • How: All five power action wrappers now use /usr/bin/ prefixed paths.

2026-03-28 Implement power action timeout via try_wait polling

  • Who: Hekate, Dom
  • Why: POWER_TIMEOUT and PowerError::Timeout were declared but never wired up. A hanging systemctl hibernate (e.g. blocked NFS mount) would freeze the power menu indefinitely.
  • Tradeoffs: Polling with try_wait() + 100ms sleep is slightly less efficient than a dedicated timeout crate, but avoids adding a dependency for a single use case.
  • How: run_command now polls child.try_wait() against a 30s deadline, kills the child on timeout.

2026-03-28 Centralize GRESOURCE_PREFIX

  • Who: Hekate, Dom
  • Why: The string /dev/moonarch/moonset was duplicated in config.rs, users.rs, and as literal strings in panel.rs and main.rs. Changing the application ID would require edits in 4+ locations.
  • Tradeoffs: Modules now depend on crate::GRESOURCE_PREFIX — tighter coupling to main.rs, but acceptable for an internal constant.
  • How: Single pub(crate) const GRESOURCE_PREFIX in main.rs, referenced everywhere else.

2026-03-28 Remove journal.md

  • Who: Hekate, Dom
  • Why: One-time development notes from the Rust rewrite, never updated after initial session. Overlapped with memory system and git history.
  • Tradeoffs: Historical context lost from the file, but the information is preserved in git history and the memory system.
  • How: Deleted. Useful technical learnings migrated to persistent memory.

2026-03-27 OVERLAY layer instead of TOP

  • Who: Hekate, Dom
  • Why: Waybar occupies the TOP layer. The power menu must appear above it.
  • Tradeoffs: OVERLAY is the highest layer — nothing can render above moonset while it's open. This is intentional for a session power menu.
  • How: setup_layer_shell uses gtk4_layer_shell::Layer::Overlay for the panel window.

2026-03-27 Lock without confirmation

  • Who: Hekate, Dom
  • Why: Lock is immediately reversible (just unlock). All other actions (logout, hibernate, reboot, shutdown) are destructive or disruptive.
  • Tradeoffs: One less click for the most common action. Risk of accidental lock is negligible since unlocking is trivial.
  • How: ActionDef.needs_confirm = false for lock; all others require inline confirmation.

2026-03-27 Niri-specific logout via niri msg action quit

  • Who: Hekate, Dom
  • Why: Moonarch is built exclusively for the Niri compositor. Generic Wayland logout mechanisms don't exist — each compositor has its own.
  • Tradeoffs: Hard dependency on Niri. If the compositor changes, power::logout() must be updated.
  • How: Command::new("/usr/bin/niri").args(["msg", "action", "quit"]).