# Changelog All notable changes to this project will be documented in this file. Format based on [Keep a Changelog](https://keepachangelog.com/). ## [0.8.0] - 2026-03-30 ### Changed - Replace `canonicalize()` with `symlink_metadata` + `is_file` + `!is_symlink` for avatar lookup — prevents symlink traversal to arbitrary files - Replace `canonicalize()` with same symlink-safe check in `resolve_background_path` - Downscale wallpaper to `MAX_BLUR_DIMENSION` (1920px) before GPU blur — prevents excessive memory use on high-res images - Validate `background_blur` per config source — invalid user value preserves system default instead of silently falling back to 0 ### Fixed - Fix blur padding offset from `(0,0)` to `(-pad,-pad)` to prevent edge darkening on blurred wallpaper ## [0.7.3] - 2026-03-29 ### Fixed - Fix shutdown and reboot — `loginctl` does not support `poweroff`/`reboot` verbs, switched to `systemctl poweroff` and `systemctl reboot` ## [0.7.2] - 2026-03-29 ### Fixed - Fix CSS priority so app styles override GTK4 user theme (Colloid-Catppuccin) — use `STYLE_PROVIDER_PRIORITY_USER` instead of `STYLE_PROVIDER_PRIORITY_APPLICATION` - Replace `border-radius: 50%` with `9999px` — GTK4 CSS does not reliably support percentage-based border-radius ## [0.7.1] - 2026-03-28 ### Fixed - Fix edge darkening on blurred wallpaper — GskBlurNode sampled transparent pixels outside texture bounds, now renders with 3x-sigma padding and crops back ## [0.7.0] - 2026-03-28 ### Added - Blur validation: `background_blur` must be 0.0–200.0 (negative, NaN, infinite, and extreme values are rejected with a warning) - `detect_locale_with()` testable DI function for locale detection (4 new tests) - Path canonicalization for `~/.face` and AccountsService avatar paths (resolves symlinks, prevents passing arbitrary files to gdk-pixbuf) ### Changed - Replace busy-loop polling (`try_wait` + `sleep(100ms)`) in `run_command` with blocking `child.wait()` + timeout thread — eliminates poll latency and thread waste - Move config loading from `activate()` to `main()` — filesystem I/O no longer blocks the GTK main loop - Click-to-dismiss now attached to overlay instead of background picture (works with or without wallpaper) ### Removed - Embedded fallback wallpaper from GResource bundle — moonarch provides `/usr/share/moonarch/wallpaper.jpg` at install time, binary size dropped from ~3.2MB to ~1.3MB - GResource fallback path in `resolve_background_path` — returns `Option` now, `None` falls through to CSS background ## [0.6.0] - 2026-03-28 ### Added - Systemd journal logging (`journalctl -t moonset`) replacing env_logger stderr output - `MOONSET_DEBUG` env var to enable debug-level journal output - Debug logging across all modules (config resolution, wallpaper source, avatar loading, power actions, locale detection, blur cache) - Shared blur cache for multi-monitor — GPU blur computed once, reused by all windows ### Changed - Lock action spawns moonlock as detached process instead of blocking via run_command — moonset can quit immediately while moonlock runs independently ## [0.4.1] - 2026-03-28 ### Added - Fade-in/fade-out animation (250ms ease-in) for panel and wallpaper windows via CSS opacity transition ### Fixed - Fix pixel format mismatch in blur path — `texture.download()` yields BGRA but was passed to `RgbaImage` without channel swap, now explicitly converts B↔R - Logout action now calls `app.quit()` to dismiss the menu immediately (previously only Lock did) - Log TOML parse errors to stderr instead of silently falling back to defaults ### Changed - Replace magic string `"lock"` comparison with `quit_after` field on `ActionDef` for type-safe action dispatch - Remove `compressed="true"` from JPEG wallpaper in GResource — JPEG is already compressed, zlib overhead hurts startup for negligible size savings ## [0.4.0] - 2026-03-28 ### Added - Optional background blur via `background_blur` config option (Gaussian blur, `image` crate) - Disk cache for blurred wallpaper (`~/.cache/moonset/`) — avoids re-blurring on subsequent starts ## [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