Finish threading the accent colour through the whole desktop

The recent accent-colour setting only reached part of the desktop.
looks.lua still hardcoded the focused-window border and glow to blue,
so any hyprctl reload -- or every fresh session, for about a second --
reverted a chosen accent; it now reads accentName the same way it
already read colorScheme. The lock screen and terminal stayed blue
regardless of the chosen accent despite the setting's own description
claiming otherwise; panama-lock and panama-theme-apps now resolve and
apply the real accent.

AccentPicker built its swatch model from Theme.accents directly
instead of the schema's own options list, so the two could drift
silently; switched it to read the schema. Its hit target only covered
the swatch, not the name label added specifically for colour-vision
accessibility -- extended to the whole row. Settings search had no
route for the "appearance" group, so searching for the accent or
colour scheme landed on Home.

ColorScheme's hex-to-Hyprland helper assumed 6-digit colours and would
silently corrupt a future translucent one; fixed it to read from the
end of the string instead of the start. An accent-only change no
longer reruns the full colour-scheme pipeline. The gradient it builds
for the focused border now goes through SystemSettings' existing
serialiser instead of a second, under-escaped copy of the same logic.

The settings-ownership contract test enforced the old rule that
ColorScheme must never touch the focused border; updated it to verify
the real, intended rule instead of contradicting the code.

Claude-Session: https://claude.ai/code/session_01E6TJUAh41HaP25MVHWkhRZ
This commit is contained in:
Gabriel Brown
2026-08-18 21:23:16 -04:00
parent 8b59b78d9f
commit 9ba224d776
9 changed files with 301 additions and 83 deletions
@@ -20,23 +20,45 @@ Flow {
readonly property string current: DesktopPreferences.get("accentName") || "blue"
// The schema's own option list, not Theme.accents directly -- two lists
// hand-kept in sync is how they drift. This is the same pattern
// ChoiceRow.qml uses for every other enum row.
readonly property var spec: PreferenceSchema.spec("accentName")
readonly property var options: root.spec && root.spec.options ? root.spec.options : []
Repeater {
// Object key order is insertion order here, so the palette's own order
// is what the user sees; blue first because it is what Panama ships.
model: Object.keys(Theme.accents)
// The schema's option order is the palette's order, so blue is first
// because it is what Panama ships.
model: root.options
Column {
id: entry
required property var modelData
readonly property var pair: Theme.accents[entry.modelData]
readonly property bool selected: entry.modelData === root.current
readonly property string name: entry.modelData.value
readonly property var pair: Theme.accents[entry.name]
readonly property bool selected: entry.name === root.current
readonly property color start: Theme.dark ? entry.pair.dark : entry.pair.light
readonly property color end: Theme.dark ? entry.pair.darkSecondary : entry.pair.lightSecondary
spacing: 5
// The hit target is the whole swatch+label unit, not just the
// 46px circle: the label exists specifically so someone with a
// colour vision deficiency can identify an accent without it, and
// a label that cannot itself be tapped defeats that.
HoverHandler {
cursorShape: Qt.PointingHandCursor
}
TapHandler {
onTapped: {
if (!SystemSettings.commitPreference("accentName", entry.name))
console.warn("AccentPicker: commitPreference rejected accent", entry.name);
}
}
Rectangle {
width: 46
height: 46
@@ -59,12 +81,6 @@ Flow {
GradientStop { position: 1.0; color: entry.end }
}
}
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: SystemSettings.commitPreference("accentName", entry.modelData)
}
}
// Always shown, not a tooltip. Telling swatches apart by colour is
@@ -73,7 +89,7 @@ Flow {
// hiding the names behind a hover would waste that.
Text {
anchors.horizontalCenter: parent.horizontalCenter
text: entry.pair.label
text: entry.modelData.label
color: entry.selected ? Theme.fg : Theme.fgMuted
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall