# Decisions Architectural and design decisions for Moonset, in reverse chronological order. ## 2026-03-28 – Optional background blur via `image` crate - **Who**: Hekate, Dom - **Why**: Blurred wallpaper as background is a common UX pattern for overlay menus - **Tradeoffs**: Adds `image` crate dependency (~15 transitive crates); CPU-side Gaussian blur at load time adds startup latency proportional to image size and sigma. Acceptable because blur runs once and the texture is shared across monitors. - **How**: `load_background_texture(bg_path, blur_radius)` loads texture, optionally applies `imageops::blur()`, returns `gdk::Texture`. Config option `background_blur: Option` in TOML. ## 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"])`.