feat(window): restore window position on X11

X11 sessions now persist and restore the window position (window_x/y) in
addition to size. Gated to X11: Wayland's xdg-shell gives clients no way
to self-position, so we center there (and iced never emits Moved on
Wayland, so window_x/y stay None). No drift across save/restore — iced's
Moved event and Position::Specific both use the window's outer position.

Also confirmed peerspeak already runs on X11 out of the box (winit
compiles both backends and auto-selects via WAYLAND_DISPLAY/DISPLAY) and
documented X11/Wayland support in FEATURES.md.

- config: window_x/window_y: Option<i32> (serde-default None).
- app: is_wayland() + pure initial_window_position() helper; a Moved
  handler records position; the close path persists it.
- tests: +3 initial_window_position (X11 restore / Wayland centers /
  partial-or-missing centers), +2 config (round-trip incl. negative
  coords; backward-compat load without the new fields). 130 -> 135 lib.

Verified live on X11/XWayland: saved an off-center position, the window
reopened there (not centered). clippy clean incl. --all-targets.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-13 16:51:22 -04:00
co-authored by Claude Opus 4.8
parent 45cea799ec
commit c888c30c08
3 changed files with 133 additions and 8 deletions
+10
View File
@@ -122,6 +122,16 @@ covers internals). When you ship a feature, add it here.
|---|---|---|
| Config file | ✅ | `~/.config/peerspeak/config.json`. |
| Backward-compatible loading | ✅ | serde `default`s fill missing fields; unknown fields tolerated. |
| Window size restored | ✅ | `window_width`/`window_height`, saved on close. |
| Window position restored | ✅ | `window_x`/`window_y`, saved on close. **X11 only** — see Platform support. |
## Platform support (Linux desktop)
| Concern | Status | Notes |
|---|---|---|
| Wayland | ✅ | Default on this dev box; winit's Wayland backend. App/taskbar icon comes from the `.desktop` file matched by `application_id = "peerspeak"`. |
| X11 (incl. XWayland) | ✅ | winit's X11 backend (both backends compile in by default; winit auto-selects — Wayland if `WAYLAND_DISPLAY` is set, else X11 via `DISPLAY`). Launch verified rendering on X11. The embedded RGBA window icon (`from_rgba`) is honored on X11 even without the `.desktop` installed. |
| Window position restore | X11 only | Wayland's xdg-shell gives clients no way to place their own window, so we center there. On X11 the saved `window_x`/`window_y` is restored via `Position::Specific` (outer position; no drift across save/restore — iced's `Moved` and `Position::Specific` both use the outer position). Verified live on X11 (saved an off-center position; the window reopened there, not centered). Gated by `is_wayland()` (`src/app/mod.rs`); decision logic unit-tested (`initial_window_position`). |
---