improve eww

This commit is contained in:
2026-09-10 19:54:50 +02:00
parent e551d36e1c
commit 7bb27f9373
46 changed files with 1296 additions and 1092 deletions
@@ -1,38 +0,0 @@
#!/usr/bin/env bash
emit() {
local powered=false connected=false device=""
if bluetoothctl show 2>/dev/null | grep -q "Powered: yes"; then
powered=true
while IFS= read -r line; do
local mac info
mac=$(echo "$line" | awk '{ print $2 }')
info=$(bluetoothctl info "$mac" 2>/dev/null)
if echo "$info" | grep -q "Connected: yes"; then
device=$(echo "$info" | awk -F': ' '/^\tName:/ { print $2; exit }')
connected=true
break
fi
done < <(bluetoothctl devices 2>/dev/null)
fi
printf '{"powered":%s,"connected":%s,"device":"%s"}\n' "$powered" "$connected" "$device"
}
emit
tmp=$(mktemp -d)
pipe="$tmp/bt-events"
mkfifo "$pipe"
trap 'rm -rf "$tmp"; kill 0 2>/dev/null' EXIT INT TERM
# Poll every 10s as reliable fallback for missed events
(while true; do sleep 10; echo poll; done) > "$pipe" &
# bluetoothctl monitor for reactive device connect/disconnect events
(bluetoothctl monitor 2>/dev/null | grep --line-buffered -E "Powered|Connected|Device") > "$pipe" &
while IFS= read -r _ < "$pipe"; do
emit
done
@@ -0,0 +1,40 @@
#!/usr/bin/env bash
# Bluetooth state — adapter power, connected device and the paired/trusted
# device list — from one ObjectManager call on the system bus. Refreshes on
# every org.bluez signal (property changes, devices added/removed) and every
# 60 s.
fallback='{"powered":false,"connected":false,"device":"","devices":[]}'
query() {
busctl --system --json=short call org.bluez / org.freedesktop.DBus.ObjectManager GetManagedObjects 2>/dev/null \
| jq -c '
.data[0] as $o
| ($o | to_entries | map(.value["org.bluez.Adapter1"] | select(.) | .Powered.data) | any) as $powered
| ($o | to_entries
| map(.value["org.bluez.Device1"] | select(.))
| map(select(.Paired.data or .Trusted.data or .Connected.data))
| map({ mac: .Address.data,
name: (.Alias.data // .Name.data // .Address.data),
connected: (.Connected.data // false),
paired: (.Paired.data // false) })
| sort_by((.connected | not), (.paired | not), .name)) as $devices
| { powered: $powered,
connected: ($devices | any(.connected)),
device: ($devices | map(select(.connected)) | .[0].name // ""),
devices: $devices }' 2>/dev/null
}
refresh() {
local out
out=$(query)
emit "${out:-$fallback}"
}
_bt_events() { exec gdbus monitor --system --dest org.bluez; }
refresh
mux_init
mux_add _bt_events
mux_tick 60
mux_loop refresh
@@ -1,33 +0,0 @@
#!/usr/bin/env bash
emit() {
local first=true arr=""
while IFS= read -r line; do
local mac name connected
mac=$(echo "$line" | awk '{ print $2 }')
name=$(echo "$line" | awk '{ $1=$2=""; sub(/^ +/, ""); print }')
info=$(bluetoothctl info "$mac" 2>/dev/null)
connected=$(echo "$info" | grep -q "Connected: yes" && echo true || echo false)
$first || arr="${arr},"
arr="${arr}{\"mac\":\"${mac}\",\"name\":\"${name}\",\"connected\":${connected}}"
first=false
done < <(bluetoothctl devices 2>/dev/null)
echo "[${arr}]"
}
emit
tmp=$(mktemp -d)
pipe="$tmp/bt-dev-events"
mkfifo "$pipe"
trap 'rm -rf "$tmp"; kill 0 2>/dev/null' EXIT INT TERM
# Poll every 10s as fallback for missed events
(while true; do sleep 10; echo poll; done) > "$pipe" &
# Reactive updates from D-Bus
(bluetoothctl monitor 2>/dev/null | grep --line-buffered -E "Connected|Device|Powered") > "$pipe" &
while IFS= read -r _ < "$pipe"; do
emit
done
@@ -1,5 +1,6 @@
#!/usr/bin/env bash
mac="$1"
# Connect or disconnect the bluetooth device with MAC $1.
mac=$1
if bluetoothctl info "$mac" 2>/dev/null | grep -q "Connected: yes"; then
bluetoothctl disconnect "$mac"
else
@@ -1,64 +1,84 @@
#!/usr/bin/env bash
# Network state for the bar icons and the net panel: wifi, ethernet and USB
# tethering. Refreshes on link/address changes and every 30 s (signal level).
get_wifi_iface() {
awk 'NR > 2 { gsub(":", "", $1); print $1; exit }' /proc/net/wireless
}
get_usb_iface() {
ip link 2>/dev/null | awk '
/^[0-9]+: usb[0-9]/ { gsub(":", "", $2); print $2; exit }
/^[0-9]+: enx/ { gsub(":", "", $2); print $2; exit }
'
}
wifi_iface() { awk 'NR > 2 { sub(":", "", $1); print $1; exit }' /proc/net/wireless; }
eth_iface() { ip -o link 2>/dev/null | awk '$2 ~ /^en[op]/ { sub(":", "", $2); print $2; exit }'; }
usb_iface() { ip -o link 2>/dev/null | awk '$2 ~ /^(usb[0-9]|enx)/ { sub(":", "", $2); print $2; exit }'; }
ipv4() { ip -4 -o addr show "$1" 2>/dev/null | awk '{ print $4; exit }'; }
signal_icon() {
local dbm="$1"
if [ -z "$dbm" ]; then echo "󰤮"; return; fi
if [ "$dbm" -ge -50 ]; then echo "󰤨"
elif [ "$dbm" -ge -60 ]; then echo "󰤥"
elif [ "$dbm" -ge -70 ]; then echo "󰤢"
elif [ "$dbm" -ge -80 ]; then echo "󰤟"
local dbm=${1:-}
[[ -z $dbm ]] && { echo "󰤮"; return; }
if ((dbm >= -50)); then echo "󰤨"
elif ((dbm >= -60)); then echo "󰤥"
elif ((dbm >= -70)); then echo "󰤢"
elif ((dbm >= -80)); then echo "󰤟"
else echo "󰤯"; fi
}
make_content() {
local wifi_iface eth_iface
wifi_iface=$(get_wifi_iface)
eth_iface=$(ip link | awk '/^[0-9]+: en[po]/ { gsub(":",""); print $2; exit }')
# Ethernet
local eth_connected=false
if [ -n "$eth_iface" ]; then
eth_state=$(ip link show "$eth_iface" 2>/dev/null | awk '/state/ { print $9 }')
[ "$eth_state" = "UP" ] && eth_connected=true
fi
# USB tethering
local usb_iface usb_connected=false
usb_iface=$(get_usb_iface)
if [ -n "$usb_iface" ] && ip -4 addr show "$usb_iface" 2>/dev/null | grep -q "inet "; then
usb_connected=true
fi
# WiFi - use IP presence as connection indicator (more reliable than wpa_cli)
local wifi_connected=false wifi_enabled=false wifi_icon="󰤮" wifi_ssid=""
if ! rfkill list wlan 2>/dev/null | grep -q "Soft blocked: yes"; then
wifi_enabled=true
fi
if [ -n "$wifi_iface" ] && ip -4 addr show "$wifi_iface" 2>/dev/null | grep -q "inet "; then
wifi_connected=true
wifi_ssid=$(wpa_cli -g "/run/wpa_supplicant/$wifi_iface" status 2>/dev/null \
| awk -F= '/^ssid=/ { print $2 }')
signal=$(awk -v iface="$wifi_iface" '$1 == iface ":" { gsub(/\./, "", $4); print $4; exit }' /proc/net/wireless)
wifi_icon=$(signal_icon "$signal")
fi
printf '{"wifi":{"connected":%s,"enabled":%s,"icon":"%s","ssid":"%s"},"ethernet":{"connected":%s},"usb":{"connected":%s}}\n' \
"$wifi_connected" "$wifi_enabled" "$wifi_icon" "$wifi_ssid" "$eth_connected" "$usb_connected"
band() {
local f=${1:-0}
if ((f >= 5925)); then echo "6 GHz"
elif ((f >= 4900)); then echo "5 GHz"
elif ((f >= 2400)); then echo "2.4 GHz"
else echo ""; fi
}
make_content
ip monitor | while read -r _; do
make_content
done
generation() {
case ${1:-} in
7) echo "Wi-Fi 7" ;; 6) echo "Wi-Fi 6" ;; 5) echo "Wi-Fi 5" ;; 4) echo "Wi-Fi 4" ;; *) echo "" ;;
esac
}
state() {
local wifi eth usb
wifi=$(wifi_iface)
eth=$(eth_iface)
usb=$(usb_iface)
local w_enabled=false w_connected=false w_icon="󰤮" w_ssid="" w_ip="" w_freq=0 w_gen="" w_signal=0 wpa
rfkill list wlan 2>/dev/null | grep -q "Soft blocked: yes" || w_enabled=true
if [[ -n $wifi ]]; then
w_ip=$(ipv4 "$wifi")
if [[ -n $w_ip ]]; then
w_connected=true
wpa=$(wpa_cli -g "/run/wpa_supplicant/$wifi" status 2>/dev/null)
w_ssid=$(awk -F= '/^ssid=/ { print $2; exit }' <<<"$wpa")
w_freq=$(awk -F= '/^freq=/ { print $2; exit }' <<<"$wpa")
w_gen=$(generation "$(awk -F= '/^wifi_generation=/ { print $2; exit }' <<<"$wpa")")
w_signal=$(awk -v i="$wifi:" '$1 == i { sub(/\./, "", $4); print $4; exit }' /proc/net/wireless)
w_icon=$(signal_icon "$w_signal")
fi
fi
local e_connected=false e_ip="" e_speed="" spd
if [[ -n $eth ]] && ip -o link show "$eth" 2>/dev/null | grep -q "state UP"; then
e_connected=true
e_ip=$(ipv4 "$eth")
spd=$(cat "/sys/class/net/$eth/speed" 2>/dev/null)
[[ ${spd:-0} -gt 0 ]] 2>/dev/null && e_speed="${spd} Mbps"
fi
local u_connected=false u_ip=""
if [[ -n $usb ]]; then
u_ip=$(ipv4 "$usb")
[[ -n $u_ip ]] && u_connected=true
fi
printf '{"wifi":{"connected":%s,"enabled":%s,"icon":"%s","ssid":"%s","ip":"%s","freq":%s,"band":"%s","gen":"%s","signal":%s},' \
"$w_connected" "$w_enabled" "$w_icon" "$(jstr "$w_ssid")" "$w_ip" "${w_freq:-0}" "$(band "$w_freq")" "$w_gen" "${w_signal:-0}"
printf '"ethernet":{"connected":%s,"interface":"%s","ip":"%s","speed":"%s"},' \
"$e_connected" "$eth" "$e_ip" "$e_speed"
printf '"usb":{"connected":%s,"interface":"%s","ip":"%s"}}' \
"$u_connected" "$usb" "$u_ip"
}
refresh() { emit "$(state)"; }
_link_events() { exec ip monitor link address; }
refresh
mux_init
mux_add _link_events
mux_tick 30
mux_loop refresh
@@ -1,79 +0,0 @@
#!/usr/bin/env bash
get_wifi_iface() {
awk 'NR > 2 { gsub(":", "", $1); print $1; exit }' /proc/net/wireless
}
get_usb_iface() {
ip link 2>/dev/null | awk '
/^[0-9]+: usb[0-9]/ { gsub(":", "", $2); print $2; exit }
/^[0-9]+: enx/ { gsub(":", "", $2); print $2; exit }
'
}
freq_band() {
local f="$1"
if [ "$f" -ge 6000 ] 2>/dev/null; then echo "6 GHz"
elif [ "$f" -ge 5000 ] 2>/dev/null; then echo "5 GHz"
elif [ "$f" -ge 2400 ] 2>/dev/null; then echo "2.4 GHz"
else echo ""; fi
}
wifi_gen_label() {
case "$1" in
7) echo "Wi-Fi 7" ;; 6) echo "Wi-Fi 6" ;;
5) echo "Wi-Fi 5" ;; 4) echo "Wi-Fi 4" ;;
*) echo "" ;;
esac
}
make_content() {
local wifi_iface eth_iface
wifi_iface=$(get_wifi_iface)
eth_iface=$(ip link | awk '/^[0-9]+: en[po]/ { gsub(":",""); print $2; exit }')
local wifi_ssid="" wifi_ip="" wifi_freq=0 wifi_band="" wifi_gen="" wifi_signal=0
if [ -n "$wifi_iface" ] && ip -4 addr show "$wifi_iface" 2>/dev/null | grep -q "inet "; then
local wpa
wpa=$(wpa_cli -g "/run/wpa_supplicant/$wifi_iface" status 2>/dev/null)
wifi_ssid=$(echo "$wpa" | awk -F= '/^ssid=/ { print $2 }')
wifi_ip=$(ip -4 addr show "$wifi_iface" | awk '/inet / { print $2 }')
wifi_freq=$(echo "$wpa" | awk -F= '/^freq=/ { print $2 }')
local gen
gen=$(echo "$wpa" | awk -F= '/^wifi_generation=/ { print $2 }')
wifi_band=$(freq_band "$wifi_freq")
wifi_gen=$(wifi_gen_label "$gen")
wifi_signal=$(awk -v iface="$wifi_iface" \
'$1 == iface ":" { gsub(/\./, "", $4); print $4; exit }' /proc/net/wireless)
fi
local eth_ip="" eth_speed="" eth_state="down"
if [ -n "$eth_iface" ]; then
eth_state=$(ip link show "$eth_iface" 2>/dev/null | awk '/state/ { print tolower($9) }')
if [ "$eth_state" = "up" ]; then
eth_ip=$(ip -4 addr show "$eth_iface" | awk '/inet / { print $2 }')
local spd
spd=$(cat /sys/class/net/"$eth_iface"/speed 2>/dev/null)
[ "${spd:-0}" -gt 0 ] 2>/dev/null && eth_speed="${spd} Mbps"
fi
fi
local usb_iface usb_ip=""
usb_iface=$(get_usb_iface)
if [ -n "$usb_iface" ] && ip -4 addr show "$usb_iface" 2>/dev/null | grep -q "inet "; then
usb_ip=$(ip -4 addr show "$usb_iface" | awk '/inet / { print $2 }')
fi
# shellcheck disable=SC2059
printf '{"wifi":{"ssid":"%s","ip":"%s","freq":%s,"band":"%s","gen":"%s","signal":%s},' \
"$wifi_ssid" "$wifi_ip" "${wifi_freq:-0}" "$wifi_band" "$wifi_gen" "${wifi_signal:-0}"
printf '"ethernet":{"state":"%s","ip":"%s","speed":"%s","interface":"%s"},' \
"$eth_state" "$eth_ip" "$eth_speed" "${eth_iface:-}"
printf '"usb":{"interface":"%s","ip":"%s"}}\n' \
"${usb_iface:-}" "$usb_ip"
}
make_content
ip monitor | while read -r _; do
make_content
done