chore: updated scripts to use icons 40e5da3a
Steve · 2026-08-19 23:54 14 file(s) · +175 −78
oxwm/config.lua +5 −2
77 77
        underline = false,
78 78
    }),
79 79
    -- SSID, "off" when the link is down, "none" without a wireless card.
80 +
    -- wifi-status supplies its own Nerd Font icon, which tracks signal
81 +
    -- strength while connected, so the format is just its output.
80 82
    -- Click opens the dmenu network menu (connect/disconnect wifi and eth0).
81 83
    oxwm.bar.block.shell({
82 -
        format = "Net: {}",
84 +
        format = "{}",
83 85
        command = scripts .. "/wifi-status",
84 86
        interval = 10,
85 87
        color = colors.lavender,
93 95
        underline = false,
94 96
    }),
95 97
    -- Volume percentage of the default sink; click toggles mute.
98 +
    -- vol-status supplies its own Nerd Font icon for the level (or mute).
96 99
    -- The vol-* keybinds also fire a notification, so this can lag a second.
97 100
    oxwm.bar.block.shell({
98 -
        format = "Vol: {}",
101 +
        format = "{}",
99 102
        command = scripts .. "/vol-status",
100 103
        interval = 2,
101 104
        color = colors.purple,
scripts/dm-eth0-connect +3 −3
22 22
23 23
[ "$(printf 'No\nYes\n' | dmenu -c -i -l 2 -p "Switch to $IFACE and disable $WIFI?")" = "Yes" ] || exit 0
24 24
25 -
notify "Switching to wired..."
25 +
notify "󰈀  Switching to wired..."
26 26
27 27
doas sh -c '
28 28
    ifdown "$2" 2>/dev/null
35 35
36 36
if ip addr show "$IFACE" | grep -q "inet "; then
37 37
    IP=$(ip -4 addr show "$IFACE" | awk '/inet /{print $2; exit}')
38 -
    notify "✓ $IFACE up — $IP"
38 +
    notify "󰈀  $IFACE up — $IP"
39 39
else
40 -
    fail "✗ $IFACE failed to come up"
40 +
    fail "󰲛  $IFACE failed to come up"
41 41
fi
scripts/dm-eth0-disable +2 −2
20 20
21 21
[ "$(printf 'No\nYes\n' | dmenu -c -i -l 2 -p "Disable $IFACE?")" = "Yes" ] || exit 0
22 22
23 -
notify "Disabling $IFACE..."
23 +
notify "󰲛  Disabling $IFACE..."
24 24
25 25
doas sh -c '
26 26
    ifdown "$1" 2>/dev/null
27 27
    ip link set "$1" down
28 28
' _ "$IFACE"
29 29
30 -
notify "$IFACE disabled"
30 +
notify "󰲛  $IFACE disabled"
scripts/dm-net-menu +34 −16
10 10
11 11
menu() { dmenu -c -i "$@"; }
12 12
13 -
# BusyBox's `ip` has no `-br`, so build the brief view by hand.
13 +
# BusyBox's `ip` has no `-br`, so build the brief view by hand. Each line is
14 +
# prefixed with a Nerd Font icon for what that interface is and how it is
15 +
# doing: 󰤨/󰤫/󰤭 wireless connected/no lease/down, 󰈀/󰲛 wired up/down.
14 16
net_status() {
15 -
    ip -4 addr show | awk '
16 -
        function flush() {
17 -
            if (iface != "") printf "%-16s %-8s %s\n", iface, state, addrs
18 -
        }
19 -
        /^[0-9]+: / {
20 -
            flush()
21 -
            iface = $2; sub(/:$/, "", iface)
22 -
            addrs = ""
23 -
            state = "DOWN"
24 -
            if ($0 ~ /state UP/) state = "UP"
25 -
            else if ($0 ~ /state UNKNOWN/) state = "UNKNOWN"
26 -
        }
27 -
        /^[[:space:]]*inet / { addrs = addrs (addrs ? " " : "") $2 }
28 -
        END { flush() }
29 -
    '
17 +
    for path in /sys/class/net/*; do
18 +
        iface=${path##*/}
19 +
        [ "$iface" = "lo" ] && continue
20 +
21 +
        state=$(cat "$path/operstate" 2>/dev/null || echo unknown)
22 +
        addrs=$(ip -4 addr show "$iface" 2>/dev/null |
23 +
            awk '/inet /{ printf "%s%s", (n++ ? " " : ""), $2 }')
24 +
25 +
        # Container veths and other virtual links with no address are noise;
26 +
        # a virtual interface that does carry one (tailscale0, docker0) is not.
27 +
        [ -z "$addrs" ] && [ ! -e "$path/device" ] && continue
28 +
29 +
        # Tunnels sit at operstate "unknown" for their whole life, so an
30 +
        # address is what actually says the link is carrying traffic.
31 +
        up=0
32 +
        case "$state" in
33 +
            up) up=1 ;;
34 +
            unknown) [ -n "$addrs" ] && up=1 ;;
35 +
        esac
36 +
37 +
        if [ -d "$path/wireless" ] || [ -e "$path/phy80211" ]; then
38 +
            if   [ "$up" -eq 0 ];  then icon="󰤭"
39 +
            elif [ -z "$addrs" ];  then icon="󰤫"
40 +
            else                        icon="󰤨"
41 +
            fi
42 +
        else
43 +
            if [ "$up" -eq 1 ]; then icon="󰈀"; else icon="󰲛"; fi
44 +
        fi
45 +
46 +
        printf '%s  %-12s %-8s %s\n' "$icon" "$iface" "$state" "$addrs"
47 +
    done
30 48
}
31 49
32 50
CHOICE=$(printf '%s\n' \
scripts/dm-wifi-connect +4 −4
46 46
47 47
doas ip link set "$IFACE" up 2>/dev/null
48 48
49 -
notify "Scanning for networks on $IFACE..."
49 +
notify "󰤬  Scanning for networks on $IFACE..."
50 50
51 51
# `scan dump` reuses cached results if the card is busy (already associated),
52 52
# which is when a live scan tends to fail.
87 87
    chmod 600 "$1"
88 88
' _ "$CONF" || fail "Could not write $CONF."
89 89
90 -
notify "Connecting to $SSID..."
90 +
notify "󰤨  Connecting to $SSID..."
91 91
92 92
doas sh -c '
93 93
    # wpa_supplicant is a supervised OpenRC service on this host and will not
121 121
122 122
if ip addr show "$IFACE" | grep -q "inet "; then
123 123
    IP=$(ip -4 addr show "$IFACE" | awk '/inet /{print $2; exit}')
124 -
    notify "✓ Connected to $SSID on $IFACE — $IP"
124 +
    notify "$("$(dirname "$0")/wifi-status" "$IFACE")  on $IFACE — $IP"
125 125
else
126 -
    fail "✗ Failed to connect to $SSID"
126 +
    fail "󰤮  Failed to connect to $SSID"
127 127
fi
scripts/dm-wifi-disable +2 −2
24 24
# Default to No so a stray Enter never takes the link down.
25 25
[ "$(printf 'No\nYes\n' | dmenu -c -i -l 2 -p "Disable WiFi on $IFACE?")" = "Yes" ] || exit 0
26 26
27 -
notify "Disabling $IFACE..."
27 +
notify "󰤭  Disabling $IFACE..."
28 28
29 29
doas sh -c '
30 30
    # wpa_supplicant runs under supervise-daemon (supervisor= in
48 48
    ip link set "$1" down
49 49
' _ "$IFACE"
50 50
51 -
notify "$IFACE disabled"
51 +
notify "󰤭  $IFACE disabled"
scripts/eth0-connect +2 −2
21 21
22 22
if ip addr show "$IFACE" | grep -q "inet "; then
23 23
    IP=$(ip -4 addr show "$IFACE" | grep inet | awk '{print $2}')
24 -
    gum style --foreground 46 --bold "✓ $IFACE up — $IP"
24 +
    gum style --foreground 46 --bold "󰈀  $IFACE up — $IP"
25 25
else
26 -
    gum style --foreground 196 --bold "✗ $IFACE failed to come up"
26 +
    gum style --foreground 196 --bold "󰲛  $IFACE failed to come up"
27 27
fi
scripts/eth0-disable +1 −1
16 16
    ip link set "$1" down
17 17
' _ "$IFACE"
18 18
19 -
gum style --foreground 214 "$IFACE disabled"
19 +
gum style --foreground 214 "󰲛  $IFACE disabled"
scripts/net-menu +34 −16
2 2
# Resolve the sibling scripts relative to this one rather than through PATH.
3 3
DIR=$(dirname "$0")
4 4
5 -
# BusyBox's `ip` has no `-br`, so build the brief view by hand.
5 +
# BusyBox's `ip` has no `-br`, so build the brief view by hand. Each line is
6 +
# prefixed with a Nerd Font icon for what that interface is and how it is
7 +
# doing: 󰤨/󰤫/󰤭 wireless connected/no lease/down, 󰈀/󰲛 wired up/down.
6 8
net_status() {
7 -
    ip -4 addr show | awk '
8 -
        function flush() {
9 -
            if (iface != "") printf "%-16s %-8s %s\n", iface, state, addrs
10 -
        }
11 -
        /^[0-9]+: / {
12 -
            flush()
13 -
            iface = $2; sub(/:$/, "", iface)
14 -
            addrs = ""
15 -
            state = "DOWN"
16 -
            if ($0 ~ /state UP/) state = "UP"
17 -
            else if ($0 ~ /state UNKNOWN/) state = "UNKNOWN"
18 -
        }
19 -
        /^[[:space:]]*inet / { addrs = addrs (addrs ? " " : "") $2 }
20 -
        END { flush() }
21 -
    '
9 +
    for path in /sys/class/net/*; do
10 +
        iface=${path##*/}
11 +
        [ "$iface" = "lo" ] && continue
12 +
13 +
        state=$(cat "$path/operstate" 2>/dev/null || echo unknown)
14 +
        addrs=$(ip -4 addr show "$iface" 2>/dev/null |
15 +
            awk '/inet /{ printf "%s%s", (n++ ? " " : ""), $2 }')
16 +
17 +
        # Container veths and other virtual links with no address are noise;
18 +
        # a virtual interface that does carry one (tailscale0, docker0) is not.
19 +
        [ -z "$addrs" ] && [ ! -e "$path/device" ] && continue
20 +
21 +
        # Tunnels sit at operstate "unknown" for their whole life, so an
22 +
        # address is what actually says the link is carrying traffic.
23 +
        up=0
24 +
        case "$state" in
25 +
            up) up=1 ;;
26 +
            unknown) [ -n "$addrs" ] && up=1 ;;
27 +
        esac
28 +
29 +
        if [ -d "$path/wireless" ] || [ -e "$path/phy80211" ]; then
30 +
            if   [ "$up" -eq 0 ];  then icon="󰤭"
31 +
            elif [ -z "$addrs" ];  then icon="󰤫"
32 +
            else                        icon="󰤨"
33 +
            fi
34 +
        else
35 +
            if [ "$up" -eq 1 ]; then icon="󰈀"; else icon="󰲛"; fi
36 +
        fi
37 +
38 +
        printf '%s  %-12s %-8s %s\n' "$icon" "$iface" "$state" "$addrs"
39 +
    done
22 40
}
23 41
24 42
CHOICE=$(gum choose "Connect to WiFi" "Disable WiFi" "Connect eth0" "Disable eth0" "Show status" "Quit")
scripts/vol-mute +3 −3
18 18
19 19
wpctl set-mute "$TARGET" "$ARG" || exit 1
20 20
21 +
# vol-status carries the icon logic for both devices, so hand the reporting
22 +
# (and the notification) off to it either way.
21 23
if [ "$TARGET" = "@DEFAULT_AUDIO_SOURCE@" ]; then
22 -
    STATE=$(wpctl get-volume @DEFAULT_AUDIO_SOURCE@ 2>/dev/null)
23 -
    case "$STATE" in *MUTED*) echo "mic muted" ;; *) echo "mic live" ;; esac
24 -
    exit 0
24 +
    exec "$(dirname "$0")/vol-status" -s -n
25 25
fi
26 26
27 27
exec "$(dirname "$0")/vol-status" -n
scripts/vol-status +43 −15
1 1
#!/bin/sh
2 2
# Requires: wireplumber (wpctl), optionally libnotify
3 -
# Prints the default sink's volume. Shared by vol-up / vol-down / vol-mute.
4 -
# Usage: vol-status [-n]   -n also fires a desktop notification
3 +
# Prints the default sink's volume with a Nerd Font icon for its level.
4 +
# Shared by vol-up / vol-down / vol-mute and the status bar.
5 +
# Usage: vol-status [-n] [-p] [-s]
6 +
#   -n  also fire a desktop notification
7 +
#   -p  plain output, no Nerd Font icon (for terminals without one)
8 +
#   -s  report the default source (microphone) instead of the sink
5 9
set -u
6 10
7 11
NOTIFY=0
8 -
[ "${1:-}" = "-n" ] && NOTIFY=1
12 +
PLAIN=0
13 +
TARGET="@DEFAULT_AUDIO_SINK@"
14 +
LABEL="Volume"
15 +
16 +
while [ $# -gt 0 ]; do
17 +
    case "$1" in
18 +
        -n|--notify) NOTIFY=1 ;;
19 +
        -p|--plain)  PLAIN=1 ;;
20 +
        -s|--source) TARGET="@DEFAULT_AUDIO_SOURCE@"; LABEL="Microphone" ;;
21 +
        *) echo "usage: vol-status [-n] [-p] [-s]" >&2; exit 2 ;;
22 +
    esac
23 +
    shift
24 +
done
9 25
10 -
RAW=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ 2>/dev/null)
26 +
RAW=$(wpctl get-volume "$TARGET" 2>/dev/null)
11 27
if [ -z "$RAW" ]; then
12 -
    echo "vol-status: no default sink (is pipewire/wireplumber running?)" >&2
28 +
    echo "vol-status: no default device (is pipewire/wireplumber running?)" >&2
13 29
    exit 1
14 30
fi
15 31
20 36
    *)       MUTED=0 ;;
21 37
esac
22 38
23 -
if [ "$MUTED" -eq 1 ]; then
24 -
    TEXT="muted ($PCT%)"
25 -
    ICON="audio-volume-muted"
39 +
# Two icon sets: speaker glyphs for the sink, mic glyphs for the source.
40 +
# ICON is the Nerd Font glyph in the bar; FDO is the freedesktop icon name
41 +
# the notification daemon looks up in the icon theme.
42 +
if [ "$TARGET" = "@DEFAULT_AUDIO_SOURCE@" ]; then
43 +
    if [ "$MUTED" -eq 1 ]; then
44 +
        ICON="󰍭"; FDO="microphone-sensitivity-muted"; TEXT="muted"
45 +
    else
46 +
        ICON="󰍬"; FDO="microphone-sensitivity-high";  TEXT="$PCT%"
47 +
    fi
48 +
elif [ "$MUTED" -eq 1 ]; then
49 +
    ICON="󰝟"; FDO="audio-volume-muted"; TEXT="muted ($PCT%)"
26 50
else
27 51
    TEXT="$PCT%"
28 -
    if   [ "$PCT" -ge 66 ]; then ICON="audio-volume-high"
29 -
    elif [ "$PCT" -ge 33 ]; then ICON="audio-volume-medium"
30 -
    elif [ "$PCT" -gt 0 ];  then ICON="audio-volume-low"
31 -
    else                         ICON="audio-volume-muted"
52 +
    if   [ "$PCT" -ge 66 ]; then ICON="󰕾"; FDO="audio-volume-high"
53 +
    elif [ "$PCT" -ge 33 ]; then ICON="󰖀"; FDO="audio-volume-medium"
54 +
    elif [ "$PCT" -gt 0 ];  then ICON="󰕿"; FDO="audio-volume-low"
55 +
    else                         ICON="󰝟"; FDO="audio-volume-muted"
32 56
    fi
33 57
fi
34 58
35 -
echo "$TEXT"
59 +
if [ "$PLAIN" -eq 1 ]; then
60 +
    echo "$TEXT"
61 +
else
62 +
    echo "$ICON  $TEXT"
63 +
fi
36 64
37 65
# Only bother with notifications when there is a session to show them in.
38 66
[ "$NOTIFY" -eq 1 ] || exit 0
41 69
42 70
notify-send \
43 71
    -a volume \
44 -
    -i "$ICON" \
72 +
    -i "$FDO" \
45 73
    -h string:x-canonical-private-synchronous:volume \
46 74
    -h "int:value:$PCT" \
47 -
    "Volume" "$TEXT"
75 +
    "$ICON  $LABEL" "$TEXT"
scripts/wifi-connect +2 −2
110 110
' _ "$IFACE"
111 111
112 112
if ip addr show "$IFACE" | grep -q "inet "; then
113 -
    gum style --foreground 46 --bold "✓ Connected to $SSID on $IFACE"
113 +
    gum style --foreground 46 --bold "$("$(dirname "$0")/wifi-status" "$IFACE")  connected on $IFACE"
114 114
else
115 -
    gum style --foreground 196 --bold "✗ Failed to connect to $SSID"
115 +
    gum style --foreground 196 --bold "󰤮  Failed to connect to $SSID"
116 116
fi
scripts/wifi-disable +1 −1
33 33
    ip link set "$1" down
34 34
' _ "$IFACE"
35 35
36 -
gum style --foreground 214 "$IFACE disabled"
36 +
gum style --foreground 214 "󰤭  $IFACE disabled"
scripts/wifi-status +39 −9
1 1
#!/bin/sh
2 2
# Requires: iw
3 -
# Prints the wireless link state, for the status bar and menus.
4 -
# Usage: wifi-status [IFACE]   (default: first wireless interface)
3 +
# Prints the wireless link state with a Nerd Font icon, for the status bar
4 +
# and menus. The icon tracks signal strength while connected, so it moves
5 +
# as the link does.
6 +
# Usage: wifi-status [-p|--plain] [IFACE]   (default: first wireless interface)
5 7
set -u
6 8
9 +
PLAIN=0
10 +
case "${1:-}" in
11 +
    -p|--plain) PLAIN=1; shift ;;
12 +
esac
13 +
14 +
# ICON_ONLY/no-icon output goes through this so every exit path is consistent.
15 +
say() {
16 +
    if [ "$PLAIN" -eq 1 ]; then
17 +
        echo "$2"
18 +
    else
19 +
        echo "$1  $2"
20 +
    fi
21 +
}
22 +
7 23
# Ask the kernel which interfaces are wireless rather than assuming wlan0.
8 24
IFACE="${1:-$(iw dev 2>/dev/null | awk '$1 == "Interface" { print $2; exit }')}"
9 25
26 +
# 󰤮 no wireless hardware at all, 󰤭 card present but down/unassociated,
27 +
# 󰤫 associated without a lease, 󰤟󰤢󰤥󰤨 connected at rising signal strength.
10 28
if [ -z "$IFACE" ]; then
11 -
    echo "none"
29 +
    say "󰤮" "none"
12 30
    exit 0
13 31
fi
14 32
15 33
# `iw link` prints "Not connected." while the card is up but unassociated, and
16 34
# fails outright once wifi-disable has downed the link.
17 -
LINK=$(iw dev "$IFACE" link 2>/dev/null) || { echo "off"; exit 0; }
35 +
LINK=$(iw dev "$IFACE" link 2>/dev/null) || { say "󰤭" "off"; exit 0; }
18 36
19 37
case "$LINK" in
20 38
    "Connected to"*) ;;
21 -
    *) echo "off"; exit 0 ;;
39 +
    *) say "󰤭" "off"; exit 0 ;;
22 40
esac
23 41
24 42
SSID=$(printf '%s\n' "$LINK" | sed -n 's/^[[:space:]]*SSID: \(..*\)$/\1/p')
26 44
27 45
# Associated but without a lease carries no traffic — say so rather than
28 46
# showing a network name that looks connected.
29 -
if ip addr show "$IFACE" 2>/dev/null | grep -q "inet "; then
30 -
    echo "$SSID"
31 -
else
32 -
    echo "$SSID (no ip)"
47 +
if ! ip addr show "$IFACE" 2>/dev/null | grep -q "inet "; then
48 +
    say "󰤫" "$SSID (no ip)"
49 +
    exit 0
33 50
fi
51 +
52 +
# "signal: -47 dBm" — the thresholds are the usual rule of thumb: better than
53 +
# -50 is excellent, -70 is the edge of usable.
54 +
DBM=$(printf '%s\n' "$LINK" | awk '/signal:/ { printf "%d", $2; exit }')
55 +
56 +
if [ -z "$DBM" ];      then ICON="󰤨"   # no signal line (some drivers) — assume good
57 +
elif [ "$DBM" -ge -50 ]; then ICON="󰤨"
58 +
elif [ "$DBM" -ge -60 ]; then ICON="󰤥"
59 +
elif [ "$DBM" -ge -70 ]; then ICON="󰤢"
60 +
else                         ICON="󰤟"
61 +
fi
62 +
63 +
say "$ICON" "$SSID"