diff --git a/config/dot/quickshell/modules/notifications/NotificationCard.qml b/config/dot/quickshell/modules/notifications/NotificationCard.qml index e3c9134..966ed8d 100644 --- a/config/dot/quickshell/modules/notifications/NotificationCard.qml +++ b/config/dot/quickshell/modules/notifications/NotificationCard.qml @@ -146,10 +146,10 @@ Rectangle { id: settingsMenu anchorItem: settingsMenuButton + // A Column already measures itself from its children, and in Qt 6 both + // implicit sizes are read-only on a positioner -- assigning them makes + // the whole shell fail to load rather than just this menu. Column { - implicitWidth: notificationSettings.implicitWidth - implicitHeight: notificationSettings.implicitHeight - TrayMenuRow { id: notificationSettings label: "Notification settings" diff --git a/docs/superpowers/plans/2026-08-18-roadmap-completion.md b/docs/superpowers/plans/2026-08-18-roadmap-completion.md index b9124ff..1f5a32e 100644 --- a/docs/superpowers/plans/2026-08-18-roadmap-completion.md +++ b/docs/superpowers/plans/2026-08-18-roadmap-completion.md @@ -33,22 +33,22 @@ - Modify: `config/dot/quickshell/scripts/panama-lock` - Modify: `config/dot/quickshell/services/Wallpaper.qml` - Modify: `config/dot/quickshell/modules/settings/WallpaperControls.qml` -- Test: `tests/quickshell/settings-ownership-contract.sh` -- Test: `tests/quickshell/display-transaction-contract.sh` -- Test: `tests/quickshell/lock-screen-helper-contract.sh` -- Test: `tests/quickshell/wallpaper-service-contract.sh` -- Test: `tests/quickshell/wallpaper-settings-contract.sh` +- Test: `tests/quickshell/settings-ownership-contract` +- Test: `tests/quickshell/display-transaction-contract` +- Test: `tests/quickshell/lock-screen-helper-contract` +- Test: `tests/quickshell/wallpaper-service-contract` +- Test: `tests/quickshell/wallpaper-settings-contract` **Interfaces:** - Produces: `Displays.primaryFirstMonitors`, event-driven topology refresh, and a lock helper that never emits an unreadable image. - Consumes: current `Theme.accent`, `Theme.accentSecondary`, display transaction rollback, and wallpaper preference schema. - [ ] Add failing ownership assertions that active borders derive from `Theme.accent` and `Theme.accentSecondary`, while inactive borders derive only from scheme roles; verify the current contract fails for the stale prohibition. -- [ ] Update the ownership implementation comments and documentation, then run `bash tests/quickshell/settings-ownership-contract.sh` and verify PASS. +- [ ] Update the ownership implementation comments and documentation, then run `bash tests/quickshell/settings-ownership-contract` and verify PASS. - [ ] Add a failing display fixture that changes the harness screen model without calling the display service’s public `refresh()` and expects topology reconciliation plus rollback of a pending transaction. -- [ ] Add an event-driven screen-model observer and primary-first derived monitor list; run `bash tests/quickshell/display-transaction-contract.sh` and `bash tests/quickshell/display-layout-contract.sh`. +- [ ] Add an event-driven screen-model observer and primary-first derived monitor list; run `bash tests/quickshell/display-transaction-contract` and `bash tests/quickshell/display-layout-contract`. - [ ] Add failing lock fixtures for missing global and per-monitor wallpapers, requiring readable shipped-image fallback and screenshot fallback when no image exists. -- [ ] Tighten `panama-lock` path validation and bounded warnings; run `bash tests/quickshell/lock-screen-helper-contract.sh`. +- [ ] Tighten `panama-lock` path validation and bounded warnings; run `bash tests/quickshell/lock-screen-helper-contract`. - [ ] Add failing wallpaper contracts for primary-first output order, selection preservation, and a HOME path containing a single quote. - [ ] Replace inline `bash -lc` path interpolation with an argument-safe helper and update controls to preserve selection; run both wallpaper contracts. - [ ] Run the Task 1 contract set and commit with message `Close desktop safety gaps`. @@ -62,8 +62,8 @@ - Modify: `config/dot/quickshell/modules/osd/Osd.qml` - Modify: `config/dot/quickshell/modules/overview/WindowThumbnail.qml` - Modify: `config/dot/quickshell/services/ShellState.qml` -- Test: `tests/quickshell/settings-jump-contract.sh` -- Create or modify: `tests/quickshell/overview-thumbnail-contract.sh` +- Test: `tests/quickshell/settings-jump-contract` +- Create or modify: `tests/quickshell/overview-thumbnail-contract` **Interfaces:** - Produces: one route per configurable surface into the existing owning Settings page. @@ -87,9 +87,9 @@ - Modify: `config/dot/quickshell/modules/settings/AppearancePage.qml` - Modify: `config/dot/quickshell/services/ColorScheme.qml` - Modify: `config/dot/quickshell/services/SettingsSearch.qml` -- Test: create `tests/quickshell/theme-profiles-contract.sh` -- Test: create `tests/quickshell/accent-controls-contract.sh` -- Test: modify `tests/quickshell/control-center-contract.sh` +- Test: create `tests/quickshell/theme-profiles-contract` +- Test: create `tests/quickshell/accent-controls-contract` +- Test: modify `tests/quickshell/control-center-contract` **Interfaces:** - Produces: profile records `{id,name,scheme,accent,secondary,shipped}` and reactive `Theme` colour roles. @@ -110,8 +110,8 @@ - Modify: `config/dot/quickshell/services/ColorScheme.qml` - Modify: tracked kitty/tmux/Vicinae/Wofi/Neovim include points as required - Create: generated-file templates or helpers under the owning application directories -- Test: create `tests/quickshell/theme-apps-accent-contract.sh` -- Test: modify `tests/quickshell/gtk-theme-contract.sh` if its invocation contract changes +- Test: create `tests/quickshell/theme-apps-accent-contract` +- Test: modify `tests/quickshell/gtk-theme-contract` if its invocation contract changes **Interfaces:** - Produces: `panama-theme-apps dark|light [#RRGGBB #RRGGBB]` with per-adapter JSON status. @@ -138,10 +138,10 @@ - Create: `config/dot/quickshell/scripts/panama-generate-docs` - Create: `docs/SETTINGS.md` - Create: `docs/SHORTCUTS.md` -- Test: create `tests/quickshell/first-run-contract.sh` -- Test: modify `tests/quickshell/settings-backup-live-contract.sh` -- Test: create `tests/quickshell/generated-docs-contract.sh` -- Test: modify `tests/quickshell/keybind-rebind-contract.sh` +- Test: create `tests/quickshell/first-run-contract` +- Test: modify `tests/quickshell/settings-backup-live-contract` +- Test: create `tests/quickshell/generated-docs-contract` +- Test: modify `tests/quickshell/keybind-rebind-contract` **Interfaces:** - Produces: fresh-install marker lifecycle, `snapshot --cause ` retention, and deterministic generated Markdown. diff --git a/tests/quickshell/accent-controls-contract.sh b/tests/quickshell/accent-controls-contract similarity index 92% rename from tests/quickshell/accent-controls-contract.sh rename to tests/quickshell/accent-controls-contract index 9dc9108..ef0fa96 100755 --- a/tests/quickshell/accent-controls-contract.sh +++ b/tests/quickshell/accent-controls-contract @@ -49,7 +49,14 @@ for target in 'Pick primary from screen' 'Pick secondary from screen'; do || fail "screen picker action is missing $target" done -rg -Fq 'model: Object.keys(Theme.accents)' "$settings/AccentPicker.qml" \ +# The curated swatches come from the accentName schema rather than from +# Object.keys(Theme.accents): the schema's option order is the palette's order, +# and it is the same source every other enum row reads. What matters here is +# unchanged -- the curated accents are still one click away, ahead of the +# editor. +rg -Fq 'PreferenceSchema.spec("accentName")' "$settings/AccentPicker.qml" \ + || fail 'curated swatches are no longer sourced from the accent schema' +rg -Fq 'model: root.options' "$settings/AccentPicker.qml" \ || fail 'curated swatches are no longer the fast path' rg -Fq 'ThemeProfiles.useCuratedAccent(entry.modelData)' "$settings/AccentPicker.qml" \ || fail 'curated swatches do not select a profile-backed accent' diff --git a/tests/quickshell/displays-contract b/tests/quickshell/displays-contract index 6ea3364..52e7915 100755 --- a/tests/quickshell/displays-contract +++ b/tests/quickshell/displays-contract @@ -54,7 +54,11 @@ rg -Fq 'options: Displays.scalesForMode(' "$page" \ || fail 'scale choices are not filtered for the active resolution' rg -Fq 'property string selectedOutput:' "$page" \ || fail 'connected outputs cannot be selected' -rg -Fq 'options: Displays.monitors.map(' "$page" \ +# primaryFirstMonitors is monitors sorted with the primary first, so the +# selector is still populated from what is connected -- which is what this +# protects. Naming the sorted list rather than the raw one is the point: the +# picker should open on the display somebody is most likely to mean. +rg -Fq 'options: Displays.primaryFirstMonitors.map(' "$page" \ || fail 'the output selector is not populated from connected displays' rg -Fq 'id: revertVerifyTimer' "$service" \ || fail 'automatic restoration has no bounded readback verification' diff --git a/tests/quickshell/osd-ui-contract b/tests/quickshell/osd-ui-contract index b600846..dc2119e 100755 --- a/tests/quickshell/osd-ui-contract +++ b/tests/quickshell/osd-ui-contract @@ -33,7 +33,20 @@ rg -Fq 'WlrLayershell.namespace: "qs-popover-osd"' "$osd" \ || fail 'OSD does not use the existing Prism blur namespace' rg -Fq 'WlrLayershell.keyboardFocus: WlrKeyboardFocus.None' "$osd" \ || fail 'OSD may steal keyboard focus' -rg -Fq 'mask: Region {}' "$osd" || fail 'OSD may intercept pointer input' +# The OSD used to take no pointer input at all. It now takes some, because a +# secondary click on a visible OSD opens its settings and dismisses it -- and a +# Wayland input region cannot be told to admit one button and not another, so +# the feature is not available without a region. +# +# What still has to hold is that the region is BOUNDED to the OSD's own surface +# rather than the screen. The OSD floats over whatever is underneath for a +# couple of seconds; a region larger than the card would swallow clicks meant +# for a window nobody could see was being covered. +rg -Fq 'mask: Region {' "$osd" || fail 'OSD declares no input region at all' +rg -Fq 'item: inputMask' "$osd" \ + || fail 'the OSD input region is not bound to an item, so it may cover more than the OSD itself' +rg -Fq 'anchors.fill: parent' "$osd" \ + || fail 'the OSD input mask does not track the surface it belongs to' rg -Fq 'PrismEdge {' "$osd" || fail 'OSD is missing the Prism signature edge' rg -Fq 'font.features: Theme.tabularFigures' "$osd" \ || fail 'changing percentages do not use tabular figures' diff --git a/tests/quickshell/overview-thumbnail-contract.sh b/tests/quickshell/overview-thumbnail-contract similarity index 100% rename from tests/quickshell/overview-thumbnail-contract.sh rename to tests/quickshell/overview-thumbnail-contract diff --git a/tests/quickshell/theme-profiles-contract.sh b/tests/quickshell/theme-profiles-contract similarity index 100% rename from tests/quickshell/theme-profiles-contract.sh rename to tests/quickshell/theme-profiles-contract