quickshell: pick the accent from the palette, don't trust base0D
Every icon in the bar was already bound to a Theme colour — the problem was which one. base0D is the accent for 33 sites and every status colour harmonises toward it, but the generator fills each slot independently: on wallhaven-5y39p9 all six accent slots come back orange (H=0.08) except base0D, which comes back blue-grey. Hence a blue NixOS logo and a blue workspace pill in an amber bar. Accent now auditions all six slots and takes the one nearest S=0.60. Nearest, not max: max picks the neon fe5162 on wallhaven-k8dqr6, close enough to err that errors stop reading as errors. Only 5y39p9 and k8dqr6 change; the other four keep the colour they already had. Renamed base0D -> accent since it no longer names the slot it comes from.
This commit is contained in:
parent
559ccc55db
commit
27414dafbc
1 changed files with 72 additions and 38 deletions
|
|
@ -545,7 +545,12 @@ in
|
|||
property string base03: "${c.base03}"
|
||||
property string base04: "${c.base04}"
|
||||
property string base05: "${c.base05}"
|
||||
property string base09: "${c.base09}"
|
||||
property string base0A: "${c.base0A}"
|
||||
property string base0B: "${c.base0B}"
|
||||
property string base0C: "${c.base0C}"
|
||||
property string base0D: "${c.base0D}"
|
||||
property string base0E: "${c.base0E}"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -563,23 +568,52 @@ in
|
|||
readonly property color base03: "#" + pal.base03
|
||||
readonly property color base04: "#" + pal.base04
|
||||
readonly property color base05: "#" + pal.base05
|
||||
// The one themed accent: active, focused, selected, filled.
|
||||
readonly property color base0D: "#" + pal.base0D
|
||||
// The one themed accent: active, focused, selected, filled —
|
||||
// and every status colour below is harmonised toward it, so a
|
||||
// bad pick tints the whole bar rather than just the highlights.
|
||||
//
|
||||
// NOT pal.base0D on its own. The generator fills each slot
|
||||
// independently and is free to hand that one a colour from
|
||||
// outside the rest of the palette's family: on the amber
|
||||
// wallhaven-5y39p9 every accent slot comes back orange
|
||||
// (H=0.08) except base0D, which comes back blue-grey (8590ae,
|
||||
// H=0.62) — that was a blue NixOS logo in an otherwise amber
|
||||
// bar. So audition all six and take whichever sits nearest a
|
||||
// good accent saturation.
|
||||
//
|
||||
// Nearest 0.6, not "the most saturated": max picks the neon
|
||||
// fe5162 (S=0.99) on wallhaven-k8dqr6, near enough to `err`
|
||||
// that errors stop reading as errors. On a monochrome
|
||||
// wallpaper every slot collapses to the same value, so the
|
||||
// choice stops mattering rather than going wrong.
|
||||
readonly property real accentSat: 0.60
|
||||
readonly property color accent: {
|
||||
const slots = [pal.base09, pal.base0A, pal.base0B,
|
||||
pal.base0C, pal.base0D, pal.base0E];
|
||||
let best = Qt.color("#" + pal.base0D);
|
||||
let bestD = Math.abs(best.hslSaturation - accentSat);
|
||||
for (let i = 0; i < slots.length; i++) {
|
||||
const c = Qt.color("#" + slots[i]);
|
||||
const d = Math.abs(c.hslSaturation - accentSat);
|
||||
if (d < bestD) { best = c; bestD = d; }
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
// ── Status colours: fixed hues, pulled toward the theme.
|
||||
// Sourcing these from stylix doesn't work — base08-base0F all
|
||||
// collapse to near-identical values on a monochrome wallpaper,
|
||||
// which leaves "battery critical" and "battery low" the same
|
||||
// colour. So the HUE is fixed and only the hue is: each one is
|
||||
// then mixed toward base0D, which keeps red reading as red
|
||||
// then mixed toward the accent, which keeps red reading as red
|
||||
// while landing it in the wallpaper's family instead of looking
|
||||
// pasted on. Blending toward base0D and not toward the card
|
||||
// pasted on. Blending toward the accent and not toward the card
|
||||
// keeps luminance roughly intact, so these stay legible as text
|
||||
// on cardBg — mixing into the background would sink them.
|
||||
readonly property real statusHarmony: 0.25 // 0 = pure hue, 1 = pure accent
|
||||
function harmonised(hex) {
|
||||
let h = Qt.color(hex);
|
||||
return Qt.tint(base0D, Qt.rgba(h.r, h.g, h.b, 1 - statusHarmony));
|
||||
return Qt.tint(accent, Qt.rgba(h.r, h.g, h.b, 1 - statusHarmony));
|
||||
}
|
||||
readonly property color err: harmonised("#e0525f") // critical: temp ≥85, batt ≤15, auth failed
|
||||
readonly property color warn: harmonised("#e0a44b") // caution: temp ≥70, batt ≤30
|
||||
|
|
@ -803,7 +837,7 @@ in
|
|||
radius: Theme.radiusCard
|
||||
color: Theme.cardBg
|
||||
border.width: Theme.borderWidth
|
||||
border.color: pam.active ? Theme.base0D
|
||||
border.color: pam.active ? Theme.accent
|
||||
: root.failed ? Theme.err
|
||||
: Theme.base03
|
||||
Behavior on border.color { ColorAnimation { duration: Theme.animFade } }
|
||||
|
|
@ -863,7 +897,7 @@ in
|
|||
text: "arrow-right"
|
||||
font.family: Theme.iconFont
|
||||
font.pixelSize: 18
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
MouseArea {
|
||||
id: confirmMa
|
||||
|
|
@ -991,7 +1025,7 @@ in
|
|||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 15
|
||||
font.bold: true
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
bottomPadding: 4
|
||||
}
|
||||
|
||||
|
|
@ -1006,7 +1040,7 @@ in
|
|||
text: modelData[0]
|
||||
font.family: Theme.fontFamily
|
||||
font.pixelSize: 13
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
Text {
|
||||
text: modelData[1]
|
||||
|
|
@ -2010,7 +2044,7 @@ in
|
|||
// variants scale with just a trackH override.
|
||||
component PillSlider: Item {
|
||||
property real value: 0
|
||||
property color fillColor: Theme.base0D
|
||||
property color fillColor: Theme.accent
|
||||
property real trackH: 8
|
||||
readonly property real knobD: trackH + 8
|
||||
signal moved(real v)
|
||||
|
|
@ -2052,7 +2086,7 @@ in
|
|||
// something you can grab.
|
||||
component MeterBar: Item {
|
||||
property real value: 0
|
||||
property color fillColor: Theme.base0D
|
||||
property color fillColor: Theme.accent
|
||||
property real trackH: 5
|
||||
height: trackH
|
||||
Rectangle {
|
||||
|
|
@ -2074,7 +2108,7 @@ in
|
|||
property bool on: false
|
||||
signal toggled(bool v)
|
||||
width: 34; height: 18; radius: 9
|
||||
color: on ? Theme.base0D : Theme.base02
|
||||
color: on ? Theme.accent : Theme.base02
|
||||
Behavior on color { ColorAnimation { duration: Theme.animFade } }
|
||||
Rectangle {
|
||||
width: 12; height: 12; radius: 6
|
||||
|
|
@ -3264,14 +3298,14 @@ in
|
|||
ColorOverlay {
|
||||
anchors.fill: launchLogo
|
||||
source: launchLogo
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
}
|
||||
|
||||
SText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "${config.home.username}"
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
|
||||
SText {
|
||||
|
|
@ -3300,7 +3334,7 @@ in
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "equal"
|
||||
font.pixelSize: 18
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
SText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
|
@ -3359,7 +3393,7 @@ in
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "sparkles"
|
||||
font.pixelSize: 14
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
SText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
|
@ -3682,7 +3716,7 @@ in
|
|||
visible: icon === ""
|
||||
text: glyph
|
||||
font.pixelSize: 20
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3779,7 +3813,7 @@ in
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: modelData.icon
|
||||
font.pixelSize: 20
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
|
@ -3890,7 +3924,7 @@ in
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: ctxMenu.pinned ? "pin-off" : "pin"
|
||||
font.pixelSize: 14
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
SText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
|
@ -4092,7 +4126,7 @@ in
|
|||
ColorOverlay {
|
||||
anchors.fill: nixLogoImg
|
||||
source: nixLogoImg
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
|
|
@ -4126,7 +4160,7 @@ in
|
|||
width: 6
|
||||
height: wsItem.modelData.focused ? 18 : 6
|
||||
radius: 3
|
||||
color: wsItem.modelData.focused ? Theme.base0D
|
||||
color: wsItem.modelData.focused ? Theme.accent
|
||||
: wsMa.containsMouse ? Theme.base04 : Theme.base03
|
||||
Behavior on height {
|
||||
NumberAnimation { duration: 200; easing.type: Easing.OutExpo }
|
||||
|
|
@ -4165,7 +4199,7 @@ in
|
|||
anchors.centerIn: parent
|
||||
text: "image"
|
||||
font.pixelSize: 18
|
||||
color: bar.activeDropdown === wallDropdown ? Theme.base0D
|
||||
color: bar.activeDropdown === wallDropdown ? Theme.accent
|
||||
: wallMa.containsMouse ? Theme.base05 : Theme.base04
|
||||
Behavior on color { ColorAnimation { duration: Theme.animFade } }
|
||||
}
|
||||
|
|
@ -4338,7 +4372,7 @@ in
|
|||
GlanceStat {
|
||||
value: srvWidget.connected ? Math.round(srvWidget.cpu) + "%" : "--"
|
||||
caption: "cpu"
|
||||
valueColor: srvWidget.connected ? Theme.base0D : Theme.base03
|
||||
valueColor: srvWidget.connected ? Theme.accent : Theme.base03
|
||||
}
|
||||
GlanceStat {
|
||||
value: srvWidget.connected && srvWidget.memTotal > 0
|
||||
|
|
@ -5268,7 +5302,7 @@ in
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
visible: modelData.buttonType !== QsMenuButtonType.None
|
||||
text: modelData.checkState === Qt.Checked ? "\u2713" : ""
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
font.pixelSize: 12
|
||||
}
|
||||
|
||||
|
|
@ -5440,7 +5474,7 @@ in
|
|||
// hover — same selection language as the
|
||||
// workspace pill above it.
|
||||
border.width: Theme.borderWidth
|
||||
border.color: active ? Theme.base0D
|
||||
border.color: active ? Theme.accent
|
||||
: wallTileMa.containsMouse ? Theme.base04
|
||||
: "transparent"
|
||||
Behavior on border.color { ColorAnimation { duration: Theme.animFade } }
|
||||
|
|
@ -5517,7 +5551,7 @@ in
|
|||
width: parent.width - 42 - 76 - 20
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
value: srvWidget.cpu / 100
|
||||
fillColor: srvWidget.cpu >= 90 ? Theme.err : Theme.base0D
|
||||
fillColor: srvWidget.cpu >= 90 ? Theme.err : Theme.accent
|
||||
}
|
||||
SText {
|
||||
width: 76
|
||||
|
|
@ -5697,7 +5731,7 @@ in
|
|||
width: parent.width - masterVolLabel.width - 8
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
value: volWidget.sink && volWidget.sink.audio ? Math.min(1, volWidget.sink.audio.volume) : 0
|
||||
fillColor: volWidget.muted ? Theme.base03 : Theme.base0D
|
||||
fillColor: volWidget.muted ? Theme.base03 : Theme.accent
|
||||
onMoved: (v) => { if (volWidget.sink && volWidget.sink.audio) volWidget.sink.audio.volume = v; }
|
||||
}
|
||||
|
||||
|
|
@ -5810,8 +5844,8 @@ in
|
|||
width: (parent.width - 12) / 3
|
||||
height: 26
|
||||
radius: 6
|
||||
color: active ? Theme.base0D : "transparent"
|
||||
border.color: active ? Theme.base0D : Theme.base03
|
||||
color: active ? Theme.accent : "transparent"
|
||||
border.color: active ? Theme.accent : Theme.base03
|
||||
border.width: 1
|
||||
|
||||
SText {
|
||||
|
|
@ -5892,7 +5926,7 @@ in
|
|||
height: 16
|
||||
trackH: 4
|
||||
value: modelData.audio ? Math.min(1, modelData.audio.volume) : 0
|
||||
fillColor: modelData.audio && modelData.audio.muted ? Theme.base03 : Theme.base0D
|
||||
fillColor: modelData.audio && modelData.audio.muted ? Theme.base03 : Theme.accent
|
||||
onMoved: (v) => { if (modelData.audio) modelData.audio.volume = v; }
|
||||
}
|
||||
|
||||
|
|
@ -6355,7 +6389,7 @@ in
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "video"
|
||||
color: recCard.recording ? Theme.err
|
||||
: recCard.selecting ? Theme.base0D : Theme.base05
|
||||
: recCard.selecting ? Theme.accent : Theme.base05
|
||||
font.pixelSize: 15
|
||||
}
|
||||
SText {
|
||||
|
|
@ -6495,7 +6529,7 @@ in
|
|||
SIcon {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
text: "coffee"
|
||||
color: caffCard.on ? Theme.base0D : Theme.base05
|
||||
color: caffCard.on ? Theme.accent : Theme.base05
|
||||
font.pixelSize: 15
|
||||
}
|
||||
SText {
|
||||
|
|
@ -6862,7 +6896,7 @@ in
|
|||
SIcon {
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
text: calPopup.weatherGlyph(modelData.code)
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
font.pixelSize: 16
|
||||
}
|
||||
SText {
|
||||
|
|
@ -6984,7 +7018,7 @@ in
|
|||
width: 3
|
||||
radius: 1.5
|
||||
height: 3 + lvl * 13
|
||||
color: Theme.base0D
|
||||
color: Theme.accent
|
||||
opacity: 0.35 + lvl * 0.65
|
||||
x: vinyl.width / 2 - width / 2
|
||||
y: vinyl.height / 2 - vinyl.ringR - height
|
||||
|
|
@ -7302,7 +7336,7 @@ in
|
|||
height: 16
|
||||
trackH: 4
|
||||
value: mediaCard.pwNode && mediaCard.pwNode.audio ? Math.min(1, mediaCard.pwNode.audio.volume) : 0
|
||||
fillColor: mediaCard.pwNode && mediaCard.pwNode.audio && mediaCard.pwNode.audio.muted ? Theme.base03 : Theme.base0D
|
||||
fillColor: mediaCard.pwNode && mediaCard.pwNode.audio && mediaCard.pwNode.audio.muted ? Theme.base03 : Theme.accent
|
||||
onMoved: (v) => { if (mediaCard.pwNode && mediaCard.pwNode.audio) mediaCard.pwNode.audio.volume = v; }
|
||||
}
|
||||
|
||||
|
|
@ -7505,7 +7539,7 @@ in
|
|||
property bool shown: false
|
||||
property string icon: "volume-2"
|
||||
property real value: 0
|
||||
property color fill: Theme.base0D
|
||||
property color fill: Theme.accent
|
||||
|
||||
// Takes over the server glance's slot: fixed position, no
|
||||
// dependence on how tall the workspace column has grown.
|
||||
|
|
@ -7547,7 +7581,7 @@ in
|
|||
show(a.muted ? "volume-x"
|
||||
: v >= 0.5 ? "volume-2"
|
||||
: v > 0 ? "volume-1" : "volume",
|
||||
v, a.muted ? Theme.base03 : Theme.base0D);
|
||||
v, a.muted ? Theme.base03 : Theme.accent);
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
|
@ -7562,7 +7596,7 @@ in
|
|||
Connections {
|
||||
target: bar.shellRoot
|
||||
function onOsdBrightness(icon, value) {
|
||||
osdItem.show(icon, value, Theme.base0D);
|
||||
osdItem.show(icon, value, Theme.accent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue