quickshell: derive surfaces from base00, fix status colours

Stylix base01/base02 come off the wallpaper and land off-hue (purple card
over a slate bar). Tint base00 instead: #1c1f26 -> #2f3440 -> #434a5b.

base08-base0C collapse to the same cyan on monochrome wallpapers, so
warning and critical were indistinguishable. Replace with fixed err/warn/
ok/info/alt tokens; base0D stays the themed accent.

Also fixes Theme.base06, which was referenced but never declared.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-08-01 13:32:26 +01:00
parent 1640f642aa
commit e2c413d997

View file

@ -265,26 +265,42 @@ in
import QtQuick
QtObject {
// Surfaces: one hue, three steps. base01/base02 are tints of
// base00 rather than stylix's own base01/base02, which come
// straight off the wallpaper and routinely land off-hue a
// purple card floating over a slate bar. Tinting keeps
// bar card hover reading as one stack. Two numbers, and
// they are the whole surface ladder.
readonly property color base00: "#${c.base00}"
readonly property color base01: "#${c.base01}"
readonly property color base02: "#${c.base02}"
readonly property color base01: Qt.lighter(base00, 1.7) // card
readonly property color base02: Qt.lighter(base00, 2.4) // hover / chip / track
// Ink, wallpaper-derived: base05 primary, base04 muted,
// base03 disabled (also the border colour).
readonly property color base03: "#${c.base03}"
readonly property color base04: "#${c.base04}"
readonly property color base05: "#${c.base05}"
readonly property color base08: "#${c.base08}"
readonly property color base09: "#${c.base09}"
readonly property color base0A: "#${c.base0A}"
readonly property color base0B: "#${c.base0B}"
readonly property color base0C: "#${c.base0C}"
// The one themed accent: active, focused, selected, filled.
readonly property color base0D: "#${c.base0D}"
readonly property color barBg: "#B3${c.base00}"
// Status colours, deliberately NOT wallpaper-derived.
// stylix's base08-base0F all collapse to near-identical values
// on a monochrome wallpaper, which leaves "battery critical"
// and "battery low" the same colour. Status has to stay legible
// whatever is on the desktop, so these are fixed.
readonly property color err: "#e0525f" // critical: temp 85, batt 15, auth failed
readonly property color warn: "#e0a44b" // caution: temp 70, batt 30
readonly property color ok: "#68c17c" // connected / active / net down
readonly property color info: "#5aa6e0" // memory
readonly property color alt: "#b98ce0" // net up
readonly property color barBg: Qt.rgba(base00.r, base00.g, base00.b, 0.70)
// Card surfaces are translucent so the compositor's bar-layer
// blur shows through a lessened blur over the panel tint.
readonly property color cardBg: "#CC${c.base01}"
readonly property color cardBg: Qt.rgba(base01.r, base01.g, base01.b, 0.80)
// Transparent base02: hover highlights fade to/from this so the
// colour animation stays in-hue instead of dipping through
// transparent *black* (which reads as an extra flash colour).
readonly property color base02t: "#00${c.base02}"
readonly property color base02t: Qt.rgba(base02.r, base02.g, base02.b, 0)
readonly property string fontFamily: "${sansFont}"
// Ligature-based icon font: text "wifi-high" renders the icon
readonly property string iconFont: "lucide"
@ -445,7 +461,7 @@ in
color: Theme.cardBg
border.width: Theme.borderWidth
border.color: pam.active ? Theme.base0D
: root.failed ? Theme.base08
: root.failed ? Theme.err
: Theme.base03
Behavior on border.color { ColorAnimation { duration: Theme.animFade } }
@ -465,7 +481,7 @@ in
anchors.centerIn: parent
visible: pwInput.text === "" && root.failed
text: "wrong password"
color: Theme.base08
color: Theme.err
font.family: Theme.fontFamily
font.pixelSize: 13
}
@ -662,7 +678,7 @@ in
text: modelData[0]
font.family: Theme.fontFamily
font.pixelSize: 13
color: Theme.base0A
color: Theme.base0D
}
Text {
text: modelData[1]
@ -1140,7 +1156,7 @@ in
radius: parent.knobD / 2
anchors.verticalCenter: parent.verticalCenter
x: Math.max(0, Math.min(parent.width - parent.knobD, parent.value * parent.width - parent.knobD / 2))
color: Theme.base06
color: Theme.base05
Behavior on x { NumberAnimation { duration: 80 } }
}
MouseArea {
@ -1216,7 +1232,7 @@ in
width: parent.width - nlTempLabel.width - 8
anchors.verticalCenter: parent.verticalCenter
value: _nlc.nl.warmth
fillColor: Theme.base09
fillColor: Theme.warn
onMoved: (v) => bar.shellRoot.setNightlight(_nlc.nl.autoOn, v)
}
SText {
@ -2179,24 +2195,24 @@ in
value: srvWidget.connected && srvWidget.memTotal > 0
? Math.round(100 * srvWidget.memUsed / srvWidget.memTotal) + "%" : "--"
caption: "ram"
valueColor: srvWidget.connected ? Theme.base0C : Theme.base03
valueColor: srvWidget.connected ? Theme.info : Theme.base03
}
GlanceStat {
value: srvWidget.connected && srvWidget.tempC >= 0 ? srvWidget.tempC + "°" : "--"
caption: "temp"
valueColor: !srvWidget.connected || srvWidget.tempC < 0 ? Theme.base03
: srvWidget.tempC >= 85 ? Theme.base08
: srvWidget.tempC >= 70 ? Theme.base0A : Theme.base05
: srvWidget.tempC >= 85 ? Theme.err
: srvWidget.tempC >= 70 ? Theme.warn : Theme.base05
}
GlanceStat {
value: srvWidget.connected ? srvWidget.rateVal(srvWidget.rxBps) : "--"
caption: " " + srvWidget.rateUnit(srvWidget.rxBps)
valueColor: srvWidget.connected ? Theme.base0B : Theme.base03
valueColor: srvWidget.connected ? Theme.ok : Theme.base03
}
GlanceStat {
value: srvWidget.connected ? srvWidget.rateVal(srvWidget.txBps) : "--"
caption: " " + srvWidget.rateUnit(srvWidget.txBps)
valueColor: srvWidget.connected ? Theme.base09 : Theme.base03
valueColor: srvWidget.connected ? Theme.alt : Theme.base03
}
GlanceStat {
value: srvWidget.pingMs < 0 ? "--"
@ -2520,8 +2536,8 @@ in
id: batteryIconText
anchors.horizontalCenter: parent.horizontalCenter
text: batteryWidget.batteryIcon
color: batteryWidget.batteryLevel <= 15 ? Theme.base08
: batteryWidget.batteryLevel <= 30 ? Theme.base0A
color: batteryWidget.batteryLevel <= 15 ? Theme.err
: batteryWidget.batteryLevel <= 30 ? Theme.warn
: Theme.base05
font.pixelSize: 18
}
@ -2530,8 +2546,8 @@ in
id: batteryText
anchors.horizontalCenter: parent.horizontalCenter
text: batteryWidget.batteryLevel
color: batteryWidget.batteryLevel <= 15 ? Theme.base08
: batteryWidget.batteryLevel <= 30 ? Theme.base0A
color: batteryWidget.batteryLevel <= 15 ? Theme.err
: batteryWidget.batteryLevel <= 30 ? Theme.warn
: Theme.base05
font.pixelSize: 10
}
@ -2697,7 +2713,7 @@ in
SIcon {
anchors.centerIn: parent
text: "power"
color: powerMa.containsMouse || sessionMenu.open ? Theme.base08 : Theme.base05
color: powerMa.containsMouse || sessionMenu.open ? Theme.err : Theme.base05
font.pixelSize: 18
Behavior on color { ColorAnimation { duration: Theme.animFade } }
}
@ -3148,7 +3164,7 @@ in
SIcon {
anchors.verticalCenter: parent.verticalCenter
text: "server"
color: srvWidget.connected ? Theme.base0B : Theme.base08
color: srvWidget.connected ? Theme.ok : Theme.err
}
SText {
anchors.verticalCenter: parent.verticalCenter
@ -3163,7 +3179,7 @@ in
? "up " + srvWidget.uptime + " load " + srvWidget.load
: "unreachable"
font.pixelSize: 12
color: srvWidget.connected ? Theme.base04 : Theme.base08
color: srvWidget.connected ? Theme.base04 : Theme.err
elide: Text.ElideRight
}
@ -3175,7 +3191,7 @@ in
width: parent.width - 42 - 76 - 20
anchors.verticalCenter: parent.verticalCenter
value: srvWidget.cpu / 100
fillColor: srvWidget.cpu >= 90 ? Theme.base08 : Theme.base0D
fillColor: srvWidget.cpu >= 90 ? Theme.err : Theme.base0D
}
SText {
width: 76
@ -3194,7 +3210,7 @@ in
width: parent.width - 42 - 76 - 20
anchors.verticalCenter: parent.verticalCenter
value: srvWidget.memTotal > 0 ? srvWidget.memUsed / srvWidget.memTotal : 0
fillColor: Theme.base0C
fillColor: Theme.info
}
SText {
width: 76
@ -3213,8 +3229,8 @@ in
text: srvWidget.tempC < 0 ? "--" : srvWidget.tempC + "°C"
font.weight: Font.Medium
color: srvWidget.tempC < 0 ? Theme.base03
: srvWidget.tempC >= 85 ? Theme.base08
: srvWidget.tempC >= 70 ? Theme.base0A : Theme.base05
: srvWidget.tempC >= 85 ? Theme.err
: srvWidget.tempC >= 70 ? Theme.warn : Theme.base05
}
}
@ -3226,7 +3242,7 @@ in
spacing: 14
Row {
spacing: 4
SIcon { text: "arrow-down"; font.pixelSize: 14; color: Theme.base0B; anchors.verticalCenter: parent.verticalCenter }
SIcon { text: "arrow-down"; font.pixelSize: 14; color: Theme.ok; anchors.verticalCenter: parent.verticalCenter }
SText {
text: srvWidget.fmtRate(srvWidget.rxBps)
font.weight: Font.Medium
@ -3235,7 +3251,7 @@ in
}
Row {
spacing: 4
SIcon { text: "arrow-up"; font.pixelSize: 14; color: Theme.base09; anchors.verticalCenter: parent.verticalCenter }
SIcon { text: "arrow-up"; font.pixelSize: 14; color: Theme.alt; anchors.verticalCenter: parent.verticalCenter }
SText {
text: srvWidget.fmtRate(srvWidget.txBps)
font.weight: Font.Medium
@ -3298,8 +3314,8 @@ in
width: 56
text: modelData.cpu.toFixed(1)
horizontalAlignment: Text.AlignRight
color: modelData.cpu >= 100 ? Theme.base08
: modelData.cpu >= 25 ? Theme.base0A : Theme.base05
color: modelData.cpu >= 100 ? Theme.err
: modelData.cpu >= 25 ? Theme.warn : Theme.base05
anchors.verticalCenter: parent.verticalCenter
}
SText {
@ -3550,7 +3566,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.base0C
fillColor: modelData.audio && modelData.audio.muted ? Theme.base03 : Theme.base0D
onMoved: (v) => { if (modelData.audio) modelData.audio.volume = v; }
}
@ -3626,7 +3642,7 @@ in
SText {
anchors.centerIn: parent
text: "Disconnect"
color: Theme.base08
color: Theme.err
font.pixelSize: 12
}
}
@ -3677,14 +3693,14 @@ in
if (s >= 40) return "wifi-low";
return "wifi-zero";
}
color: modelData.active ? Theme.base0B : Theme.base04
color: modelData.active ? Theme.ok : Theme.base04
font.pixelSize: 16
anchors.verticalCenter: parent.verticalCenter
}
SText {
text: modelData.ssid
color: modelData.active ? Theme.base0B : Theme.base05
color: modelData.active ? Theme.ok : Theme.base05
font.pixelSize: 12
elide: Text.ElideRight
width: 140
@ -4222,7 +4238,7 @@ in
SIcon {
anchors.horizontalCenter: parent.horizontalCenter
text: calPopup.weatherGlyph(modelData.code)
color: Theme.base0C
color: Theme.base0D
font.pixelSize: 16
}
SText {
@ -4344,7 +4360,7 @@ in
width: 3
radius: 1.5
height: 3 + lvl * 13
color: Theme.base0C
color: Theme.base0D
opacity: 0.35 + lvl * 0.65
x: vinyl.width / 2 - width / 2
y: vinyl.height / 2 - vinyl.ringR - height
@ -4588,7 +4604,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.base0C
fillColor: mediaCard.pwNode && mediaCard.pwNode.audio && mediaCard.pwNode.audio.muted ? Theme.base03 : Theme.base0D
onMoved: (v) => { if (mediaCard.pwNode && mediaCard.pwNode.audio) mediaCard.pwNode.audio.volume = v; }
}
@ -4782,7 +4798,7 @@ in
Connections {
target: bar.shellRoot
function onOsdBrightness(icon, value) {
osdItem.show(icon, value, Theme.base0A);
osdItem.show(icon, value, Theme.base0D);
}
}