From ce804942a92d85caf15aa65413a001c354ccd3f1 Mon Sep 17 00:00:00 2001 From: soraefir Date: Fri, 12 Jun 2026 23:49:38 +0200 Subject: [PATCH] radio-win --- .claude/settings.local.json | 14 ----- .../home/wayland/apps/eww/bar/css/_clock.scss | 3 - .../home/wayland/apps/eww/bar/css/_net.scss | 23 ++++++-- .../home/wayland/apps/eww/bar/css/_radio.scss | 7 +-- .../home/wayland/apps/eww/bar/css/_sys.scss | 57 ++++--------------- modules/home/wayland/apps/eww/bar/eww.scss | 29 ++-------- .../wayland/apps/eww/bar/modules/net.yuck | 7 ++- .../wayland/apps/eww/bar/modules/sys.yuck | 1 - .../apps/eww/bar/scripts/net/bluetooth | 19 +++++-- .../home/wayland/apps/eww/bar/scripts/net/net | 23 +++++++- .../wayland/apps/eww/bar/scripts/net/netinfo | 17 +++++- .../home/wayland/apps/eww/bar/scripts/sys/cpu | 1 - .../wayland/apps/eww/bar/windows/net.yuck | 56 ++++++++++++++---- 13 files changed, 140 insertions(+), 117 deletions(-) delete mode 100644 .claude/settings.local.json delete mode 100755 modules/home/wayland/apps/eww/bar/scripts/sys/cpu diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index d2781da..0000000 --- a/.claude/settings.local.json +++ /dev/null @@ -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)" - ] - } -} diff --git a/modules/home/wayland/apps/eww/bar/css/_clock.scss b/modules/home/wayland/apps/eww/bar/css/_clock.scss index 726f2d1..a21aae3 100644 --- a/modules/home/wayland/apps/eww/bar/css/_clock.scss +++ b/modules/home/wayland/apps/eww/bar/css/_clock.scss @@ -1,6 +1,3 @@ -.calendar-win { -} - calendar { padding: 5pt; diff --git a/modules/home/wayland/apps/eww/bar/css/_net.scss b/modules/home/wayland/apps/eww/bar/css/_net.scss index 1ae5ee6..7d930ca 100644 --- a/modules/home/wayland/apps/eww/bar/css/_net.scss +++ b/modules/home/wayland/apps/eww/bar/css/_net.scss @@ -1,14 +1,14 @@ // Bar icons -.net-icon { font-size: 14px; padding: 3pt 0; } -.net-active { color: $base07; } -.net-dim { color: $base02; } -.blt-on { color: $base07; } -.blt-connected { color: $base0D; } +.net-icon { font-size: 14px; padding: 3pt 0; } +.net-active, .blt-on { color: $base07; } +.net-dim { color: $base02; } +.blt-connected { color: $base0D; } // Popup window section accents .wifi-accent { background-color: $base0C; } .eth-accent { background-color: $base0B; } .blt-accent { background-color: $base0D; } +.usb-accent { background-color: $base09; } // Netinfo rows .netinfo-row { margin-bottom: 3pt; } @@ -16,9 +16,22 @@ .netinfo-value { font-size: 0.72em; color: $base05; } .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 .bt-device-row { margin-bottom: 4pt; } .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:hover { background-color: $base02; } .bt-btn-on { color: $base0D; } .bt-btn-off { color: $base03; } diff --git a/modules/home/wayland/apps/eww/bar/css/_radio.scss b/modules/home/wayland/apps/eww/bar/css/_radio.scss index 5aa4872..b71e919 100644 --- a/modules/home/wayland/apps/eww/bar/css/_radio.scss +++ b/modules/home/wayland/apps/eww/bar/css/_radio.scss @@ -1,8 +1,7 @@ - .radio-win { - //margin: $gaps-screen; - //padding: .5em; - } + //margin: $gaps-screen; + //padding: .5em; +} .album_art { background-repeat: no-repeat; diff --git a/modules/home/wayland/apps/eww/bar/css/_sys.scss b/modules/home/wayland/apps/eww/bar/css/_sys.scss index b4e5a08..109f362 100644 --- a/modules/home/wayland/apps/eww/bar/css/_sys.scss +++ b/modules/home/wayland/apps/eww/bar/css/_sys.scss @@ -4,11 +4,7 @@ .gpubar { color: $base0E; } .membar { color: $base08; } .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 .sys-win { @@ -47,26 +43,17 @@ margin: 6pt 0 10pt 0; } -.sys-sublabel { - font-size: 0.72em; - color: $base04; - margin-right: 8pt; -} +// All rings share the same track background +.cpu-usage-ring, .cpu-freq-ring, +.gpu-ring, .gpu-freq-ring, +.ram-ring, .swap-ring, .bat-ring { background-color: $bg0; } // CPU grid -.cpu-usage-ring { - color: $base0C; - background-color: $bg0; - margin: 3pt; -} +.cpu-usage-ring { color: $base0C; margin: 3pt; } // Inner freq ring — margin shrinks it inside overlay for concentric effect // 0% = cpu min freq, 100% = cpu max freq -.cpu-freq-ring { - color: $base0D; - background-color: $bg0; - margin: 12px; -} +.cpu-freq-ring { color: $base0D; margin: 12px; } .cpu-core-label { font-size: 0.7em; @@ -74,17 +61,8 @@ } // GPU rings -.gpu-ring { - color: $base0E; - background-color: $bg0; - margin: 3pt; -} - -.gpu-freq-ring { - color: $base0D; - background-color: $bg0; - margin: 13px; -} +.gpu-ring { color: $base0E; margin: 3pt; } +.gpu-freq-ring { color: $base0D; margin: 13px; } .gpu-ring-value { font-size: 0.82em; @@ -138,11 +116,7 @@ } // RAM ring -.ram-ring { - color: $base08; - background-color: $bg0; - margin: 4pt; -} +.ram-ring { color: $base08; margin: 4pt; } .ram-cached-ring { color: $base02; @@ -162,11 +136,7 @@ } // Swap ring -.swap-ring { - color: $base09; - background-color: $bg0; - margin: 3pt; -} +.swap-ring { color: $base09; margin: 3pt; } .swap-section-label { font-size: 0.62em; @@ -175,10 +145,7 @@ } // Battery ring -.bat-ring { - background-color: $bg0; - margin: 4pt; -} +.bat-ring { margin: 4pt; } .bat-ring-label { font-size: 0.7em; diff --git a/modules/home/wayland/apps/eww/bar/eww.scss b/modules/home/wayland/apps/eww/bar/eww.scss index 5dfb04b..14442b9 100644 --- a/modules/home/wayland/apps/eww/bar/eww.scss +++ b/modules/home/wayland/apps/eww/bar/eww.scss @@ -18,10 +18,6 @@ border-color: $base04; } -@mixin test { - -} - /* GENERAL */ * { @@ -49,25 +45,12 @@ tooltip { font-weight: 900; } -.grey { - color: $base02; -} - -.red { - color: $base0F; -} - -.orange { - color: $base08; -} - -.green { - color: $base0B; -} - -.blue { - color: $base0C; -} +/* WORKSPACE COLORS - emitted dynamically by scripts/workspaces as class names */ +.grey { color: $base02; } +.red { color: $base0F; } +.orange { color: $base08; } +.green { color: $base0B; } +.blue { color: $base0C; } /* WINDOW WRAPPER CSS */ diff --git a/modules/home/wayland/apps/eww/bar/modules/net.yuck b/modules/home/wayland/apps/eww/bar/modules/net.yuck index 60dcc80..d060384 100644 --- a/modules/home/wayland/apps/eww/bar/modules/net.yuck +++ b/modules/home/wayland/apps/eww/bar/modules/net.yuck @@ -1,5 +1,5 @@ (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") (deflisten bluetooth @@ -15,6 +15,11 @@ :class "net-icon ${net.ethernet.connected ? 'net-active' : 'net-dim'}" :tooltip {net.ethernet.connected ? "Ethernet: Connected" : "Ethernet: Disconnected"} :text "󰈀") + (label + :visible {net.usb.connected} + :class "net-icon net-active" + :tooltip "USB: Connected" + :text "󰌷") (label :class "net-icon ${net.wifi.connected ? 'net-active' : 'net-dim'}" :tooltip {net.wifi.connected ? "WiFi: ${net.wifi.ssid}" : "WiFi: Disconnected"} diff --git a/modules/home/wayland/apps/eww/bar/modules/sys.yuck b/modules/home/wayland/apps/eww/bar/modules/sys.yuck index 0d70bfe..e2559b1 100644 --- a/modules/home/wayland/apps/eww/bar/modules/sys.yuck +++ b/modules/home/wayland/apps/eww/bar/modules/sys.yuck @@ -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 memory :initial '{"human":{"used":"0G","total":"0G","cached":"0G"},"used":0.0,"total":1.0,"cached":0.0}' "scripts/sys/memory") diff --git a/modules/home/wayland/apps/eww/bar/scripts/net/bluetooth b/modules/home/wayland/apps/eww/bar/scripts/net/bluetooth index 3aa33be..8483bd3 100755 --- a/modules/home/wayland/apps/eww/bar/scripts/net/bluetooth +++ b/modules/home/wayland/apps/eww/bar/scripts/net/bluetooth @@ -6,6 +6,7 @@ emit() { 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 @@ -20,8 +21,18 @@ emit() { } emit -bluetoothctl monitor 2>/dev/null | while IFS= read -r line; do - case "$line" in - *"Powered"*|*"Connected"*|*"Device"*) emit ;; - esac + +tmp=$(mktemp -d) +pipe="$tmp/bt-events" +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 diff --git a/modules/home/wayland/apps/eww/bar/scripts/net/net b/modules/home/wayland/apps/eww/bar/scripts/net/net index 0630be7..bc27df3 100755 --- a/modules/home/wayland/apps/eww/bar/scripts/net/net +++ b/modules/home/wayland/apps/eww/bar/scripts/net/net @@ -4,6 +4,13 @@ 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 } + ' +} + signal_icon() { local dbm="$1" if [ -z "$dbm" ]; then echo "󰤮"; return; fi @@ -27,8 +34,18 @@ make_content() { [ "$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_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 wifi_connected=true 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") fi - printf '{"wifi":{"connected":%s,"icon":"%s","ssid":"%s"},"ethernet":{"connected":%s}}\n' \ - "$wifi_connected" "$wifi_icon" "$wifi_ssid" "$eth_connected" + 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" } make_content diff --git a/modules/home/wayland/apps/eww/bar/scripts/net/netinfo b/modules/home/wayland/apps/eww/bar/scripts/net/netinfo index b613bdc..2a313fa 100755 --- a/modules/home/wayland/apps/eww/bar/scripts/net/netinfo +++ b/modules/home/wayland/apps/eww/bar/scripts/net/netinfo @@ -4,6 +4,13 @@ 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" @@ -51,11 +58,19 @@ make_content() { 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"}}\n' \ + 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 diff --git a/modules/home/wayland/apps/eww/bar/scripts/sys/cpu b/modules/home/wayland/apps/eww/bar/scripts/sys/cpu deleted file mode 100755 index 8441a36..0000000 --- a/modules/home/wayland/apps/eww/bar/scripts/sys/cpu +++ /dev/null @@ -1 +0,0 @@ -#!/usr/bin/env zsh diff --git a/modules/home/wayland/apps/eww/bar/windows/net.yuck b/modules/home/wayland/apps/eww/bar/windows/net.yuck index 7ac8913..02f1fed 100644 --- a/modules/home/wayland/apps/eww/bar/windows/net.yuck +++ b/modules/home/wayland/apps/eww/bar/windows/net.yuck @@ -1,25 +1,37 @@ -(defpoll netinfo - :interval "5s" - :initial '{"wifi":{"ssid":"","ip":"","freq":0,"band":"","gen":"","signal":0},"ethernet":{"state":"down","ip":"","speed":"","interface":""}}' +(deflisten netinfo + :initial '{"wifi":{"ssid":"","ip":"","freq":0,"band":"","gen":"","signal":0},"ethernet":{"state":"down","ip":"","speed":"","interface":""},"usb":{"interface":"","ip":""}}' "scripts/net/netinfo") (deflisten bt-devices :initial "[]" "scripts/net/bt-devices") -; --- Shared row widget --- +; --- Shared widgets --- (defwidget netinfo-row [label value] (box :orientation "h" :space-evenly false :class "netinfo-row" (label :class "netinfo-label" :halign "start" :text label) (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 --- (defwidget wifi-net-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 :visible {net.wifi.connected} (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}")) (label :class "netinfo-dim" :halign "start" :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 --- @@ -57,19 +77,31 @@ (defwidget bluetooth-net-section [] (box :orientation "v" :space-evenly false :class "sys-section" - (section-header :title "Bluetooth" :accent "blt-accent") - (box :orientation "v" :space-evenly false - (for device in {bt-devices} - (bt-device-row :device {device}))))) + (section-header-toggle + :title "Bluetooth" :accent "blt-accent" + :enabled {bluetooth.powered} + :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 --- (defwidget net-win [] (box :class "sys-win" :space-evenly false :orientation "v" - (wifi-net-section) - (box :class "section-sep") + (box :visible {net.usb.connected} :space-evenly false :orientation "v" + (usb-net-section) + (box :class "section-sep")) (ethernet-net-section) (box :class "section-sep") + (wifi-net-section) + (box :class "section-sep") (bluetooth-net-section))) (defwindow net