feat: replace noctalia with an eww panel (#3)
CI / eval (push) Successful in 2m3s
CI / lint (push) Successful in 29s

This commit was merged in pull request #3.
This commit is contained in:
2026-08-19 15:13:05 +01:00
parent d61700d173
commit a0a69cf58c
16 changed files with 565 additions and 180 deletions
@@ -0,0 +1,37 @@
# One JSON object per audio node. $1 is "sink" or "source". wpctl prints
# "Volume: 0.45", with " [MUTED]" appended, and errors when there is no node.
case "$1" in
sink) node="@DEFAULT_AUDIO_SINK@" ;;
source) node="@DEFAULT_AUDIO_SOURCE@" ;;
*) echo "usage: audio sink|source" >&2; exit 2 ;;
esac
raw=$(wpctl get-volume "$node" 2>/dev/null || true)
case "$raw" in
*Volume:*) ;;
*)
jq -nc '{ present: false, volume: 0, muted: true, icon: "󰖁" }'
exit 0
;;
esac
volume=$(printf '%s' "$raw" | awk '{ printf "%d", $2 * 100 }')
muted=false
case "$raw" in *MUTED*) muted=true ;; esac
if [ "$1" = "source" ]; then
if [ "$muted" = true ]; then icon="󰍭"; else icon="󰍬"; fi
elif [ "$muted" = true ]; then icon="󰖁"
elif [ "$volume" -ge 66 ]; then icon="󰕾"
elif [ "$volume" -ge 33 ]; then icon="󰖀"
else icon="󰕿"
fi
jq -nc \
--argjson volume "$volume" \
--argjson muted "$muted" \
--arg icon "$icon" \
'{ present: true, volume: $volume, muted: $muted, icon: $icon }'
@@ -0,0 +1,32 @@
# One JSON object for the panel's battery row. `present: false` on the desktops,
# which have no BAT* at all — the row hides itself on that.
bat=$(find /sys/class/power_supply -maxdepth 1 -name 'BAT*' 2>/dev/null | sort | head -1)
if [ -z "$bat" ]; then
jq -nc '{ present: false, icon: "", label: "", sub: "" }'
exit 0
fi
capacity=$(cat "$bat/capacity")
status=$(cat "$bat/status")
if [ "$status" = "Charging" ] || [ "$status" = "Full" ]; then
icon="󰂄"
elif [ "$capacity" -ge 90 ]; then icon="󰁹"
elif [ "$capacity" -ge 80 ]; then icon="󰂂"
elif [ "$capacity" -ge 70 ]; then icon="󰂁"
elif [ "$capacity" -ge 60 ]; then icon="󰂀"
elif [ "$capacity" -ge 50 ]; then icon="󰁿"
elif [ "$capacity" -ge 40 ]; then icon="󰁾"
elif [ "$capacity" -ge 30 ]; then icon="󰁽"
elif [ "$capacity" -ge 20 ]; then icon="󰁼"
elif [ "$capacity" -ge 10 ]; then icon="󰁻"
else icon="󰁺"
fi
jq -nc \
--arg icon "$icon" \
--arg label "$capacity%" \
--arg sub "$status" \
'{ present: true, icon: $icon, label: $label, sub: $sub }'
@@ -0,0 +1,22 @@
# One JSON object for the panel's bluetooth row. bluetoothctl blocks forever
# instead of erroring when there is no adapter, hence the /sys check + timeouts.
if [ -z "$(find /sys/class/bluetooth -mindepth 1 -maxdepth 1 2>/dev/null)" ]; then
jq -nc '{ powered: false, icon: "󰂲", label: "No adapter", sub: "" }'
exit 0
fi
powered=$(timeout 2 bluetoothctl show 2>/dev/null | awk '/Powered:/ { print $2; exit }' || true)
if [ "$powered" != "yes" ]; then
jq -nc '{ powered: false, icon: "󰂲", label: "Off", sub: "" }'
exit 0
fi
connected=$(timeout 2 bluetoothctl devices Connected 2>/dev/null | cut -d' ' -f3- | paste -sd', ' - || true)
if [ -n "$connected" ]; then
jq -nc --arg sub "$connected" '{ powered: true, icon: "󰂱", label: "On", sub: $sub }'
else
jq -nc '{ powered: true, icon: "󰂯", label: "On", sub: "Nothing connected" }'
fi
@@ -0,0 +1,11 @@
# Toggle the panel on whichever monitor has focus. `eww open --toggle` can't do
# this: it ignores --screen when the window is already open elsewhere, so the
# panel would stay stuck on the monitor it first appeared on.
if eww active-windows | grep -q '^panel'; then
exec eww close panel
fi
screen=$(hyprctl -j monitors | jq -r 'map(select(.focused))[0].id // 0')
exec eww open panel --screen "$screen"
@@ -0,0 +1,43 @@
# One JSON object for the panel's network row. State must match "connected"
# exactly: NetworkManager reports docker0 and br-* as "connected (externally)".
status=$(nmcli -t -f TYPE,STATE,CONNECTION device status 2>/dev/null || true)
# nmcli's terse output backslash-escapes colons inside connection names, so
# rejoin fields 3..NF and unescape rather than taking $3.
pick() {
printf '%s\n' "$status" | awk -F: -v want="$1" '
$1 == want && $2 == "connected" {
name = $3
for (i = 4; i <= NF; i++) name = name ":" $i
print name
exit
}' | sed 's/\\:/:/g'
}
wifi=$(pick wifi)
ethernet=$(pick ethernet)
if [ -n "$wifi" ]; then
signal=$(nmcli -t -f IN-USE,SIGNAL dev wifi 2>/dev/null | awk -F: '$1 == "*" { print $2; exit }' || true)
if [ -z "$signal" ]; then icon="󰤨"
elif [ "$signal" -ge 75 ]; then icon="󰤨"
elif [ "$signal" -ge 50 ]; then icon="󰤥"
elif [ "$signal" -ge 25 ]; then icon="󰤢"
else icon="󰤟"
fi
if [ -n "$signal" ]; then
sub="Wi-Fi · $signal%"
else
sub="Wi-Fi"
fi
jq -nc --arg icon "$icon" --arg label "$wifi" --arg sub "$sub" \
'{ icon: $icon, label: $label, sub: $sub }'
elif [ -n "$ethernet" ]; then
jq -nc --arg label "$ethernet" '{ icon: "󰈀", label: $label, sub: "Ethernet" }'
else
jq -nc '{ icon: "󰤭", label: "Offline", sub: "" }'
fi