Build the Panama Hyprland desktop

This commit is contained in:
Gabriel Brown
2026-08-17 10:32:55 -04:00
parent 67033f2a31
commit 5248883e4b
190 changed files with 18554 additions and 34 deletions
@@ -0,0 +1,128 @@
# Panama Settings Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Build the approved Luminous System Settings control center and map it to `Super+I` while preserving GNOME Settings as a launcher-accessible fallback.
**Architecture:** A persisted `DesktopPreferences` singleton owns user choices, `SystemSettings` owns allow-listed system reads and writes, and a normal tiled Settings window renders focused pages over those boundaries. Existing shell consumers continue through `Settings.qml`, while `ShellState` and typed IPC own window routing.
**Tech Stack:** Quickshell 0.3.0, Qt 6 QML, Quickshell Io and PipeWire, Hyprland 0.56 Lua configuration, systemd, Bash integration contracts
**Spec:** `docs/superpowers/specs/2026-08-17-panama-settings-design.md`
## Global Constraints
- Use Tokyo Night Moon tokens and the existing Prism edge; no component-local color literals.
- Apply only allow-listed Hyprland numeric settings; never execute UI-provided shell text.
- Do not expose full-time desktop HDR without tested automatic rollback.
- Do not continuously poll or animate while idle.
- Preserve GNOME Settings as an installed, searchable fallback.
- Keep unrelated pre-existing Panama changes untouched.
---
### Task 1: Persisted desktop preferences
**Files:**
- Create: `config/dot/quickshell/config/DesktopPreferences.qml`
- Modify: `config/dot/quickshell/config/Settings.qml`
- Test: `tests/quickshell/settings-preferences-contract.sh`
**Interfaces:**
- Produces: writable `use24Hour`, `showSeconds`, `showWeekday`, `showCpu`, `showMemory`, `showGpu`, `dockAutohide`, `dockRevealDelayMs`, `dockHideDelayMs`, `focusDurationMinutes`, `autoHdr`, `vrrPolicy`, `directScanoutPolicy`, and `lastPage` properties plus `resetDesktopDefaults(): void`.
- Consumes: `Quickshell.stateDir`, `FileView`, and `JsonAdapter`.
- [x] Write a standalone Quickshell contract that changes clock, dock, and display-policy values in a disposable state directory, restarts the harness, and asserts the literal values survive.
- [x] Run the contract and verify it fails because `DesktopPreferences` does not exist.
- [x] Implement the JSON adapter and bind dynamic `Settings.qml` values to it.
- [x] Run the persistence contract and the existing focus/dock consumers to green.
### Task 2: Allow-listed system boundary
**Files:**
- Create: `config/dot/quickshell/services/SystemSettings.qml`
- Test: `tests/quickshell/settings-system-contract.sh`
**Interfaces:**
- Consumes: `DesktopPreferences`, `NightLight`, `Notifs`, `Caffeine`, `hyprctl`, `systemctl`, and `pgrep`.
- Produces: monitor identity and geometry, display-policy setters, bounded `refresh(): void`, service status, `openGnomePanel(panel: string): void`, `openApplication(id: string): void`, and an inline `lastError`.
- [x] Write an IPC-backed contract that applies current policy values, refreshes the active monitor, and rejects an unsupported GNOME panel.
- [x] Run it and verify the `settings-system` diagnostics target is absent.
- [x] Implement fixed-command processes and strict numeric/panel allow lists.
- [x] Run the contract and confirm the live compositor returns to its original values.
### Task 3: Luminous window and core pages
**Files:**
- Create: `config/dot/quickshell/modules/settings/SettingsWindow.qml`
- Create: `config/dot/quickshell/modules/settings/SettingsShell.qml`
- Create: `config/dot/quickshell/modules/settings/SettingsSidebar.qml`
- Create: `config/dot/quickshell/modules/settings/SettingsCard.qml`
- Create: `config/dot/quickshell/modules/settings/SettingRow.qml`
- Create: `config/dot/quickshell/modules/settings/SettingsToggle.qml`
- Create: `config/dot/quickshell/modules/settings/HomePage.qml`
- Create: `config/dot/quickshell/modules/settings/AppearancePage.qml`
- Create: `config/dot/quickshell/modules/settings/DisplaysPage.qml`
- Create: `config/dot/quickshell/modules/settings/DesktopPage.qml`
- Create: `config/dot/quickshell/modules/settings/qmldir`
- Test: `tests/quickshell/settings-window-contract.sh`
**Interfaces:**
- Consumes: `DesktopPreferences`, `SystemSettings`, `NightLight`, and `ShellState.settingsPage`.
- Produces: a tiled `Panama Settings` window with Home, Appearance, Displays, and Desktop pages.
- [x] Write a live contract that opens the window to each core page and verifies one `Panama Settings` toplevel remains mapped.
- [x] Run it and verify the `settings` IPC target is absent.
- [x] Implement the two-pane Luminous shell and reusable row/card controls.
- [x] Implement real preference, Night Light, HDR policy, VRR, direct-scanout, clock, vitals, and dock controls.
- [x] Run the page contract and inspect Quickshell logs for construction warnings.
### Task 4: System pages and fallback handoffs
**Files:**
- Create: `config/dot/quickshell/modules/settings/SoundPage.qml`
- Create: `config/dot/quickshell/modules/settings/NotificationsPage.qml`
- Create: `config/dot/quickshell/modules/settings/ShortcutsPage.qml`
- Create: `config/dot/quickshell/modules/settings/ServicesPage.qml`
- Create: `config/dot/quickshell/modules/settings/AboutPage.qml`
- Modify: `config/dot/quickshell/modules/settings/SettingsShell.qml`
- Test: `tests/quickshell/settings-pages-contract.sh`
**Interfaces:**
- Consumes: existing PipeWire controls, `Notifs`, `FocusSession`, service status from Task 2, and fixed GNOME panel handoffs.
- Produces: Sound, Notifications & Focus, Shortcuts, Startup & Services, and About destinations.
- [x] Extend the page contract with search routing, live DND/focus changes, audio construction, service refresh, and GNOME fallback command validation.
- [x] Run it and verify the new page names fail before implementation.
- [x] Build the five pages using the same row/card vocabulary and no inactive fake controls.
- [x] Run contracts and verify absent optional services render as unavailable.
### Task 5: Shell, keybinding, launcher, and compositor integration
**Files:**
- Modify: `config/dot/quickshell/services/ShellState.qml`
- Modify: `config/dot/quickshell/shell.qml`
- Modify: `config/dot/hypr/keybinds.lua`
- Modify: `config/dot/hypr/rules.lua`
- Create: `config/local/share/applications/panama-settings.desktop`
- Modify: `setup/scripts/link-dotfiles`
- Modify: `README.md`
- Modify: `config/dot/hypr/README.md`
**Interfaces:**
- Produces: `ShellState.settingsOpen`, `settingsPage`, typed `settings` and `settings-system` IPC targets, `Super+I`, and a searchable desktop entry.
- [x] Extend the live contract to open, close, toggle, and route directly to a named page.
- [x] Wire the Settings window and IPC handlers into the shell.
- [x] Replace the GNOME Settings `Super+I` command with Panama IPC while retaining the GNOME desktop entry.
- [x] Let the titled window participate in the active Hyprland tiling layout.
- [x] Link the Panama desktop entry into `~/.local/share/applications` and refresh the launcher cache.
### Task 6: Full-system verification
- [x] Run every Quickshell contract, `Hyprland --verify-config`, and desktop-file validation.
- [x] Reload Hyprland, restart Quickshell, and inspect fresh logs for errors or warnings.
- [x] Exercise Home, Displays, Desktop, Sound, Notifications, Services, shortcut search, and a GNOME handoff.
- [x] Capture Home, Displays, Desktop, and Services pages for visual review.
- [x] Inspect the exact Panama diff and confirm unrelated pre-existing changes were preserved.