radio-win

This commit is contained in:
soraefir
2026-06-12 23:49:38 +02:00
parent c724c853f5
commit ce804942a9
13 changed files with 140 additions and 117 deletions

View File

@@ -1,14 +0,0 @@
{
"permissions": {
"allow": [
"WebFetch(domain:elkowar.github.io)",
"WebFetch(domain:github.com)",
"WebFetch(domain:raw.githubusercontent.com)",
"WebSearch",
"WebFetch(domain:deepwiki.com)",
"Bash(amdgpu_top -J -s 1000 -d 1)",
"Bash(amdgpu_top -J -s 1000 -n 1)",
"Bash(sensors -j)"
]
}
}

View File

@@ -1,6 +1,3 @@
.calendar-win {
}
calendar { calendar {
padding: 5pt; padding: 5pt;

View File

@@ -1,14 +1,14 @@
// Bar icons // Bar icons
.net-icon { font-size: 14px; padding: 3pt 0; } .net-icon { font-size: 14px; padding: 3pt 0; }
.net-active { color: $base07; } .net-active, .blt-on { color: $base07; }
.net-dim { color: $base02; } .net-dim { color: $base02; }
.blt-on { color: $base07; } .blt-connected { color: $base0D; }
.blt-connected { color: $base0D; }
// Popup window section accents // Popup window section accents
.wifi-accent { background-color: $base0C; } .wifi-accent { background-color: $base0C; }
.eth-accent { background-color: $base0B; } .eth-accent { background-color: $base0B; }
.blt-accent { background-color: $base0D; } .blt-accent { background-color: $base0D; }
.usb-accent { background-color: $base09; }
// Netinfo rows // Netinfo rows
.netinfo-row { margin-bottom: 3pt; } .netinfo-row { margin-bottom: 3pt; }
@@ -16,9 +16,22 @@
.netinfo-value { font-size: 0.72em; color: $base05; } .netinfo-value { font-size: 0.72em; color: $base05; }
.netinfo-dim { font-size: 0.72em; color: $base03; margin-bottom: 4pt; } .netinfo-dim { font-size: 0.72em; color: $base03; margin-bottom: 4pt; }
// Section toggle button
.net-toggle-btn {
padding: 2pt 4pt;
border-radius: $border-radius;
font-size: 1.1em;
}
.net-toggle-btn:hover { background-color: $base02; }
.net-toggle-on { color: $base07; }
.net-toggle-on:hover { color: $base06; }
.net-toggle-off { color: $base03; }
.net-toggle-off:hover { color: $base05; }
// Bluetooth device list // Bluetooth device list
.bt-device-row { margin-bottom: 4pt; } .bt-device-row { margin-bottom: 4pt; }
.bt-device-name { font-size: 0.78em; color: $base05; } .bt-device-name { font-size: 0.78em; color: $base05; }
.bt-device-btn { padding: 2pt 6pt; border-radius: $border-radius; font-size: 1em; } .bt-device-btn { padding: 2pt 6pt; border-radius: $border-radius; font-size: 1em; }
.bt-device-btn:hover { background-color: $base02; }
.bt-btn-on { color: $base0D; } .bt-btn-on { color: $base0D; }
.bt-btn-off { color: $base03; } .bt-btn-off { color: $base03; }

View File

@@ -1,8 +1,7 @@
.radio-win { .radio-win {
//margin: $gaps-screen; //margin: $gaps-screen;
//padding: .5em; //padding: .5em;
} }
.album_art { .album_art {
background-repeat: no-repeat; background-repeat: no-repeat;

View File

@@ -4,11 +4,7 @@
.gpubar { color: $base0E; } .gpubar { color: $base0E; }
.membar { color: $base08; } .membar { color: $base08; }
.batbar { color: $base0B; } .batbar { color: $base0B; }
.cpubar, .gpubar, .membar, .batbar { background-color: $bg0; margin: $gaps-window 0; }
.cpubar, .gpubar, .membar, .batbar {
background-color: $bg0;
margin: $gaps-window 0;
}
// Window // Window
.sys-win { .sys-win {
@@ -47,26 +43,17 @@
margin: 6pt 0 10pt 0; margin: 6pt 0 10pt 0;
} }
.sys-sublabel { // All rings share the same track background
font-size: 0.72em; .cpu-usage-ring, .cpu-freq-ring,
color: $base04; .gpu-ring, .gpu-freq-ring,
margin-right: 8pt; .ram-ring, .swap-ring, .bat-ring { background-color: $bg0; }
}
// CPU grid // CPU grid
.cpu-usage-ring { .cpu-usage-ring { color: $base0C; margin: 3pt; }
color: $base0C;
background-color: $bg0;
margin: 3pt;
}
// Inner freq ring — margin shrinks it inside overlay for concentric effect // Inner freq ring — margin shrinks it inside overlay for concentric effect
// 0% = cpu min freq, 100% = cpu max freq // 0% = cpu min freq, 100% = cpu max freq
.cpu-freq-ring { .cpu-freq-ring { color: $base0D; margin: 12px; }
color: $base0D;
background-color: $bg0;
margin: 12px;
}
.cpu-core-label { .cpu-core-label {
font-size: 0.7em; font-size: 0.7em;
@@ -74,17 +61,8 @@
} }
// GPU rings // GPU rings
.gpu-ring { .gpu-ring { color: $base0E; margin: 3pt; }
color: $base0E; .gpu-freq-ring { color: $base0D; margin: 13px; }
background-color: $bg0;
margin: 3pt;
}
.gpu-freq-ring {
color: $base0D;
background-color: $bg0;
margin: 13px;
}
.gpu-ring-value { .gpu-ring-value {
font-size: 0.82em; font-size: 0.82em;
@@ -138,11 +116,7 @@
} }
// RAM ring // RAM ring
.ram-ring { .ram-ring { color: $base08; margin: 4pt; }
color: $base08;
background-color: $bg0;
margin: 4pt;
}
.ram-cached-ring { .ram-cached-ring {
color: $base02; color: $base02;
@@ -162,11 +136,7 @@
} }
// Swap ring // Swap ring
.swap-ring { .swap-ring { color: $base09; margin: 3pt; }
color: $base09;
background-color: $bg0;
margin: 3pt;
}
.swap-section-label { .swap-section-label {
font-size: 0.62em; font-size: 0.62em;
@@ -175,10 +145,7 @@
} }
// Battery ring // Battery ring
.bat-ring { .bat-ring { margin: 4pt; }
background-color: $bg0;
margin: 4pt;
}
.bat-ring-label { .bat-ring-label {
font-size: 0.7em; font-size: 0.7em;

View File

@@ -18,10 +18,6 @@
border-color: $base04; border-color: $base04;
} }
@mixin test {
}
/* GENERAL */ /* GENERAL */
* { * {
@@ -49,25 +45,12 @@ tooltip {
font-weight: 900; font-weight: 900;
} }
.grey { /* WORKSPACE COLORS - emitted dynamically by scripts/workspaces as class names */
color: $base02; .grey { color: $base02; }
} .red { color: $base0F; }
.orange { color: $base08; }
.red { .green { color: $base0B; }
color: $base0F; .blue { color: $base0C; }
}
.orange {
color: $base08;
}
.green {
color: $base0B;
}
.blue {
color: $base0C;
}
/* WINDOW WRAPPER CSS */ /* WINDOW WRAPPER CSS */

View File

@@ -1,5 +1,5 @@
(deflisten net (deflisten net
:initial '{"wifi":{"connected":false,"icon":"󰤮","ssid":""},"ethernet":{"connected":false}}' :initial '{"wifi":{"connected":false,"enabled":false,"icon":"󰤮","ssid":""},"ethernet":{"connected":false},"usb":{"connected":false}}'
"scripts/net/net") "scripts/net/net")
(deflisten bluetooth (deflisten bluetooth
@@ -15,6 +15,11 @@
:class "net-icon ${net.ethernet.connected ? 'net-active' : 'net-dim'}" :class "net-icon ${net.ethernet.connected ? 'net-active' : 'net-dim'}"
:tooltip {net.ethernet.connected ? "Ethernet: Connected" : "Ethernet: Disconnected"} :tooltip {net.ethernet.connected ? "Ethernet: Connected" : "Ethernet: Disconnected"}
:text "󰈀") :text "󰈀")
(label
:visible {net.usb.connected}
:class "net-icon net-active"
:tooltip "USB: Connected"
:text "󰌷")
(label (label
:class "net-icon ${net.wifi.connected ? 'net-active' : 'net-dim'}" :class "net-icon ${net.wifi.connected ? 'net-active' : 'net-dim'}"
:tooltip {net.wifi.connected ? "WiFi: ${net.wifi.ssid}" : "WiFi: Disconnected"} :tooltip {net.wifi.connected ? "WiFi: ${net.wifi.ssid}" : "WiFi: Disconnected"}

View File

@@ -1,4 +1,3 @@
(deflisten cpu :initial '{}' "scripts/sys/cpu")
(deflisten gpu :initial '{"gfx_pct":0,"mem_pct":0,"media_pct":0,"sclk":0,"mclk":0,"sclk_pct":0,"mclk_pct":0,"vclk":0,"vclk_pct":0,"temp":0,"power":0,"vram_used":0,"vram_total":1}' "scripts/sys/gpu") (deflisten gpu :initial '{"gfx_pct":0,"mem_pct":0,"media_pct":0,"sclk":0,"mclk":0,"sclk_pct":0,"mclk_pct":0,"vclk":0,"vclk_pct":0,"temp":0,"power":0,"vram_used":0,"vram_total":1}' "scripts/sys/gpu")
(deflisten memory :initial '{"human":{"used":"0G","total":"0G","cached":"0G"},"used":0.0,"total":1.0,"cached":0.0}' "scripts/sys/memory") (deflisten memory :initial '{"human":{"used":"0G","total":"0G","cached":"0G"},"used":0.0,"total":1.0,"cached":0.0}' "scripts/sys/memory")

View File

@@ -6,6 +6,7 @@ emit() {
if bluetoothctl show 2>/dev/null | grep -q "Powered: yes"; then if bluetoothctl show 2>/dev/null | grep -q "Powered: yes"; then
powered=true powered=true
while IFS= read -r line; do while IFS= read -r line; do
local mac info
mac=$(echo "$line" | awk '{ print $2 }') mac=$(echo "$line" | awk '{ print $2 }')
info=$(bluetoothctl info "$mac" 2>/dev/null) info=$(bluetoothctl info "$mac" 2>/dev/null)
if echo "$info" | grep -q "Connected: yes"; then if echo "$info" | grep -q "Connected: yes"; then
@@ -20,8 +21,18 @@ emit() {
} }
emit emit
bluetoothctl monitor 2>/dev/null | while IFS= read -r line; do
case "$line" in tmp=$(mktemp -d)
*"Powered"*|*"Connected"*|*"Device"*) emit ;; pipe="$tmp/bt-events"
esac mkfifo "$pipe"
trap 'rm -rf "$tmp"; kill 0 2>/dev/null' EXIT INT TERM
# Poll every 2s as reliable fallback for missed events
(while true; do sleep 2; 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 done

View File

@@ -4,6 +4,13 @@ get_wifi_iface() {
awk 'NR > 2 { gsub(":", "", $1); print $1; exit }' /proc/net/wireless 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 }
'
}
signal_icon() { signal_icon() {
local dbm="$1" local dbm="$1"
if [ -z "$dbm" ]; then echo "󰤮"; return; fi if [ -z "$dbm" ]; then echo "󰤮"; return; fi
@@ -27,8 +34,18 @@ make_content() {
[ "$eth_state" = "UP" ] && eth_connected=true [ "$eth_state" = "UP" ] && eth_connected=true
fi 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) # WiFi — use IP presence as connection indicator (more reliable than wpa_cli)
local wifi_connected=false wifi_icon="󰤮" wifi_ssid="" 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 if [ -n "$wifi_iface" ] && ip -4 addr show "$wifi_iface" 2>/dev/null | grep -q "inet "; then
wifi_connected=true wifi_connected=true
wifi_ssid=$(wpa_cli -g "/run/wpa_supplicant/$wifi_iface" status 2>/dev/null \ wifi_ssid=$(wpa_cli -g "/run/wpa_supplicant/$wifi_iface" status 2>/dev/null \
@@ -37,8 +54,8 @@ make_content() {
wifi_icon=$(signal_icon "$signal") wifi_icon=$(signal_icon "$signal")
fi fi
printf '{"wifi":{"connected":%s,"icon":"%s","ssid":"%s"},"ethernet":{"connected":%s}}\n' \ printf '{"wifi":{"connected":%s,"enabled":%s,"icon":"%s","ssid":"%s"},"ethernet":{"connected":%s},"usb":{"connected":%s}}\n' \
"$wifi_connected" "$wifi_icon" "$wifi_ssid" "$eth_connected" "$wifi_connected" "$wifi_enabled" "$wifi_icon" "$wifi_ssid" "$eth_connected" "$usb_connected"
} }
make_content make_content

View File

@@ -4,6 +4,13 @@ get_wifi_iface() {
awk 'NR > 2 { gsub(":", "", $1); print $1; exit }' /proc/net/wireless 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() { freq_band() {
local f="$1" local f="$1"
if [ "$f" -ge 6000 ] 2>/dev/null; then echo "6 GHz" if [ "$f" -ge 6000 ] 2>/dev/null; then echo "6 GHz"
@@ -51,11 +58,19 @@ make_content() {
fi fi
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 # shellcheck disable=SC2059
printf '{"wifi":{"ssid":"%s","ip":"%s","freq":%s,"band":"%s","gen":"%s","signal":%s},' \ 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}" "$wifi_ssid" "$wifi_ip" "${wifi_freq:-0}" "$wifi_band" "$wifi_gen" "${wifi_signal:-0}"
printf '"ethernet":{"state":"%s","ip":"%s","speed":"%s","interface":"%s"}}\n' \ printf '"ethernet":{"state":"%s","ip":"%s","speed":"%s","interface":"%s"},' \
"$eth_state" "$eth_ip" "$eth_speed" "${eth_iface:-}" "$eth_state" "$eth_ip" "$eth_speed" "${eth_iface:-}"
printf '"usb":{"interface":"%s","ip":"%s"}}\n' \
"${usb_iface:-}" "$usb_ip"
} }
make_content make_content

View File

@@ -1 +0,0 @@
#!/usr/bin/env zsh

View File

@@ -1,25 +1,37 @@
(defpoll netinfo (deflisten netinfo
:interval "5s" :initial '{"wifi":{"ssid":"","ip":"","freq":0,"band":"","gen":"","signal":0},"ethernet":{"state":"down","ip":"","speed":"","interface":""},"usb":{"interface":"","ip":""}}'
:initial '{"wifi":{"ssid":"","ip":"","freq":0,"band":"","gen":"","signal":0},"ethernet":{"state":"down","ip":"","speed":"","interface":""}}'
"scripts/net/netinfo") "scripts/net/netinfo")
(deflisten bt-devices (deflisten bt-devices
:initial "[]" :initial "[]"
"scripts/net/bt-devices") "scripts/net/bt-devices")
; --- Shared row widget --- ; --- Shared widgets ---
(defwidget netinfo-row [label value] (defwidget netinfo-row [label value]
(box :orientation "h" :space-evenly false :class "netinfo-row" (box :orientation "h" :space-evenly false :class "netinfo-row"
(label :class "netinfo-label" :halign "start" :text label) (label :class "netinfo-label" :halign "start" :text label)
(label :class "netinfo-value" :halign "end" :hexpand true :text value))) (label :class "netinfo-value" :halign "end" :hexpand true :text value)))
(defwidget section-header-toggle [title accent enabled onclick icon-on icon-off]
(box :orientation "h" :space-evenly false :valign "center" :class "sys-section-header"
(box :class "section-accent ${accent}")
(label :class "sys-label" :text title :hexpand true :halign "start")
(button
:class "net-toggle-btn ${enabled ? 'net-toggle-on' : 'net-toggle-off'}"
:onclick onclick
(label :text {enabled ? icon-on : icon-off}))))
; --- WiFi --- ; --- WiFi ---
(defwidget wifi-net-section [] (defwidget wifi-net-section []
(box :orientation "v" :space-evenly false :class "sys-section" (box :orientation "v" :space-evenly false :class "sys-section"
(section-header :title "WiFi" :accent "wifi-accent") (section-header-toggle
:title "WiFi" :accent "wifi-accent"
:enabled {net.wifi.enabled}
:onclick {net.wifi.enabled ? "rfkill block wlan" : "rfkill unblock wlan"}
:icon-on "󰤨" :icon-off "󰖪")
(box :orientation "v" :space-evenly false (box :orientation "v" :space-evenly false
:visible {net.wifi.connected} :visible {net.wifi.connected}
(netinfo-row :label "SSID" :value {netinfo.wifi.ssid}) (netinfo-row :label "SSID" :value {netinfo.wifi.ssid})
@@ -28,7 +40,15 @@
(netinfo-row :label "Freq" :value "${netinfo.wifi.freq} MHz · ${netinfo.wifi.band} · ${netinfo.wifi.gen}")) (netinfo-row :label "Freq" :value "${netinfo.wifi.freq} MHz · ${netinfo.wifi.band} · ${netinfo.wifi.gen}"))
(label :class "netinfo-dim" :halign "start" (label :class "netinfo-dim" :halign "start"
:visible {!net.wifi.connected} :visible {!net.wifi.connected}
:text "Not connected"))) :text {net.wifi.enabled ? "Not connected" : "Disabled"})))
; --- USB ---
(defwidget usb-net-section []
(box :orientation "v" :space-evenly false :class "sys-section"
(section-header :title "USB" :accent "usb-accent")
(netinfo-row :label "Interface" :value {netinfo.usb.interface})
(netinfo-row :label "IP" :value {netinfo.usb.ip})))
; --- Ethernet --- ; --- Ethernet ---
@@ -57,19 +77,31 @@
(defwidget bluetooth-net-section [] (defwidget bluetooth-net-section []
(box :orientation "v" :space-evenly false :class "sys-section" (box :orientation "v" :space-evenly false :class "sys-section"
(section-header :title "Bluetooth" :accent "blt-accent") (section-header-toggle
(box :orientation "v" :space-evenly false :title "Bluetooth" :accent "blt-accent"
(for device in {bt-devices} :enabled {bluetooth.powered}
(bt-device-row :device {device}))))) :onclick {bluetooth.powered ? "bluetoothctl power off" : "bluetoothctl power on"}
:icon-on "󰂯" :icon-off "󰂲")
(scroll :vscroll true :hscroll false :height 90
:visible {bluetooth.powered}
(box :orientation "v" :space-evenly false
(for device in {bt-devices}
(bt-device-row :device {device}))))
(label :class "netinfo-dim" :halign "start"
:visible {!bluetooth.powered}
:text "Disabled")))
; --- Root --- ; --- Root ---
(defwidget net-win [] (defwidget net-win []
(box :class "sys-win" :space-evenly false :orientation "v" (box :class "sys-win" :space-evenly false :orientation "v"
(wifi-net-section) (box :visible {net.usb.connected} :space-evenly false :orientation "v"
(box :class "section-sep") (usb-net-section)
(box :class "section-sep"))
(ethernet-net-section) (ethernet-net-section)
(box :class "section-sep") (box :class "section-sep")
(wifi-net-section)
(box :class "section-sep")
(bluetooth-net-section))) (bluetooth-net-section)))
(defwindow net (defwindow net