eww QoL update and vpn toggle

This commit is contained in:
Jonas H
2026-08-04 11:36:51 +02:00
parent cda919c383
commit da0df79afc
8 changed files with 499 additions and 197 deletions

View File

@@ -1,201 +1,219 @@
*{
* {
all: unset;
}
// ---------------------------------------------------------------------------
// Tokens
// ---------------------------------------------------------------------------
$font-family: "JetBrainsMono Nerd Font", monospace;
$bg-bar: #000000;
$bg-popup: #0d0d0d;
$border: #2a2a2a;
$track: #3a3a3a;
$accent: #E0AF68;
$urgent: #F7768E;
$fg: #ffffff;
$fg-dim: #9a9a9a;
// Legacy aliases
$background: $bg-bar;
$foreground: $fg;
// Spacing. Widget-to-widget gaps live in eww.yuck (`gap` / `gap-tight`).
// Only edge padding and slider sizes are set here.
$bar-edge: 12px;
// Nerd Font glyphs draw wider than their advance width, so a label sized to
// the advance clips the ink. Every bar icon gets this much breathing room on
// both sides. It is subtracted from `gap` / `gap-tight` in eww.yuck, so the
// gaps you see stay 14px / 6px.
$icon-pad: 3px;
$slider-width: 44px;
$slider-height: 6px;
window {
font-family: "JetBrainsMono Nerd Font", monospace;
background-color: #000000;
color: #FFFFFF;
font-family: $font-family;
background-color: $bg-bar;
color: $fg;
}
/* Global normalization - no widget should add spacing */
// No widget adds its own spacing. Gaps come from box :spacing only.
eventbox, box, label, scale {
padding: 0;
margin: 0;
}
$font-family: "JetBrainsMono Nerd Font", monospace;
// ---------------------------------------------------------------------------
// Bar
// ---------------------------------------------------------------------------
// Global colors (sync with ~/.config/colors)
$bg-bar: #000000;
$track: #3a3a3a;
$accent: #E0AF68;
$urgent: #F7768E;
$fg: #ffffff;
.bar {
background-color: $bg-bar;
}
// Legacy
$background: $bg-bar;
$foreground: $fg;
// The last icon already carries $icon-pad, so subtract it to keep the visible
// edge gap equal to $bar-edge.
.system {
margin-right: $bar-edge - $icon-pad;
}
.workspaces-widget {
margin-left: $bar-edge - 6px;
}
.workspace-entry {
/* Styles for all workspace entries */
padding: 0 0.5em;
font-family: $font-family;
color : $foreground;
padding: 0 6px;
color: $fg;
}
.workspace-entry.current {
/* Styles for the current workspace */
color: $accent;
font-weight: bold;
}
.workspace-entry.urgent {
/* Styles for urgent workspaces */
color: $urgent;
font-weight: bold;
}
.time-label {
font-family: $font-family;
color : $foreground;
font-weight: bold;
margin-right: 5px;
}
.notification-eventbox {
padding: 0;
min-width: 0;
min-height: 0;
}
// ---------------------------------------------------------------------------
// Bar items
// ---------------------------------------------------------------------------
// Every bar glyph and value shares one look.
.signal-icon,
.net-icon,
.brightness-icon,
.volume-icon,
.battery-icon,
.battery-percent,
.time-label,
.notification-icon {
font-family: $font-family;
color : $foreground;
font-weight: bold;
margin-right: 5px;
}
.battery-percent {
font-family: $font-family;
color : $foreground;
font-weight: bold;
margin-right: 5px;
}
.battery-icon {
font-family: $font-family;
color : $foreground;
color: $fg;
font-weight: bold;
padding: 0 $icon-pad;
}
.bar {
background-color: $background;
}
.net-vpn-on { color: $accent; }
.net-offline { color: $urgent; }
.wifi-eventbox {
padding: 0;
.signal-eventbox,
.net-eventbox,
.notification-eventbox {
min-width: 0;
min-height: 0;
}
.wifi-icon{
color : $foreground;
background-color: $background;
font-weight: bold;
}
.brightness-icon {
color: $foreground;
font-weight: bold;
margin-right: 3px;
}
.volume-icon {
color: $foreground;
font-weight: bold;
margin-right: 3px;
}
.volume-bar {
min-width: 10px;
min-height: 6px;
padding: 0;
margin: 0;
margin-right: 10px;
border: none;
outline: none;
}
.volume-bar trough {
background-color: $track;
border-radius: 3px;
min-height: 6px;
min-width: 10px;
padding: 0;
margin: 0;
border: none;
outline: none;
}
.volume-bar highlight {
background-color: $fg;
border-radius: 3px;
padding: 0;
margin: 0;
}
.volume-bar slider {
all: unset;
padding: 0;
margin: 0;
min-width: 0;
min-height: 0;
}
// ---------------------------------------------------------------------------
// Sliders
// ---------------------------------------------------------------------------
// Sliders have no ink overflow, so they carry $icon-pad as a margin instead.
// This keeps the icon-to-slider gap equal to every other tight gap.
.volume-bar,
.brightness-bar {
min-width: 10px;
min-height: 6px;
padding: 0;
margin: 0;
margin-right: 10px;
min-width: $slider-width;
min-height: $slider-height;
margin: 0 $icon-pad;
border: none;
outline: none;
}
.volume-bar trough,
.brightness-bar trough {
background-color: $track;
border-radius: 3px;
min-height: 6px;
min-width: 10px;
padding: 0;
margin: 0;
min-width: $slider-width;
min-height: $slider-height;
border: none;
outline: none;
}
.volume-bar highlight,
.brightness-bar highlight {
background-color: $fg;
border-radius: 3px;
padding: 0;
margin: 0;
}
.volume-bar slider,
.brightness-bar slider {
all: unset;
padding: 0;
margin: 0;
min-width: 0;
min-height: 0;
}
.signal-eventbox {
padding: 0;
min-width: 0;
min-height: 0;
// ---------------------------------------------------------------------------
// Network popup
// ---------------------------------------------------------------------------
.net-popup {
background-color: $bg-popup;
border: 1px solid $border;
border-radius: 6px;
padding: 12px 14px;
}
.signal-icon {
color: $foreground;
.net-popup-header {
color: $fg-dim;
font-size: 11px;
font-weight: bold;
margin-right: 5px;
}
.net-row-icon {
color: $fg;
font-size: 18px;
}
.net-row-icon.net-vpn-off {
color: $track;
}
.net-row-title {
color: $fg;
font-weight: bold;
}
.net-row-subtitle {
color: $fg-dim;
font-size: 11px;
}
.net-separator {
background-color: $border;
min-height: 1px;
}
.net-vpn-eventbox {
min-height: 0;
}
.net-pill {
font-size: 11px;
font-weight: bold;
padding: 2px 8px;
border-radius: 10px;
}
.net-pill-on {
background-color: $accent;
color: $bg-bar;
}
.net-pill-off {
background-color: $track;
color: $fg;
}
// ---------------------------------------------------------------------------
// Tooltips
// ---------------------------------------------------------------------------
tooltip {
background-color: $bg-bar;
color: $fg;
border: none;
border-radius: 0;
font-family: "JetBrainsMono Nerd Font", monospace;
border: 1px solid $border;
border-radius: 4px;
font-family: $font-family;
}

View File

@@ -1,10 +1,31 @@
;; ---------------------------------------------------------------------------
;; Layout constants
;; ---------------------------------------------------------------------------
;; gap = space between two widget groups in the bar
;; gap-tight = space inside a group (icon + its value)
;; Keep every spacing in the bar on one of these two values.
;;
;; Each bar icon carries $icon-pad (3px per side) in eww.scss, so Nerd Font
;; glyphs are not clipped. That padding sits inside the gap, so these numbers
;; are the gap you want to see, minus 2 * $icon-pad:
;; groups: 21px visible = 15 + 3 + 3
;; tight : 10px visible = 4 + 3 + 3
(defvar gap 15)
(defvar gap-tight 4)
;; ---------------------------------------------------------------------------
;; Workspaces
;; ---------------------------------------------------------------------------
(deflisten workspaces :initial "[]" "bash ~/.config/eww/scripts/get-workspaces")
(deflisten current_workspace :initial "1" "bash ~/.config/eww/scripts/get-active-workspace")
(defwidget workspaces [monitor]
(eventbox :onscroll "bash ~/.config/eww/scripts/change-active-workspace {} ${current_workspace}" :class "workspaces-widget"
(box :spacing 10 :orientation "h" :halign "start" :space-evenly false
(eventbox :onscroll "bash ~/.config/eww/scripts/change-active-workspace {} ${current_workspace}"
:class "workspaces-widget"
(box :spacing 0 :orientation "h" :halign "start" :space-evenly false
(label :text "${workspaces}${current_workspace}" :visible false)
(for workspace in workspaces
(box
@@ -13,6 +34,9 @@
(box :class "workspace-entry ${workspace.focused ? 'current' : ''} ${workspace.urgent ? 'urgent' : ''}"
(label :text "${workspace.id}"))))))))
;; ---------------------------------------------------------------------------
;; Clock
;; ---------------------------------------------------------------------------
(defpoll time :interval "1s"
"date '+%H:%M'")
@@ -20,40 +44,107 @@
(defpoll time_tooltip :interval "1s"
"date '+%A, %B %d, %Y'")
(defwidget time-widget []
(label
:text {time}
:tooltip time_tooltip
:class "time-label"))
;; ---------------------------------------------------------------------------
;; Notifications
;; ---------------------------------------------------------------------------
(defwidget notification-widget []
(eventbox :class "notification-eventbox" :onclick "bash ~/.config/eww/scripts/notification-history-toggle"
(eventbox :class "notification-eventbox"
:onclick "bash ~/.config/eww/scripts/notification-history-toggle"
:tooltip "Toggle notification history"
(label :text "" :class "notification-icon")))
;; ---------------------------------------------------------------------------
;; Battery
;; ---------------------------------------------------------------------------
(deflisten BATPERC :initial "" "bash ~/.config/eww/scripts/battery-perc-monitor")
(deflisten BATICON :initial "" "bash ~/.config/eww/scripts/battery-icon-monitor")
(deflisten BATTIME :initial "" "bash ~/.config/eww/scripts/battery-time-monitor")
(defwidget battery-widget []
(box :orientation "horizontal" :spacing 0 :tooltip "Time remaining: ${BATTIME}"
(box :orientation "h" :space-evenly false :spacing gap-tight
:tooltip "Time remaining: ${BATTIME}"
(label :text {BATICON} :class "battery-icon")
(label :text {BATPERC} :class "battery-percent")))
(defwidget internet []
(label :text wifi-icon
:tooltip wifi-name
:class "wifi-icon"))
(deflisten wifi-icon :initial "󰪎" "bash ~/.config/eww/scripts/wifi-monitor")
(deflisten wifi-name :initial "" "bash ~/.config/eww/scripts/wifi-name-monitor")
;; ---------------------------------------------------------------------------
;; Network (wifi / wired / vpn)
;; ---------------------------------------------------------------------------
(deflisten net
:initial '{"icon":"󰪎","vpn":false,"vpnname":"asahi","vpnstate":"missing","wifi":false,"ssid":"","wifidev":"","signal":0,"wired":false,"wireddev":"","wiredconn":"","online":false,"tooltip":"No connection"}'
"bash ~/.config/eww/scripts/net-info")
;; Bar entry. Click opens the network popup for this monitor.
(defwidget internet [popup]
(eventbox :class "net-eventbox"
:onclick "eww open --toggle ${popup}"
:tooltip {net.tooltip}
(label :text {net.icon}
:class "net-icon ${net.vpn ? 'net-vpn-on' : (net.online ? 'net-online' : 'net-offline')}")))
;; One connection row inside the popup.
(defwidget net-row [icon title subtitle]
(box :orientation "h" :space-evenly false :spacing 10 :halign "start" :class "net-row"
(label :text icon :class "net-row-icon")
(box :orientation "v" :space-evenly false :halign "start"
(label :text title :class "net-row-title" :halign "start" :limit-width 24)
(label :text subtitle :class "net-row-subtitle" :halign "start" :limit-width 28))))
(defwidget net-popup-content []
(box :class "net-popup" :orientation "v" :space-evenly false :spacing 12
(label :text "Network" :class "net-popup-header" :halign "start")
;; --- active connections ---
(box :orientation "v" :space-evenly false :spacing 10
(box :visible {net.wired} :space-evenly false
(net-row :icon "󰈀"
:title {net.wiredconn}
:subtitle "Wired · ${net.wireddev}"))
(box :visible {net.wifi} :space-evenly false
(net-row :icon "󰖩"
:title {net.ssid}
:subtitle "Wi-Fi · ${net.wifidev} · ${net.signal}%"))
(box :visible {!net.online} :space-evenly false
(net-row :icon "󰪎"
:title "Not connected"
:subtitle "No wired or Wi-Fi link")))
(box :class "net-separator" :height 1)
;; --- vpn toggle ---
(eventbox :class "net-vpn-eventbox"
:cursor {net.vpnstate == "missing" ? "not-allowed" : "pointer"}
:onclick {net.vpnstate == "missing" ? "" : "bash ~/.config/eww/scripts/vpn-toggle"}
:tooltip {net.vpnstate == "missing"
? "Import it first: sudo nmcli connection import type wireguard file /etc/wireguard/${net.vpnname}.conf"
: "Click to toggle the ${net.vpnname} VPN"}
(box :orientation "h" :space-evenly false :spacing 10
(label :text "󱁍" :class "net-row-icon ${net.vpn ? 'net-vpn-on' : 'net-vpn-off'}")
(box :orientation "v" :space-evenly false :halign "start" :hexpand true
(label :text "VPN · ${net.vpnname}" :class "net-row-title" :halign "start")
(label :text {net.vpnstate} :class "net-row-subtitle" :halign "start"))
(label :text {net.vpn ? "ON" : "OFF"}
:halign "end"
:class "net-pill ${net.vpn ? 'net-pill-on' : 'net-pill-off'}")))))
;; ---------------------------------------------------------------------------
;; Brightness
;; ---------------------------------------------------------------------------
(deflisten brightness :initial "50" "bash ~/.config/eww/scripts/brightness")
(defwidget brightness-widget []
(eventbox :onscroll "[ {} = up ] && brightnessctl set 10%+ || brightnessctl set 10%-"
:tooltip "Brightness: ${brightness}%"
(box :orientation "h" :spacing 0
(box :orientation "h" :space-evenly false :spacing gap-tight
(label :text "󰌵" :class "brightness-icon")
(scale :min 0
:max 100
@@ -61,44 +152,55 @@
:class "brightness-bar"
:onchange "brightnessctl set {}%"))))
;; ---------------------------------------------------------------------------
;; Volume
;; ---------------------------------------------------------------------------
(deflisten volume :initial "50" "bash ~/.config/eww/scripts/volume")
(deflisten volume-icon :initial "" "bash ~/.config/eww/scripts/volume-icon-monitor")
(defwidget volume-widget []
(eventbox :onscroll "[ {} = up ] && pactl set-sink-volume @DEFAULT_SINK@ +10% || pactl set-sink-volume @DEFAULT_SINK@ -10%"
:tooltip "Volume: ${volume}%"
(box :orientation "h" :spacing 0
(eventbox :onscroll "[ {} = up ] && pactl set-sink-volume @DEFAULT_SINK@ +10% || pactl set-sink-volume @DEFAULT_SINK@ -10%"
:tooltip "Volume: ${volume}%"
(box :orientation "h" :space-evenly false :spacing gap-tight
(label :text volume-icon :class "volume-icon")
(scale :min 0
:max 100
:value volume
:class "volume-bar"
:onchange "pactl set-sink-volume @DEFAULT_SINK@ {}%"))))
:onchange "pactl set-sink-volume @DEFAULT_SINK@ {}%"))))
;; ---------------------------------------------------------------------------
;; Signal
;; ---------------------------------------------------------------------------
(defwidget signal-widget []
(eventbox :class "signal-eventbox" :onclick "bash ~/.config/eww/scripts/signal-toggle"
:tooltip "Signal"
(label :text "󰭹" :class "signal-icon")))
(defwidget system []
(box :orientation "h" :halign "end" :spacing 0
;; ---------------------------------------------------------------------------
;; Bar
;; ---------------------------------------------------------------------------
(defwidget system [popup]
(box :class "system" :orientation "h" :halign "end" :space-evenly false :spacing gap
(signal-widget)
(internet)
(internet :popup popup)
(brightness-widget)
(volume-widget)
(battery-widget)
(time-widget)
(notification-widget)))
(defwidget bar [monitor]
(box :orientation "h" :space-evenly false
(defwidget bar [monitor popup]
(box :class "bar" :orientation "h" :space-evenly false
(workspaces :monitor monitor)
(box :hexpand true)
(system)))
(system :popup popup)))
(defwindow bar0
:monitor 0
:monitor "HDMI-A-1"
:geometry (geometry :x "0%"
:y "0px"
:width "100%"
@@ -109,10 +211,10 @@
:reserve (struts :distance "40px" :side "top")
:windowtype "dock"
:wm-ignore false
(bar :monitor "HDMI-A-1"))
(bar :monitor "HDMI-A-1" :popup "net-popup0"))
(defwindow bar1
:monitor 1
:monitor "eDP-1"
:geometry (geometry :x "0%"
:y "0px"
:width "100%"
@@ -123,6 +225,28 @@
:reserve (struts :distance "40px" :side "top")
:windowtype "dock"
:wm-ignore false
(bar :monitor "eDP-1"))
(bar :monitor "eDP-1" :popup "net-popup1"))
;; Popups sit under the bar on the same monitor. The bar reserves 40px at the
;; top, so anchoring at "top right" already lands below it.
(defwindow net-popup0
:monitor "HDMI-A-1"
:geometry (geometry :x "10px"
:y "0px"
:width "330px"
:anchor "top right")
:stacking "overlay"
:exclusive false
:focusable false
(net-popup-content))
(defwindow net-popup1
:monitor "eDP-1"
:geometry (geometry :x "10px"
:y "0px"
:width "330px"
:anchor "top right")
:stacking "overlay"
:exclusive false
:focusable false
(net-popup-content))

View File

@@ -0,0 +1,59 @@
#!/bin/bash
# Capture the eww bar (and optionally the area under it) with grim, for visual
# debugging of spacing and icons.
#
# Usage:
# bar-shot # right end of the bar on the focused output
# bar-shot -o eDP-1 # pick the output
# bar-shot -f # full bar width
# bar-shot -p # bar + 300px below it, to see popups
# bar-shot -w 900 # width of the right-end crop (default 780)
# bar-shot -O /tmp/x.png # output path (default /tmp/bar-shot.png)
#
# Scale factor 2 is used so glyph spacing stays readable when zoomed.
set -euo pipefail
OUT=""
FULL=0
POPUP=0
WIDTH=780
FILE=/tmp/bar-shot.png
BAR_H=30
POPUP_H=320
while getopts "o:fpw:O:h" opt; do
case "$opt" in
o) OUT=$OPTARG ;;
f) FULL=1 ;;
p) POPUP=1 ;;
w) WIDTH=$OPTARG ;;
O) FILE=$OPTARG ;;
h) sed -n '2,16p' "$0"; exit 0 ;;
*) exit 2 ;;
esac
done
if [ -z "$OUT" ]; then
OUT=$(swaymsg -t get_outputs -r | jq -r '.[] | select(.focused) | .name')
[ -n "$OUT" ] || OUT=$(swaymsg -t get_outputs -r | jq -r '[.[] | select(.active)][0].name')
fi
read -r X Y W _H < <(
swaymsg -t get_outputs -r |
jq -r --arg o "$OUT" '.[] | select(.name == $o) | "\(.rect.x) \(.rect.y) \(.rect.width) \(.rect.height)"'
)
height=$BAR_H
[ "$POPUP" -eq 1 ] && height=$POPUP_H
if [ "$FULL" -eq 1 ]; then
geom="$X,$Y ${W}x${height}"
else
crop=$WIDTH
[ "$crop" -gt "$W" ] && crop=$W
geom="$((X + W - crop)),$Y ${crop}x${height}"
fi
grim -g "$geom" -s 2 "$FILE"
echo "$FILE ($OUT $geom)"

120
eww/.config/eww/scripts/net-info Executable file
View File

@@ -0,0 +1,120 @@
#!/bin/bash
# Emit the full network state as one JSON line for eww.
# Replaces wifi-monitor, wifi-name-monitor and vpn-monitor.
#
# Output shape:
# {
# "icon": "f", # bar glyph: vpn / online / offline
# "vpn": true, # vpn connection is active
# "vpnname": "asahi",
# "vpnstate": "connected", # connected | disconnected | missing
# "wifi": true,
# "ssid": "Mosenet",
# "wifidev": "wld0",
# "signal": 68,
# "wired": false,
# "wireddev": "",
# "online": true,
# "tooltip": "Wi-Fi: Mosenet"
# }
VPN_CONN="${VPN_CONN:-asahi}"
ICON_VPN="󱁍" # vpn active
ICON_ONLINE="󰖟" # connected, no vpn
ICON_OFFLINE="󰪎" # no connection
vpn_state() {
if nmcli -t -f NAME connection show --active 2>/dev/null | grep -qx "$VPN_CONN"; then
echo connected
elif nmcli -t -f NAME connection show 2>/dev/null | grep -qx "$VPN_CONN"; then
echo disconnected
else
echo missing
fi
}
# First connected device of the given nmcli type. Prints "device<TAB>connection".
connected_device() {
nmcli -t -f DEVICE,TYPE,STATE,CONNECTION device 2>/dev/null |
awk -F: -v want="$1" '$2 == want && $3 == "connected" { print $1 "\t" $4; exit }'
}
wifi_signal() {
nmcli -t -f IN-USE,SIGNAL device wifi list --rescan no 2>/dev/null |
awk -F: '/^\*/ { print $2; exit }'
}
emit_state() {
local vpnstate vpn wifi_row wired_row
local wifidev="" ssid="" signal=0 wireddev="" wiredconn=""
local wifi=false wired=false online=false icon tooltip
vpnstate=$(vpn_state)
[ "$vpnstate" = connected ] && vpn=true || vpn=false
wifi_row=$(connected_device wifi)
if [ -n "$wifi_row" ]; then
wifi=true
wifidev=${wifi_row%%$'\t'*}
ssid=${wifi_row#*$'\t'}
signal=$(wifi_signal)
[ -n "$signal" ] || signal=0
fi
wired_row=$(connected_device ethernet)
if [ -n "$wired_row" ]; then
wired=true
wireddev=${wired_row%%$'\t'*}
wiredconn=${wired_row#*$'\t'}
fi
if [ "$wifi" = true ] || [ "$wired" = true ]; then
online=true
fi
if [ "$vpn" = true ]; then
icon="$ICON_VPN"
elif [ "$online" = true ]; then
icon="$ICON_ONLINE"
else
icon="$ICON_OFFLINE"
fi
if [ "$wired" = true ]; then
tooltip="Wired: $wiredconn"
elif [ "$wifi" = true ]; then
tooltip="Wi-Fi: $ssid"
else
tooltip="No connection"
fi
[ "$vpn" = true ] && tooltip="$tooltip | VPN $VPN_CONN up"
jq -nc \
--arg icon "$icon" \
--argjson vpn "$vpn" \
--arg vpnname "$VPN_CONN" \
--arg vpnstate "$vpnstate" \
--argjson wifi "$wifi" \
--arg ssid "$ssid" \
--arg wifidev "$wifidev" \
--argjson signal "${signal:-0}" \
--argjson wired "$wired" \
--arg wireddev "$wireddev" \
--arg wiredconn "$wiredconn" \
--argjson online "$online" \
--arg tooltip "$tooltip" \
'$ARGS.named'
}
last=$(emit_state)
printf '%s\n' "$last"
# Report only real changes, so eww does not redraw on unrelated network events.
nmcli monitor | while read -r _; do
current=$(emit_state)
if [ "$current" != "$last" ]; then
printf '%s\n' "$current"
last=$current
fi
done

View File

@@ -0,0 +1,20 @@
#!/bin/bash
# Toggle the "asahi" WireGuard connection in NetworkManager.
# Usage: vpn-toggle [toggle|up|down|status]
# Requires the connection to be imported first:
# sudo nmcli connection import type wireguard file /etc/wireguard/asahi.conf
CONN="asahi"
is_up() {
nmcli -t -f NAME connection show --active 2>/dev/null | grep -qx "$CONN"
}
case "${1:-toggle}" in
up) nmcli connection up "$CONN" >/dev/null 2>&1 ;;
down) nmcli connection down "$CONN" >/dev/null 2>&1 ;;
status) is_up && echo up || echo down ;;
toggle) is_up && nmcli connection down "$CONN" >/dev/null 2>&1 \
|| nmcli connection up "$CONN" >/dev/null 2>&1 ;;
*) echo "Usage: ${0##*/} [toggle|up|down|status]" >&2; exit 2 ;;
esac

View File

@@ -1,13 +0,0 @@
#!/bin/sh
symbol() {
[ $(cat /sys/class/net/w*/operstate) = down ] && echo 󰪎 && exit
echo 󰖟
}
name() {
nmcli | grep "^wlp" | sed 's/\ connected\ to\ /Connected to /g' | cut -d ':' -f2
}
[ "$1" = "icon" ] && symbol && exit
[ "$1" = "name" ] && name && exit

View File

@@ -1,13 +0,0 @@
#!/bin/bash
get_icon() {
[ $(cat /sys/class/net/w*/operstate 2>/dev/null) = down ] && echo "󰪎" || echo "󰖟"
}
# Output initial state
get_icon
# Monitor network changes
nmcli monitor | while read -r line; do
get_icon
done

View File

@@ -1,13 +0,0 @@
#!/bin/bash
get_name() {
nmcli | grep "^wlp" | sed 's/\ connected\ to\ /Connected to /g' | cut -d ':' -f2
}
# Output initial state
get_name
# Monitor network changes
nmcli monitor | while read -r line; do
get_name
done