Fix SIM2 QMI UIM provisioning, auto-enable ModemManager, PIN auto-prompt, call audio, and Dunst clearing

This commit is contained in:
Luxferre
2026-10-25 11:31:41 +02:00
parent 9b712dcbca
commit b56f310f21
41 changed files with 1193 additions and 352 deletions
+26 -45
View File
@@ -3,61 +3,42 @@
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
ca_dbus_get_prop() {
dbus-send --session --print-reply --dest=org.mobian_project.CallAudio \
--reply-timeout=2500 /org/mobian_project/CallAudio org.freedesktop.DBus.Properties.Get \
string:org.mobian_project.CallAudio string:"$1"
}
ca_dbus_set_prop() {
dbus-send --session --print-reply --type=method_call \
--reply-timeout=2500 --dest=org.mobian_project.CallAudio \
/org/mobian_project/CallAudio org.mobian_project.CallAudio."$1" "$2" |\
grep -q "boolean true" && return 0 || return 1
}
enable_call_audio_mode() {
if pactl -f json info 2>/dev/null | jq -r .server_name | grep -q PipeWire; then
sxmo_audio.sh device set Earpiece
sxmo_log "Successfully enabled call audio mode (Earpiece)."
sxmo_hook_statusbar.sh volume
return 0
fi
if ca_dbus_set_prop SelectMode uint32:1; then
sxmo_log "Successfully enabled call audio mode."
sxmo_hook_statusbar.sh volume
else
sxmo_notify_user.sh "Failed to enable call audio mode."
return 1
fi
if command -v amixer >/dev/null 2>&1; then
amixer -c 0 sset 'PRI_MI2S_RX Voice Mixer VoiceMMode1' on >/dev/null 2>&1 || true
amixer -c 0 sset 'VoiceMMode1 Capture Mixer TERT_MI2S_TX' on >/dev/null 2>&1 || true
amixer -c 0 sset 'RX1 MIX1 INP1' 'RX1' >/dev/null 2>&1 || true
amixer -c 0 sset 'RDAC2 MUX' 'RX1' >/dev/null 2>&1 || true
amixer -c 0 sset 'EAR_S' 'Switch' >/dev/null 2>&1 || true
amixer -c 0 sset 'DEC1 MUX' 'ADC1' >/dev/null 2>&1 || true
amixer -c 0 sset 'ADC1 Volume' 100% >/dev/null 2>&1 || true
amixer -c 0 sset 'RX1 Digital Volume' 84 >/dev/null 2>&1 || true
fi
sxmo_audio.sh device set Earpiece >/dev/null 2>&1 || true
sxmo_log "Enabled ALSA voice call audio mode (Earpiece)."
sxmo_hook_statusbar.sh volume >/dev/null 2>&1 || true
return 0
}
disable_call_audio_mode() {
if pactl -f json info 2>/dev/null | jq -r .server_name | grep -q PipeWire; then
sxmo_audio.sh device set Speaker
sxmo_log "Successfully disabled call audio mode (Speaker)."
sxmo_hook_statusbar.sh volume
return 0
fi
if ca_dbus_set_prop SelectMode uint32:0; then
sxmo_log "Successfully disabled call audio mode."
sxmo_hook_statusbar.sh volume
else
sxmo_notify_user.sh "Failed to disable call audio mode."
return 1
fi
if command -v amixer >/dev/null 2>&1; then
amixer -c 0 sset 'PRI_MI2S_RX Voice Mixer VoiceMMode1' off >/dev/null 2>&1 || true
amixer -c 0 sset 'VoiceMMode1 Capture Mixer TERT_MI2S_TX' off >/dev/null 2>&1 || true
fi
sxmo_audio.sh device set Speaker >/dev/null 2>&1 || true
sxmo_log "Disabled ALSA voice call audio mode (Speaker)."
sxmo_hook_statusbar.sh volume >/dev/null 2>&1 || true
return 0
}
setup_audio() {
if ! enable_call_audio_mode; then
return 1
fi
enable_call_audio_mode
return 0
}
reset_audio() {
if ! disable_call_audio_mode; then
return 1
fi
disable_call_audio_mode
return 0
}
"$@"
+5 -3
View File
@@ -36,7 +36,7 @@ pickup() {
NUM="$(vid_to_number "$CALLID" 2>/dev/null || true)"
DIRECTION="$(
mmcli --voice-status -o "$CALLID" -K |
(mmcli -m any -o "$CALLID" -K 2>/dev/null || mmcli -o "$CALLID" -K 2>/dev/null || mmcli --voice-status -o "$CALLID" -K 2>/dev/null) |
grep call.properties.direction |
cut -d: -f2 |
tr -d " "
@@ -53,11 +53,12 @@ pickup() {
return 1
fi
sxmo_notify_user.sh "Started call"
touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.initiatedcall"
log_event "call_start" "$CALLID"
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen outgoing "$CALLID" "$NUM" >/dev/null 2>&1 || true
else
sxmo_notify_user.sh "Started call"
fi
;;
incoming)
@@ -74,11 +75,12 @@ pickup() {
return 1
fi
sxmo_notify_user.sh "Picked up call"
touch "$XDG_RUNTIME_DIR/sxmo_calls/${CALLID}.pickedupcall"
log_event "call_pickup" "$CALLID"
if command -v xcallscreen >/dev/null 2>&1; then
xcallscreen active "$CALLID" "$NUM" >/dev/null 2>&1 || true
else
sxmo_notify_user.sh "Picked up call"
fi
;;
*)
+24 -17
View File
@@ -16,15 +16,16 @@ dial_number() {
return 0
fi
NUMBER="$1"
NUMBER="$(printf "%s" "$1" | tr -cd '+0-9*#')"
if [ -z "$NUMBER" ]; then
return 1
fi
CLEANEDNUMBER="$(pnc find ${DEFAULT_COUNTRY:+-c "$DEFAULT_COUNTRY"} "$1" 2>/dev/null || true)"
if [ -n "$CLEANEDNUMBER" ] && [ "$NUMBER" != "$CLEANEDNUMBER" ]; then
NUMBER="$(cat <<EOF | sxmo_dmenu.sh -p "Rewrite ?"
$NUMBER
$CLEANEDNUMBER
EOF
)"
mm_state="$(mmcli -m any -K 2>/dev/null | awk -F': ' '$1 == "modem.generic.state" {print $2; exit}')"
if [ "$mm_state" = "disabled" ] || [ -z "$mm_state" ]; then
mmcli -m any -e >/dev/null 2>&1 || true
mmcli -m any --3gpp-register-home >/dev/null 2>&1 || true
sleep 1
fi
sxmo_log "Attempting to dial: $NUMBER"
@@ -33,7 +34,7 @@ EOF
fi
if ! CALLID="$(
mmcli -m any --voice-create-call "number=$NUMBER" |
mmcli -m any --voice-create-call="number=$NUMBER" 2>/dev/null |
grep -Eo "Call/[0-9]+" |
grep -oE "[0-9]+"
)"; then
@@ -79,16 +80,22 @@ EOF
}
dial_ussd() {
USSD="$1"
DBUS_MODEM=$(mmcli -J -L | jq -r '."modem-list"[]')
MM_BUS="org.freedesktop.ModemManager1"
USSD_IFACE="org.freedesktop.ModemManager1.Modem.Modem3gpp.Ussd"
sxmo_log "Dialling USSD: $USSD"
OUTPUT=$(busctl --json=short call "$MM_BUS" "$DBUS_MODEM" "$USSD_IFACE" Initiate "s" "$USSD" | jq -r '.data[]')
sxmo_terminal.sh sxmo_ussd.sh "$DBUS_MODEM" "Unknown" "$OUTPUT" &
OUTPUT="$(doas -n /usr/libexec/msm-modem-uim-selection ussd initiate "$USSD" 2>/dev/null || /usr/libexec/msm-modem-uim-selection ussd initiate "$USSD" 2>/dev/null || true)"
if [ -z "$OUTPUT" ]; then
DBUS_MODEM="$(mmcli -J -L 2>/dev/null | jq -r '."modem-list"[]' 2>/dev/null | head -n1)"
MM_BUS="org.freedesktop.ModemManager1"
USSD_IFACE="org.freedesktop.ModemManager1.Modem.Modem3gpp.Ussd"
if [ -n "$DBUS_MODEM" ]; then
OUTPUT="$(busctl --json=short call "$MM_BUS" "$DBUS_MODEM" "$USSD_IFACE" Initiate "s" "$USSD" 2>/dev/null | jq -r '.data[]' 2>/dev/null || true)"
fi
fi
if [ -n "$OUTPUT" ]; then
sxmo_notify_user.sh "USSD ($USSD): $OUTPUT"
else
sxmo_notify_user.sh --urgency=critical "USSD request failed ($USSD)"
fi
}
dial_menu() {
+174
View File
@@ -0,0 +1,174 @@
#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# include common definitions
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
# see networkmanager documentation for these state names
statenumtoname() {
case "$1" in
"int32 -1") printf "failed" ;;
"int32 0") printf "unknown" ;;
"int32 1") printf "initializing" ;;
"int32 2") printf "locked" ;;
"int32 3") printf "disabled" ;;
"int32 4") printf "disabling" ;;
"int32 5") printf "enabling" ;;
"int32 6") printf "enabled" ;;
"int32 7") printf "searching" ;;
"int32 8") printf "registered" ;;
"int32 9") printf "disconnecting" ;;
"int32 10") printf "connecting" ;;
"int32 11") printf "connected" ;;
*) printf "ERROR" ;;
esac
}
mainloop() {
# get initial modem state and handle SIM2/QMI PIN lock or unprovisioned slot
(
tries=0
newstate=""
while [ "$tries" -lt 15 ]; do
newstate="$(mmcli -m any -K 2>/dev/null | grep "^modem.generic.state " | cut -d':' -f2 | sed 's/^ //')"
if [ -n "$newstate" ]; then
break
fi
sleep 2
tries=$((tries + 1))
done
uim_st="$(doas -n /usr/libexec/msm-modem-uim-selection status 2>/dev/null || /usr/libexec/msm-modem-uim-selection status 2>/dev/null || true)"
if printf "%s\n" "$uim_st" | grep -qE "SLOT[12]_PIN1_STATE=(enabled-not-verified|blocked)|SLOT[12]_APP_STATE=(pin1|puk1)"; then
newstate="locked"
elif printf "%s\n" "$uim_st" | grep -qE "SLOT[12]_STATE=present" && printf "%s\n" "$uim_st" | grep -q "^PRIMARY_GW_SLOT=0$"; then
doas -n /usr/libexec/msm-modem-uim-selection boot >/dev/null 2>&1 || true
newstate="$(mmcli -m any -K 2>/dev/null | grep "^modem.generic.state " | cut -d':' -f2 | sed 's/^ //')"
fi
if [ -n "$newstate" ]; then
# fake oldstate (boot) and reason (0)
sxmo_hook_modem.sh "boot" "$newstate" "0"
sxmo_hook_statusbar.sh modem
fi
) &
# Monitor for incoming calls
dbus-monitor --system "interface='org.freedesktop.ModemManager1.Modem.Voice',type='signal',member='CallAdded'" |
while read -r line; do
echo "$line" | grep -qE "^signal" && sxmo_modem.sh checkforincomingcalls
done &
# Monitor for incoming texts
dbus-monitor --system "interface='org.freedesktop.ModemManager1.Modem.Messaging',type='signal',member='Added'" |
while read -r line; do
echo "$line" | grep -qE "^signal" && sxmo_modem.sh checkfornewtexts
done &
# Check for new texts periodically
sxmo_run_aligned.sh 300 sxmo_modem.sh checkfornewtexts &
# Monitor for finished calls
dbus-monitor --system "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.freedesktop.ModemManager1.Call'" |
while read -r line; do
echo "$line" | grep -qE "^signal" && sxmo_modem.sh checkforfinishedcalls
done &
# Periodically remove finished calls
sxmo_run_aligned.sh 300 sxmo_modem.sh checkforfinishedcalls &
# Monitor for modem state change
dbus-monitor --system "interface='org.freedesktop.ModemManager1.Modem',type='signal',member='StateChanged'" |
while read -r line; do
if echo "$line" | grep -qE "^signal.*StateChanged"; then
read -r oldstate
read -r newstate
read -r reason
sxmo_hook_modem.sh "$(statenumtoname "$oldstate")" \
"$(statenumtoname "$newstate")" \
"$(echo "$reason" | sed 's/uint32 //')"
sxmo_hook_statusbar.sh modem
fi
done &
# Monitor for 3GPP USSD
dbus-monitor --system "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.freedesktop.ModemManager1.Modem.Modem3gpp.Ussd'" |
while read -r line; do
case "$line" in
*"/org/freedesktop/ModemManager1/Modem"*)
MODEM=$(echo "$line" | awk -F'[;=]' '{print $6}')
CHANGED=0
;;
*"string \"NetworkNotification"*)
TYPE="NetworkNotification"
CHANGED=1
;;
*"string \"NetworkRequest"*)
TYPE="NetworkRequest"
CHANGED=1
;;
*)
CHANGED=0
;;
esac
if [ "$CHANGED" = "1" ]; then
# Fetch message (third argument) in sxmo_ussd.sh to save time in this loop
sxmo_terminal.sh sxmo_ussd.sh "$MODEM" "$TYPE" "" &
fi
done &
if [ -f "${SXMO_MMS_BASE_DIR:-"$HOME"/.mms/modemmanager}/mms" ]; then
# monitor for received mms
dbus-monitor "interface='org.ofono.mms.Service',type='signal',member='MessageAdded'" |
while read -r line; do
if echo "$line" | grep -q '^object path'; then
MESSAGE_PATH="$(echo "$line" | cut -d\" -f2)"
fi
if echo "$line" | grep -q 'string "received"'; then
sxmo_mms.sh processmms "$MESSAGE_PATH"
fi
done &
fi
if [ -f "${SXMO_VVM_BASE_DIR:-"$HOME"/.vvm/modemmanager}/vvm" ]; then
# monitor for vvm (Visual Voice Mail)
VVM_START=0
dbus-monitor "interface='org.kop316.vvm.Service',type='signal',member='MessageAdded'" |
while read -r line; do
if echo "$line" | grep -q '^object path'; then
VVM_ID="$(echo "$line" | cut -d\" -f2 | rev | cut -d'/' -f1 | rev)"
VVM_START=1
fi
if echo "$line" | grep -q '^]'; then
VVM_START=0
sxmo_vvm.sh processvvm "$VVM_DATE" "$VVM_SENDER" "$VVM_ID" "$VVM_ATTACHMENT"
fi
if [ "$VVM_START" -eq 1 ]; then
if echo "$line" | grep -q '^string "Date"'; then
read -r line
VVM_DATE="$(echo "$line" | cut -d\" -f2)"
elif echo "$line" | grep -q '^string "Sender"'; then
read -r line
VVM_SENDER="$(echo "$line" | cut -d\" -f2)"
elif echo "$line" | grep -q '^string "Attachments"'; then
read -r line
VVM_ATTACHMENT="$(echo "$line" | cut -d\" -f2)"
fi
fi
done &
fi
wait
}
# new session, clean up all phone related files
rm "$XDG_RUNTIME_DIR/sxmo_calls/"* 2>/dev/null || true
rm -f "$XDG_RUNTIME_DIR"/sxmo.ring.pid 2>/dev/null
rm -f "$SXMO_NOTIFDIR"/incomingcall* 2>/dev/null
mainloop
+155 -135
View File
@@ -12,189 +12,209 @@ SXMO_NOTIFDIR="${SXMO_NOTIFDIR:-${XDG_DATA_HOME:-$HOME/.local/share}/sxmo/notifi
[ -z "$SXMO_NOTIFDIR" ] || [ "$SXMO_NOTIFDIR" = "/" ] && SXMO_NOTIFDIR="$HOME/.local/share/sxmo/notifications"
_clear_notif_group() {
find "$SXMO_NOTIFDIR" -type f | while read -r file; do
if awk NR==1 "$file" | grep -lxq "$1"; then
rm "$file"
fi
done
find "$SXMO_NOTIFDIR" -type f 2>/dev/null | while read -r file; do
if [ -f "$file" ] && awk NR==1 "$file" 2>/dev/null | grep -lxq "$1"; then
rm -f "$file"
fi
done
}
_handle_new_notif_file(){
file="$1"
clear_all() {
rm -f "$SXMO_NOTIFDIR"/* 2>/dev/null || true
dunstctl close-all >/dev/null 2>&1 || true
dunstctl history-clear >/dev/null 2>&1 || true
pkill -x dunstify >/dev/null 2>&1 || true
sxmo_hook_statusbar.sh notifications >/dev/null 2>&1 || true
}
if [ "$(wc -l "$file" | cut -d' ' -f1)" -lt 3 ]; then
sxmo_log "Invalid notification file $file found, deleting!"
rm -f "$file"
return
fi
_handle_new_notif_file() {
file="$1"
[ -f "$file" ] || return 0
sxmo_hook_notification.sh "$file" &
if [ "$(wc -l < "$file" 2>/dev/null || echo 0)" -lt 3 ]; then
sxmo_log "Invalid notification file $file found, deleting!"
rm -f "$file"
return 0
fi
group="$(awk NR==1 "$file")"
action="$(awk NR==2 "$file")"
msg="$(tail -n+3 "$file" | cut -c1-70)"
sxmo_hook_notification.sh "$file" &
case "$(dunstify --action="default,Open" "$msg")" in
"2")
#
# _clear_notif_group "$group"
#
;;
"default")
_clear_notif_group "$group"
setsid -f sh -c "$action" > /dev/null 2>&1
;;
esac
group="$(awk NR==1 "$file" 2>/dev/null)"
action="$(awk NR==2 "$file" 2>/dev/null)"
msg="$(tail -n+3 "$file" 2>/dev/null | cut -c1-70)"
(
case "$(dunstify --action="default,Open" "$msg" 2>/dev/null)" in
"2")
;;
"default")
_clear_notif_group "$group"
sxmo_hook_statusbar.sh notifications >/dev/null 2>&1 || true
if [ -n "$action" ] && [ "$action" != "none" ]; then
setsid -f sh -c "$action" > /dev/null 2>&1
fi
;;
esac
) &
}
_notifications_hook() {
_cnt=0
for _nf in "$SXMO_NOTIFDIR"/*; do
[ -f "$_nf" ] && _cnt=$((_cnt + 1))
done
sxmo_hook_notifications.sh "$_cnt"
_cnt=0
for _nf in "$SXMO_NOTIFDIR"/*; do
[ -f "$_nf" ] && _cnt=$((_cnt + 1))
done
sxmo_hook_notifications.sh "$_cnt"
}
monitor() {
mkdir -p "$SXMO_NOTIFDIR"
mkdir -p "$SXMO_NOTIFDIR"
find "$SXMO_NOTIFDIR" -type f | while read -r file; do
_handle_new_notif_file "$file"
done
find "$SXMO_NOTIFDIR" -type f 2>/dev/null | while read -r file; do
_handle_new_notif_file "$file"
done
_notifications_hook
_notifications_hook
fifo="$(mktemp -u)"
mkfifo "$fifo"
inotifywait -mq -e attrib,move,delete "$SXMO_NOTIFDIR" >> "$fifo" &
inotif_pid=$!
fifo="$(mktemp -u)"
mkfifo "$fifo"
inotifywait -mq -e close_write,moved_to,delete "$SXMO_NOTIFDIR" >> "$fifo" &
inotif_pid=$!
finish() {
kill "$inotif_pid"
rm "$fifo"
exit
}
trap 'finish' TERM INT EXIT
finish() {
kill "$inotif_pid" 2>/dev/null || true
rm -f "$fifo"
exit
}
trap 'finish' TERM INT EXIT
while read -r notif_folder notif_type notif_file; do
if echo "$notif_type" | grep -qE "CREATE|MOVED_TO|ATTRIB"; then
_handle_new_notif_file "$notif_folder$notif_file"
fi
_notifications_hook
done < "$fifo"
while read -r notif_folder notif_type notif_file; do
if echo "$notif_type" | grep -qE "CLOSE_WRITE|MOVED_TO"; then
_handle_new_notif_file "$notif_folder$notif_file"
fi
_notifications_hook
done < "$fifo"
wait "$inotif_pid"
wait "$inotif_pid"
}
_menu_lines() {
find "$SXMO_NOTIFDIR" -type f | while read -r file; do
msg="$(tail -n+3 "$file" | tr "\n^" " ")"
hrandmin="$(stat --printf %y "$file" | grep -oE '[0-9]{2}:[0-9]{2}')"
cat <<EOF
find "$SXMO_NOTIFDIR" -type f 2>/dev/null | while read -r file; do
[ -f "$file" ] || continue
msg="$(tail -n+3 "$file" 2>/dev/null | tr "\n^" " ")"
hrandmin="$(stat -c %y "$file" 2>/dev/null | grep -oE '[0-9]{2}:[0-9]{2}' | head -n1)"
cat <<EOF
$hrandmin $msg^$file
EOF
done
done
}
menu() {
choices="$(cat <<EOF
$icon_cls Close Menu
choices="$(cat <<EOF
$icon_del Clear Notifications
$(_menu_lines)
$icon_cls Close Menu
EOF
)"
)"
picked="$(
printf "%b" "$choices" |
cut -d^ -f1 |
sxmo_dmenu.sh -i -p "Notifs"
)"
picked="$(
printf "%b" "$choices" |
cut -d^ -f1 |
sxmo_dmenu.sh -i -p "Notifs"
)"
case "$picked" in
"$icon_cls Close Menu"|"")
exit
;;
"$icon_del Clear Notifications")
rm "$SXMO_NOTIFDIR"/*
# we must update statusbar here because this function depends
# on number of files in $SXMO_NOTIFDIR
sxmo_hook_statusbar.sh notifications
exit
;;
*)
file="$(
printf "%b" "$choices" |
grep -F "$picked" |
cut -d^ -f2
)"
group="$(awk NR==1 "$file")"
action="$(awk NR==2 "$file")"
_clear_notif_group "$group"
setsid -f sh -c "$action" > /dev/null 2>&1
;;
esac
case "$picked" in
"$icon_cls Close Menu"|"")
exit
;;
"$icon_del Clear Notifications")
clear_all
exit
;;
*)
file="$(
printf "%b" "$choices" |
grep -F "$picked" |
cut -d^ -f2 |
head -n1
)"
if [ -n "$file" ] && [ -f "$file" ]; then
group="$(awk NR==1 "$file" 2>/dev/null)"
action="$(awk NR==2 "$file" 2>/dev/null)"
_clear_notif_group "$group"
rm -f "$file" 2>/dev/null || true
dunstctl close-all >/dev/null 2>&1 || true
sxmo_hook_statusbar.sh notifications >/dev/null 2>&1 || true
if [ -n "$action" ] && [ "$action" != "none" ]; then
setsid -f sh -c "$action" > /dev/null 2>&1
fi
fi
;;
esac
}
new() {
while : ; do
case "$1" in
-i)
id="$2"
shift 2
;;
-g)
group="$2"
shift 2
;;
*)
break
;;
esac
done
while : ; do
case "$1" in
-i)
id="$2"
shift 2
;;
-g)
group="$2"
shift 2
;;
*)
break
;;
esac
done
if [ "$#" -lt 2 ]; then
usage
exit 1
fi
if [ "$#" -lt 2 ]; then
usage
exit 1
fi
if [ -z "$id" ]; then
id="$(tr -dc 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c 10)"
fi
if [ -z "$group" ]; then
group="$(tr -dc 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c 10)"
fi
if [ -z "$id" ]; then
id="$(tr -dc 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c 10)"
fi
if [ -z "$group" ]; then
group="$(tr -dc 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c 10)"
fi
action="$1"
msg="$2"
action="$1"
msg="$2"
touch "$SXMO_NOTIFDIR/$id"
printf "%s\n%s\n%b\n" "$group" "$action" "$msg" > "$SXMO_NOTIFDIR/$id"
mkdir -p "$SXMO_NOTIFDIR"
printf "%s\n%s\n%b\n" "$group" "$action" "$msg" > "$SXMO_NOTIFDIR/$id"
sxmo_hook_statusbar.sh notifications
sxmo_hook_statusbar.sh notifications
}
usage() {
cat <<EOF
cat <<EOF
$(basename "$0"): manage sxmo notifications
Subcommands:
monitor
Watch for new notification, dispatch libnotify events, handle actions
menu
Open a menu to dismiss notifications
new [-i id] [-g group] <action> <message...>
Register a new notification
monitor
Watch for new notification, dispatch libnotify events, handle actions
menu
Open a menu to dismiss notifications
clear
Clear all notifications and close active Dunst popups
new [-i id] [-g group] <action> <message...>
Register a new notification
EOF
}
cmd="$1"
shift
shift 2>/dev/null || true
case "$cmd" in
monitor) monitor "$@";;
menu) menu "$@";;
new) new "$@";;
*)
usage
exit 1
;;
monitor) monitor "$@" ;;
menu) menu "$@" ;;
clear) clear_all ;;
new) new "$@" ;;
*)
usage
exit 1
;;
esac