Appearance now opens on Themes: light and dark side by side, each remembering its own choice, over galleries of ten shipped themes — Tokyo Moon and Day joined by Moon Rose, Catppuccin, Nord, Gruvbox and Everforest in both modes. A theme is a complete palette: the catalog lives in themes.json, Theme.qml reads every color token from the active record, and one render pipeline carries it to kitty, tmux, btop, GTK, Vicinae, Firefox's chrome, and the lock screen. The Theme editor builds new ones from four wells — wheel, hex, or eyedropper — with derived surfaces, a saturation slider, debounced fine-tune, and effects that save with the theme. Custom edits finally keep GNOME's accent, kitty's border, and hyprlock in sync. Wallpapers can be video: mpvpaper per output, hardware-decoded, muted and looped, supervised and respawned. Panama owns the pausing — games, battery, and a bar pill for right now — because the compositor rebuilds full-screen blur for every frame a video wallpaper draws. The lock screen gets a still frame. Titlebars stop lying. GNOME apps get close-only on your chosen side, the maximize and double-click settings are gone, the Settings window obeys the same rules, and its titlebar can be turned off entirely. Typography becomes five labeled dropdowns instead of a wall of samples. Contracts updated and written throughout (165 now); per the redesign workflow none were executed — the full sweep runs once at the end. Claude-Session: https://claude.ai/code/session_01Ms2FbjQy31TVf3CEvQhGM8
88 lines
8.1 KiB
Markdown
88 lines
8.1 KiB
Markdown
# Settings redesign — deferred test runs
|
|
|
|
No contract is executed while the settings redesign is in flight: many are live
|
|
harnesses that open windows, drive overlays, and run display transactions on
|
|
the real desktop. Everything below runs **once, at the end of the redesign,
|
|
with Gabriel's go-ahead**, and failures get fixed then.
|
|
|
|
## The run
|
|
|
|
- `panama test` — the full suite (165 contracts as of the phase 3 contracts
|
|
wave; the top-level README's count line is set to match and is itself
|
|
checked by `setup/readme-contract`).
|
|
|
|
## Known items to verify or investigate at the end
|
|
|
|
- `quickshell/welcome-contract` — failed once ("the welcome screen did not
|
|
open") during a full-suite run storming the live session; passed in
|
|
isolation minutes earlier after the Welcome.qml comment edit. Suspected
|
|
contention flake, not a regression. Confirm.
|
|
- `setup/readme-contract` — counts contracts; keep the README number in sync
|
|
as later phases add contracts (phase 2 added `phone-page-contract`).
|
|
- Phase 2 additions already written and passing when last run:
|
|
`my-home-settings-contract` (renamed from `home-phone-settings-contract`),
|
|
`phone-page-contract`, extended `home_assistant_bridge_test.py` and
|
|
`kdeconnect_bridge_test.py`.
|
|
- Each later phase (Appearance, …) appends its new/changed contracts here
|
|
instead of running them.
|
|
|
|
## Phase 3 (Appearance) — append below
|
|
|
|
The contracts wave is done. Everything below is written and **still to be
|
|
RUN**. Nothing in this list has been executed against a live harness: the
|
|
static halves were checked against the tree, but every harness run and the
|
|
full-suite pass are deferred to the end-of-redesign sweep.
|
|
|
|
### New contracts (3)
|
|
|
|
| Contract | What it pins |
|
|
|---|---|
|
|
| `quickshell/theme-catalog-contract` | `config/themes.json` shape (10 themes, 6 dark / 4 light), every palette and ansi block accepted by the model's own validators, moon and day byte-identical to the shell's pre-theme literals, `ThemeCatalog.qml`'s embedded fallback carrying both, and `Theme.qml` holding no palette ternary. |
|
|
| `quickshell/video-wallpaper-contract` | Three independent pause reasons (`FocusModes.gameRunning`, `Battery.acOnline` plus the preference, `manuallyPaused`) and pausing over mpv's JSON IPC; the mpvpaper argv (`hwdec=vaapi`, `no-audio`, `loop-file=inf`, `input-ipc-server=`); the hyprpaper stop/start choreography and `Wallpaper.refreshActive()`; `Wallpaper.qml`'s video routing branches; the helper's 60-file cap, depth-2 scan and mp4/mkv/webm filter; the still frame for the lock screen; `WallpaperIndicator` in `Bar.qml`'s right-hand row with its `visible` binding, spoken name and no animation; the two schema keys; the doctor check id. |
|
|
| `quickshell/settings-titlebar-contract` | No minimize or maximize anywhere in the settings chrome (comments may say the words, code may not); `height: shown ? 48 : 0` so hiding collapses rather than leaving a hole; `buttonsLeft` side-awareness with exactly one anchor released per element; the close button's `activeFocusOnTab`, `Accessible.role`/`name`, Return/Space handlers and focus treatment, and that it is the only button; Escape declared on the shell rather than inside the bar; the `panamaTitlebar` schema entry and its Appearance row. |
|
|
|
|
### Updated contracts (6)
|
|
|
|
| Contract | What it now pins |
|
|
|---|---|
|
|
| `quickshell/accent-controls-contract` | Rewritten around the new editor: the nine surviving components and their qmldir lines, `AccentPicker`/`ThemeProfilePicker` staying deleted *and* unregistered, the four wells and their single `apply()` path, one hyprpicker invocation aimed by a remembered target, `ColorWell`'s hex validation committing on Enter and focus-out but never per keystroke, the six HSV labels, the debounce (the write lives in `commitTimer`, `changeChannel` writes nothing, `releaseTimer` hands the sliders back), `commitActive` recomputing `accentName` through `nearestCuratedName` with `selectProfile`/`updateActive` both routing into it, `Theme.qml` reading `ThemeProfiles.activePalette`, the Themes and Theme editor tabs, four search labels, and the no-animation ban extended over all nine components. Live half rewritten against the rebuilt harness. |
|
|
| `quickshell/theme-profiles-contract` | Node half rebuilt for the optional-field model: `shippedProfiles()` with no argument still returns the three built-in fallbacks (back-compat), the ten catalog records survive with palettes and ansi and no effects, palette/ansi/effects survive a stored record with per-key effect clamping, an invalid palette drops the FIELD not the profile, the caller's shipped list owns the id and name space, `editProfile` passes untouched fields through and a shipped fork carries the whole palette, `nearestCuratedName` mappings (mauve→orchid, gruvbox-yellow→amber, grey→slate, per scheme), and `derivePalette`/`resaturatePalette`/`deriveAnsi`/`mixHex` producing palettes the validators accept. Live half now pins the per-mode selection flow: a light/dark flip returns to the theme chosen on that side, never a forced default. |
|
|
| `quickshell/desktop-style-contract` | `titlebarMaximizeButton` and `titlebarDoubleClick` asserted **gone** from the schema and from `DesktopStyle`, along with `action-double-click-titlebar`; `panamaTitlebar` added (bool, def true, group titlebar); the button layout pinned close-only on both sides with `minimize`/`maximize` banned from the function body; the Appearance greps moved to Fonts/Sizes/Rendering with exactly five `FontPicker` rows and their five role labels, plus the honest-titlebar subtitle. |
|
|
| `quickshell/settings-ownership-contract` | The ColorScheme block was pinning `inactiveBorderDark`/`inactiveBorderLight`, which no longer exist. It now pins the inactive border as the active theme's `gutter`, bans a regrown literal, pins the accent border roles through the new `hyprColor(value, alpha)` signature, requires both roles to be restated on a theme change, and cross-checks Hyprland's startup literals against moon's and day's gutters in `themes.json`. |
|
|
| `quickshell/lock-screen-settings-contract` | The "between Background and Shell typography" ordering check named a card that no longer exists. It now pins Background → Video playback → Lock screen order, and that all three sit on the Background tab. |
|
|
| `quickshell/settings-search-contract` | Seven fixed cases added for the new surface: themes, theme editor, dark mode, Catppuccin, Gruvbox, video wallpaper, titlebar. The schema-label sweep already covers the new keys automatically. |
|
|
|
|
### Verified against the new tree, no edit needed
|
|
|
|
- `quickshell/settings-hardcoded-values-contract` — its scope is `Settings.qml`,
|
|
which the theme work did not touch; `Theme.qml`'s literals are covered by
|
|
`theme-catalog-contract` instead.
|
|
- `quickshell/wallpaper-service-contract` — already carries the video routing
|
|
greps.
|
|
- `quickshell/wallpaper-settings-contract`, `wallpaper-policy-contract`,
|
|
`settings-nav-contract`, `settings-pages-contract`, `manual-contract`,
|
|
`settings-docs-contract`, `qmldir-registration-contract`,
|
|
`settings-sync-contract`, `settings-backup-contract` — checked, nothing stale.
|
|
- `quickshell/panama-doctor-contract` — already lists `input.video-wallpaper`.
|
|
|
|
### Docs updated in the same wave
|
|
|
|
- `modules/settings/README.md` — new **Appearance** section (Themes, Theme
|
|
editor, backgrounds still and moving, the honest titlebar); the border
|
|
ownership paragraph corrected to the theme's gutter.
|
|
- `manual/05-making-it-yours.md` — rewritten Appearance chapter: the two
|
|
galleries, per-mode memory, the four-well editor, video wallpapers, and why
|
|
there is no minimize.
|
|
- Top-level `README.md` — contract count 162 → 165, confirmed by
|
|
`setup/readme-contract`.
|
|
|
|
### Still open before the run
|
|
|
|
- The parallel pipeline wave's files (`gtk-theme-contract`,
|
|
`lock-screen-theme-contract`, `palette-contract`, the two bridge tests) are
|
|
not counted above. If that wave adds contracts, the README count line and the
|
|
count in this file both need bumping again before the suite runs.
|
|
- `AppearancePage.qml`'s `tab` property defaults to `"background"` while its
|
|
own comment says Themes leads. Decide which is intended before the run;
|
|
nothing currently pins it either way.
|