docs: add CHANGELOG.md, DECISIONS.md, bump version to 0.1.1
Add CHANGELOG documenting all changes since 0.1.0 and the initial release. Add DECISIONS.md as an architectural decision log. Update CLAUDE.md to reflect current architecture. Bump to 0.1.1 for the security and correctness fixes in the previous commit.
This commit is contained in:
parent
496a7a4c72
commit
473bed479a
38
CHANGELOG.md
Normal file
38
CHANGELOG.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
Format based on [Keep a Changelog](https://keepachangelog.com/).
|
||||
|
||||
## [0.1.1] - 2026-03-28
|
||||
|
||||
### Fixed
|
||||
|
||||
- Use absolute paths for all system binaries (`systemctl`, `loginctl`, `niri`, `moonlock`) to prevent PATH hijacking
|
||||
- Implement `POWER_TIMEOUT` (30s) via `try_wait()` polling — previously declared but unused, leaving power actions able to block indefinitely
|
||||
- Prevent panic in `load_background_texture` when GResource path contains non-UTF-8 bytes — now falls back to known wallpaper resource
|
||||
- Fix fallback user UID from `0` (root) to `u32::MAX` as a safe sentinel value
|
||||
- Fix CSS comment incorrectly describing circular buttons as "square card"
|
||||
|
||||
### Changed
|
||||
|
||||
- Compress wallpaper in GResource bundle (`compressed="true"`) to reduce binary size
|
||||
- Merge double `idle_add_local_once` into single idle cycle for faster keyboard focus on launch
|
||||
- Centralize `GRESOURCE_PREFIX` as `pub(crate) const` in `main.rs` (was duplicated in `config.rs`, `users.rs`, and literal strings in `panel.rs`)
|
||||
- Translate README.md and config comments from German to English
|
||||
- Remove stale `journal.md` (one-time development notes, not actively maintained)
|
||||
|
||||
## [0.1.0] - 2026-03-27
|
||||
|
||||
### Added
|
||||
|
||||
- Rust rewrite of the Python power menu (gtk4-rs + gtk4-layer-shell)
|
||||
- 5 power actions: Lock, Logout, Hibernate, Reboot, Shutdown
|
||||
- Inline confirmation for destructive actions (all except Lock)
|
||||
- Multi-monitor wallpaper support via shared `gdk::Texture`
|
||||
- DE/EN localization with automatic locale detection
|
||||
- TOML configuration for custom wallpaper path
|
||||
- GResource bundle for CSS, wallpaper, and default avatar
|
||||
- Async power actions via `glib::spawn_future_local` + `gio::spawn_blocking`
|
||||
- Async avatar loading (file-based avatars decoded off UI thread)
|
||||
- Cached icon loading at startup
|
||||
- 45 unit tests
|
||||
18
CLAUDE.md
18
CLAUDE.md
@ -17,7 +17,7 @@ Lock, Logout, Hibernate, Reboot, Shutdown.
|
||||
## Projektstruktur
|
||||
|
||||
- `src/` — Rust-Quellcode (main.rs, power.rs, i18n.rs, config.rs, users.rs, panel.rs)
|
||||
- `resources/` — GResource-Assets (style.css, wallpaper.jpg, default-avatar.svg)
|
||||
- `resources/` — GResource-Assets (style.css, wallpaper.jpg komprimiert, default-avatar.svg)
|
||||
- `config/` — Beispiel-Konfigurationsdateien
|
||||
|
||||
## Kommandos
|
||||
@ -35,20 +35,24 @@ LD_PRELOAD=/usr/lib/libgtk4-layer-shell.so ./target/release/moonset
|
||||
|
||||
## Architektur
|
||||
|
||||
- `power.rs` — 5 Power-Action-Wrapper (lock, logout, hibernate, reboot, shutdown)
|
||||
- `main.rs` — Entry Point, GTK App, Layer Shell Setup, Multi-Monitor, zentrale `GRESOURCE_PREFIX`-Konstante
|
||||
- `power.rs` — 5 Power-Action-Wrapper mit absoluten Pfaden und 30s Timeout (lock, logout, hibernate, reboot, shutdown)
|
||||
- `i18n.rs` — Locale-Erkennung und String-Tabellen (DE/EN)
|
||||
- `config.rs` — TOML-Config + Wallpaper-Fallback
|
||||
- `panel.rs` — GTK4 UI (Action-Buttons, Inline-Confirmation, WallpaperWindow)
|
||||
- `main.rs` — Entry Point, GTK App, Layer Shell Setup, Multi-Monitor
|
||||
- `resources/style.css` — Catppuccin Mocha Theme (aus Python-Version übernommen)
|
||||
- `users.rs` — User-Erkennung, Avatar-Loading (AccountsService, ~/.face, GResource-Fallback)
|
||||
- `resources/style.css` — GTK-Theme-Colors für Konsistenz mit dem aktiven Desktop-Theme
|
||||
|
||||
## Design Decisions
|
||||
|
||||
Siehe `DECISIONS.md` für das vollständige Entscheidungsprotokoll.
|
||||
|
||||
Kurzfassung der wichtigsten Entscheidungen:
|
||||
- **OVERLAY statt TOP Layer**: Waybar liegt auf TOP, moonset muss darüber
|
||||
- **Niri-spezifischer Logout** (`niri msg action quit`): Moonarch setzt fest auf Niri
|
||||
- **Einmal-Start per Keybind**: Kein Daemon, GTK `application_id` verhindert Doppelstart
|
||||
- **System-Icons**: Adwaita/Catppuccin liefern alle benötigten symbolischen Icons
|
||||
- **Lock ohne Confirmation**: Lock ist sofort reversibel, braucht kein Confirm
|
||||
- **Icon-Scaling**: 22px Theme-Variante laden, auf 64px skalieren via GdkPixbuf
|
||||
- **GResource-Bundle**: CSS, Wallpaper und Default-Avatar sind in die Binary kompiliert
|
||||
- **Async Power Actions**: `glib::spawn_future_local` + `gio::spawn_blocking` statt raw Threads
|
||||
- **Absolute Pfade für Binaries**: `/usr/bin/systemctl` etc. statt relativer Pfade (Security)
|
||||
- **GResource-Bundle**: CSS, Wallpaper (komprimiert) und Default-Avatar sind in die Binary kompiliert
|
||||
- **Async Power Actions**: `glib::spawn_future_local` + `gio::spawn_blocking` mit 30s Timeout
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "moonset"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
edition = "2024"
|
||||
description = "Wayland session power menu with GTK4 and Layer Shell"
|
||||
license = "MIT"
|
||||
|
||||
52
DECISIONS.md
Normal file
52
DECISIONS.md
Normal file
@ -0,0 +1,52 @@
|
||||
# Decisions
|
||||
|
||||
Architectural and design decisions for Moonset, in reverse chronological order.
|
||||
|
||||
## 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"])`.
|
||||
Loading…
x
Reference in New Issue
Block a user