From 55985a8f20ce7add0f85a230904d41189bfcb03c Mon Sep 17 00:00:00 2001 From: Stacy Harper Date: Sun, 12 Sep 2021 09:34:55 +0200 Subject: [PATCH] Rework the status bar Goals of this patch : - display the signal quality I used a thermometer icon cause there is no available icon with a filleable bar o_O - display the currently used network technology (4g, 3g, etc...) I used the mapping from: https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/blob/master/include/ModemManager-enums.h#L220 Dylan also said: Anything from POTS to GPRS = 2G UMTS to EVDOB = 3G LTE = 4G 5GNR = 5G - display the modem infos when modemmonitor is disabled We want to decorelate the modem monitor from the icon. We still want to know easily if modem monitor is runing but we also want those modem infos if not. - simplify the modem state determination (no state file anymore) The statusbar probe mmcli itself. - fix the leading timer without call issue This was caused by the "pgrep -f" command that was matching itself. Using a simple "pgrep" looks good enough anyway. - fix some sxmo_statusbar update spaming issues (vol control) This one point took me a lot of time to findout a good solution. We want the USR1 kill to be spamable without causing issue to the displayed bar. We dont want mid rendered bar (half the icons). We dont want empty bars (empty stdout line). I use some variable to store pid, smart waits and a better trap function to make it to works cleanly. Now we can spam statusbarupdate. Only the last one will actually redraw the bar. Signed-off-by: Stacy Harper Signed-off-by: Maarten van Gompel --- scripts/core/sxmo_common.sh | 2 - scripts/core/sxmo_statusbar.sh | 200 +++++++++++++++-------- scripts/modem/sxmo_modemmonitor.sh | 33 +--- scripts/modem/sxmo_modemmonitortoggle.sh | 2 +- 4 files changed, 131 insertions(+), 106 deletions(-) diff --git a/scripts/core/sxmo_common.sh b/scripts/core/sxmo_common.sh index 485742f..7441231 100644 --- a/scripts/core/sxmo_common.sh +++ b/scripts/core/sxmo_common.sh @@ -32,8 +32,6 @@ export XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" # shellcheck disable=SC2034 export CONTACTFILE="$XDG_CONFIG_HOME/sxmo/contacts.tsv" # shellcheck disable=SC2034 -export MODEMSTATEFILE="$XDG_RUNTIME_DIR/sxmo.modem.state" -# shellcheck disable=SC2034 export UNSUSPENDREASONFILE="$XDG_RUNTIME_DIR/sxmo.suspend.reason" # shellcheck disable=SC2034 export LASTSTATE="$XDG_RUNTIME_DIR/sxmo.suspend.laststate" diff --git a/scripts/core/sxmo_statusbar.sh b/scripts/core/sxmo_statusbar.sh index f75a6f2..6a8aa1b 100755 --- a/scripts/core/sxmo_statusbar.sh +++ b/scripts/core/sxmo_statusbar.sh @@ -4,54 +4,92 @@ # shellcheck source=scripts/core/sxmo_common.sh . "$(dirname "$0")/sxmo_common.sh" -trap "update" USR1 +percenticon() { + if [ "$1" -lt 20 ]; then + printf "" + elif [ "$1" -lt 40 ]; then + printf "" + elif [ "$1" -lt 60 ]; then + printf "" + elif [ "$1" -lt 80 ]; then + printf "" + else + printf "" + fi +} + +bar() { + MMCLI="$(mmcli -m any -J)" -update() { # In-call.. show length of call - CALLINFO=" " - if pgrep -f sxmo_modemcall.sh; then + if pgrep sxmo_modemcall.sh > /dev/null; then NOWS="$(date +"%s")" CALLSTARTS="$(date +"%s" -d "$( grep -aE 'call_start|call_pickup' "$XDG_DATA_HOME"/sxmo/modem/modemlog.tsv | tail -n1 | cut -f1 )")" - CALLSECONDS="$(echo "$NOWS" - "$CALLSTARTS" | bc)" - CALLINFO="${CALLSECONDS}s" + CALLSECONDS="$(printf "%s - %s" "$NOWS" "$CALLSTARTS" | bc)" + printf "%ss " "$CALLSECONDS" fi - # symbol if wireguard/vpn is connected - VPN="" - VPNDEVICE="$(nmcli con show | grep vpn | awk '{ print $4 }')" - WGDEVICE="$(nmcli con show | grep wireguard | awk '{ print $4 }')" - if [ -n "$VPNDEVICE" ] && [ "$VPNDEVICE" != "--" ]; then - VPN="" - elif [ -n "$WGDEVICE" ] && [ "$WGDEVICE" != "--" ]; then - VPN="" + MODEMSTATUS="" + if [ -z "$MMCLI" ]; then + printf "" + else + MODEMSTATUS="$(printf %s "$MMCLI" | jq -r .modem.generic.state)" + case "$MODEMSTATUS" in + locked) + printf "" + ;; + registered|connected) + MODEMSIGNAL="$(printf %s "$MMCLI" | jq -r '.modem.generic."signal-quality".value')" + percenticon "$MODEMSIGNAL" + ;; + disconnected) + printf "ﲁ" + ;; + esac + fi + + if [ "$MODEMSTATUS" = "connected" ]; then + printf " " + USEDTECHS="$(printf %s "$MMCLI" | jq -r '.modem.generic."access-technologies"[]')" + case "$USEDTECHS" in + *5gnr*) + printf 5g # no icon yet + ;; + *lte*) + printf ﰒ + ;; + *umts*|*hsdpa*|*hsupa*|*hspa*|*1xrtt*|*evdo0*|*evdoa*|*evdob*) + printf ﰑ + ;; + *edge*) + printf E + ;; + *pots*|*gsm*|*gprs*) + printf ﰐ + ;; + esac + fi + + if pgrep -f sxmo_modemmonitor.sh > /dev/null; then + printf " " fi - # W symbol if wireless is connect - WIRELESS="" WLANSTATE="$(tr -d "\n" < /sys/class/net/wlan0/operstate)" if [ "$WLANSTATE" = "up" ]; then - WIRELESS="" + printf " " fi - # M symbol if modem monitoring is on & modem present - MODEMMON="" - if [ -f "$MODEMSTATEFILE" ]; then - MODEMSTATE="$(cat "$MODEMSTATEFILE")" - if [ locked = "$MODEMSTATE" ]; then - MODEMMON="" - elif [ registered = "$MODEMSTATE" ]; then - MODEMMON="" - elif [ connected = "$MODEMSTATE" ]; then - MODEMMON="" - elif [ failed = "$MODEMSTATE" ] || [ disconnected = "$MODEMSTATE" ]; then - MODEMMON="" - else - MODEMMON="" - fi + # symbol if wireguard/vpn is connected + VPNDEVICE="$(nmcli con show | grep vpn | awk '{ print $4 }')" + WGDEVICE="$(nmcli con show | grep wireguard | awk '{ print $4 }')" + if [ -n "$VPNDEVICE" ] && [ "$VPNDEVICE" != "--" ]; then + printf " " + elif [ -n "$WGDEVICE" ] && [ "$WGDEVICE" != "--" ]; then + printf " " fi # Find battery and get percentage + status @@ -62,55 +100,60 @@ update() { fi done + printf " " if [ "$BATSTATUS" = "C" ]; then if [ "$PCT" -lt 20 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 30 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 40 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 60 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 80 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 90 ]; then - BATSTATUS="$PCT% " + printf "" else - BATSTATUS="$PCT% " + printf "" fi else if [ "$PCT" -lt 10 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 20 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 30 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 40 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 50 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 60 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 70 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 80 ]; then - BATSTATUS="$PCT% " + printf "" elif [ "$PCT" -lt 90 ]; then - BATSTATUS="$PCT% " + printf "" else - BATSTATUS="$PCT% " + printf "" fi fi + [ -z "$SXMO_BAR_HIDE_BAT_PER" ] && printf " %s%%" "$PCT" + + printf " " + # Volume AUDIODEV="$(sxmo_audiocurrentdevice.sh)" - AUDIOSYMBOL=$(echo "$AUDIODEV" | cut -c1) + AUDIOSYMBOL="$(printf %s "$AUDIODEV" | cut -c1)" if [ "$AUDIOSYMBOL" = "L" ] || [ "$AUDIOSYMBOL" = "N" ]; then - AUDIOSYMBOL="" #speakers or none, use no special symbol + printf "" #speakers or none, use no special symbol elif [ "$AUDIOSYMBOL" = "H" ]; then - AUDIOSYMBOL=" " + printf " " elif [ "$AUDIOSYMBOL" = "E" ]; then - AUDIOSYMBOL=" " #earpiece + printf " " #earpiece fi VOL=0 [ "$AUDIODEV" = "None" ] || VOL="$( @@ -121,32 +164,45 @@ update() { xargs printf %.0f )" if [ "$AUDIODEV" != "None" ]; then - if [ "$VOL" -eq 0 ]; then - VOLUMESYMBOL="ﱝ" - elif [ "$VOL" -lt 25 ]; then - VOLUMESYMBOL="奄" - elif [ "$VOL" -gt 75 ]; then - VOLUMESYMBOL="墳" - else - VOLUMESYMBOL="奔" + if [ "$VOL" -gt 66 ]; then + printf "" + elif [ "$VOL" -gt 33 ]; then + printf "" + elif [ "$VOL" -gt 0 ]; then + printf "" + elif [ "$VOL" -eq 0 ]; then + printf "ﱝ" fi fi - # Time - TIME="$(date +%R)" - BAR="$(echo "${CALLINFO} ${MODEMMON} ${WIRELESS} ${VPN} ${AUDIOSYMBOL}${VOLUMESYMBOL} ${BATSTATUS} ${TIME}" | sed 's| \+| |g')" + printf " %s\0" "$(date +%R)" +} - case "$(sxmo_wm.sh)" in - sway) printf "%s\n" "$BAR";; - dwm) xsetroot -name "$BAR";; - esac +WM="$(sxmo_wm.sh)" + +forceupdate() { + kill "$SLEEPID" } +trap "forceupdate" USR1 -# E.g. on first boot justs to make sure the bar comes in quickly -update +update() { + BAR="$(bar)" + [ -z "$SLEEPID" ] && return # to prevent mid rendering interuption + printf %s "$BAR" | case "$WM" in + sway|ssh) xargs -0 printf "%s\n";; + dwm) xargs -0 xsetroot -name;; + esac +} while : do - sleep 30 & wait - update + sleep 10 & + SLEEPID=$! + + update & + UPDATEID=$! + + wait "$SLEEPID" + unset SLEEPID + wait "$UPDATEID" done diff --git a/scripts/modem/sxmo_modemmonitor.sh b/scripts/modem/sxmo_modemmonitor.sh index 055a4d8..1446236 100755 --- a/scripts/modem/sxmo_modemmonitor.sh +++ b/scripts/modem/sxmo_modemmonitor.sh @@ -12,8 +12,6 @@ err() { } gracefulexit() { - rm "$MODEMSTATEFILE" - sxmo_statusbarupdate.sh sleep 1 echo "sxmo_modemmonitor: gracefully exiting (on signal or after error)">&2 kill -9 0 @@ -223,17 +221,9 @@ checkfornewtexts() { } initialmodemstatus() { - touch "$MODEMSTATEFILE" state=$(mmcli -m "$(modem_n)") - if echo "$state" | grep -q -E "^.*state:.*connected.*$"; then - echo connected > "$MODEMSTATEFILE" - elif echo "$state" | grep -q -E "^.*state:.*registered.*$"; then - echo registered > "$MODEMSTATEFILE" - elif echo "$state" | grep -q -E "^.*state:.*locked.*$"; then - echo locked > "$MODEMSTATEFILE" + if echo "$state" | grep -q -E "^.*state:.*locked.*$"; then pidof unlocksim || sxmo_hooks.sh unlocksim & - else - echo unknown > "$MODEMSTATEFILE" fi } @@ -243,6 +233,7 @@ mainloop() { checkforincomingcalls checkfornewtexts + initialmodemstatus # Monitor for incoming calls dbus-monitor --system "interface='org.freedesktop.ModemManager1.Modem.Voice',type='signal',member='CallAdded'" | \ @@ -262,11 +253,6 @@ mainloop() { echo "$line" | grep -E "^signal" && checkforfinishedcalls done & - #Monitor for modem state changes - # arg1 holds the new state: MM_MODEM_STATE_FAILED = -1, MM_MODEM_STATE_UNKNOWN = 0, ... MM_MODEM_STATE_REGISTERED=8, MM_MODEM_STATE_CONNECTED = 11 - initialmodemstatus - sxmo_statusbarupdate.sh - dbus-monitor --system "interface='org.freedesktop.ModemManager1.Modem',type='signal',member='StateChanged'" | \ while read -r line; do if echo "$line" | grep -E "^signal.*StateChanged"; then @@ -274,25 +260,14 @@ mainloop() { read -r oldstate #unused but we need to read past it read -r newstate if echo "$newstate" | grep "int32 2"; then - echo locked > "$MODEMSTATEFILE" pidof unlocksim || sxmo_hooks.sh unlocksim & elif echo "$newstate" | grep "int32 8"; then - echo registered > "$MODEMSTATEFILE" #if there is a PIN entry menu open, kill it: # shellcheck disable=SC2009 ps aux | grep dmenu | grep PIN | gawk '{ print $1 }' | xargs kill checkforfinishedcalls checkforincomingcalls checkfornewtexts - elif echo "$newstate" | grep "int32 11"; then - echo connected > "$MODEMSTATEFILE" - #3G/2G/4G available - elif echo "$newstate" | grep "int32 -1"; then - echo failed > "$MODEMSTATEFILE" - elif echo "$newstate" | grep "int32 3"; then - echo disabled > "$MODEMSTATEFILE" - else - echo unknown > "$MODEMSTATEFILE" fi sxmo_statusbarupdate.sh fi @@ -316,7 +291,6 @@ mainloop() { echo "sxmo_modemmonitor: modem not found, waiting for modem... (try #$TRIES)">&2 sleep 3 if [ "$TRIES" -eq 10 ]; then - echo failed > "$MODEMSTATEFILE" echo "sxmo_modemmonitor: forcing modem restart">&2 sxmo_modemmonitortoggle.sh restart #will kill the modemmonitor too break @@ -331,9 +305,6 @@ mainloop() { wait wait wait - - rm "$MODEMSTATEFILE" 2>/dev/null - sxmo_statusbarupdate.sh } diff --git a/scripts/modem/sxmo_modemmonitortoggle.sh b/scripts/modem/sxmo_modemmonitortoggle.sh index f37aa35..76b0b6e 100755 --- a/scripts/modem/sxmo_modemmonitortoggle.sh +++ b/scripts/modem/sxmo_modemmonitortoggle.sh @@ -99,7 +99,6 @@ on() { while ! printf %s "$(mmcli -L)" 2> /dev/null | grep -qoE 'Modem\/([0-9]+)'; do TRIES=$((TRIES+1)) if [ "$TRIES" -eq 10 ]; then - printf "failed\n" > "$MODEMSTATEFILE" notify-send --urgency=critical "We failed to start the modem monitor. We may need hard reboot." fi sleep 5 @@ -128,4 +127,5 @@ case "$1" in off) off;; esac +sleep 1 sxmo_statusbarupdate.sh