Files
bananarchy/overlay/rootfs/usr/bin/sxmo_appmenu.sh
T

323 lines
7.8 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: AGPL-3.0-only
# Copyright 2022 Sxmo Contributors
# include common definitions
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
. sxmo_hook_icons.sh
# shellcheck source=scripts/core/sxmo_common.sh
. sxmo_common.sh
unalias dmenu 2>/dev/null || true
unalias bemenu 2>/dev/null || true
confirm() {
PICKED="$(printf "Yes\nNo\n" | run_dmenu -p "Confirm $1")"
if [ "$PICKED" = "Yes" ]; then
return 0
else
return 1
fi
}
run_dmenu() {
if [ "${SXMO_WM:-dwm}" = "dwm" ] && command -v dmenu >/dev/null 2>&1; then
dmenu -c -l "${SXMO_DMENU_PORTRAIT_LINES:-9}" "$@"
else
sxmo_dmenu.sh "$@"
fi
}
supertoggle_daemon() {
if superctl status "$1" | grep -q started; then
superctl stop "$1"
sxmo_notify_user.sh "$1 Stopped"
else
superctl start "$1"
sxmo_notify_user.sh "$1 Started"
fi
}
toggle_daemon() {
name="$1"
shift
if sxmo_jobs.sh running "$1" -q; then
sxmo_jobs.sh stop "$@"
notify-send "$name Stopped"
else
sxmo_jobs.sh start "$@" &
notify-send "$name Started"
fi
}
sxmo_type() {
sxmo_type.sh -s 200 "$@"
}
get_focused_window() {
if [ -r "${XDG_RUNTIME_DIR:-/run/user/10000}/sxmo.focusedwin" ]; then
{
read -r WMCLASS || WMCLASS=""
read -r WMNAME || WMNAME=""
} < "${XDG_RUNTIME_DIR:-/run/user/10000}/sxmo.focusedwin"
return
fi
exec 0<<EOF
$(sxmo_wm.sh focusedwindow -r)
EOF
read -r WMCLASS
read -r WMNAME
}
has_tracked_calls() {
[ -d "$XDG_RUNTIME_DIR/sxmo_calls" ] || return 1
for f in "$XDG_RUNTIME_DIR/sxmo_calls"/*; do
[ -e "$f" ] && return 0
done
return 1
}
call_entries() {
has_tracked_calls || return 0
shown_incall_menu=
sxmo_modemcall.sh list_active_calls | while read -r line; do
case "$line" in
*"(ringing-in)")
CALLID="${line%% *}"
CALLID="${CALLID##*/}"
NUMBER="$(sxmo_modemcall.sh vid_to_number "$CALLID")"
CONTACT="$(sxmo_contacts.sh --name "$NUMBER")"
printf "%s Incoming call %s ^ 0 ^ sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incoming_call_menu %s\n" \
"$icon_phn" "$CONTACT" "$CALLID"
;;
*)
[ -n "$shown_incall_menu" ] && continue
shown_incall_menu=1
printf "%s Incall Menu ^ 0 ^ sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incall_menu\n" \
"$icon_phn"
;;
esac
done
}
count_notifications() {
n=0
if [ -d "$SXMO_NOTIFDIR" ]; then
for f in "$SXMO_NOTIFDIR"/*; do
[ -f "$f" ] && n=$((n + 1))
done
fi
printf "%s" "$n"
}
bt_is_unblocked_fast() {
for rfk in /sys/class/rfkill/rfkill*; do
[ -r "$rfk/type" ] || continue
read -r rtype < "$rfk/type" 2>/dev/null || continue
if [ "$rtype" = "bluetooth" ]; then
read -r soft < "$rfk/soft" 2>/dev/null || soft=0
read -r hard < "$rfk/hard" 2>/dev/null || hard=0
[ "$soft" = "0" ] && [ "$hard" = "0" ] && return 0
return 1
fi
done
return 1
}
fast_sys_choices() {
WINNAME="Sys"
_bt_line=""
if bt_is_unblocked_fast; then
_bt_line="$icon_bth Bluetooth^1^sxmo_bluetoothmenu.sh
"
fi
_flash_line=""
_bl=""
if [ -r /sys/class/leds/white:torch/brightness ]; then
read -r _bl < /sys/class/leds/white:torch/brightness 2>/dev/null || _bl=""
elif [ -r /sys/class/leds/white:flash/brightness ]; then
read -r _bl < /sys/class/leds/white:flash/brightness 2>/dev/null || _bl=""
fi
if [ -n "$_bl" ]; then
if [ "$_bl" -gt 0 ] 2>/dev/null; then
_flash_line="$icon_fll Flashlight $icon_ton^1^sxmo_flashtoggle.sh
"
else
_flash_line="$icon_fll Flashlight $icon_tof^1^sxmo_flashtoggle.sh
"
fi
fi
CHOICES="$icon_trm St^0^st -e ${SHELL:-/bin/sh}
$icon_grd Apps^0^sxmo_appmenu.sh applications
$icon_grd Scripts^0^sxmo_appmenu.sh scripts
$icon_dir Files^0^sxmo_files.sh
$icon_phn Dialer^0^sxmo_modemdial.sh
$icon_msg Texts^0^sxmo_modemtext.sh
$icon_usr Contacts^0^sxmo_contactmenu.sh
${_bt_line}$icon_cam Camera^0^bananarchy-photo --menu
${_flash_line}$icon_net Networks^0^sxmo_networks.sh
$icon_mus Audio^0^sxmo_audio.sh
$icon_phn Modem^0^sxmo_appmenu.sh modem
$icon_win Windows^0^sxmo_wmmenu.sh
$icon_cfg Config^0^sxmo_appmenu.sh config
$icon_pwr Power^0^sxmo_appmenu.sh power"
}
getprogchoices() {
case "$WMCLASS" in
""|sys)
fast_sys_choices
;;
applications)
WINNAME="Apps"
if [ -s "${XDG_RUNTIME_DIR:-/tmp}/sxmo_apps.cache" ]; then
CHOICES="$(cat "${XDG_RUNTIME_DIR:-/tmp}/sxmo_apps.cache")"
else
CHOICES="$(sxmo_hook_apps.sh)"
fi
;;
scripts)
WINNAME="Scripts"
if [ -s "${XDG_RUNTIME_DIR:-/tmp}/sxmo_scripts.cache" ]; then
CHOICES="$(cat "${XDG_RUNTIME_DIR:-/tmp}/sxmo_scripts.cache")"
else
CHOICES="$(sxmo_hook_scripts.sh)"
fi
;;
power)
WINNAME="Power"
CHOICES="$icon_lck Lock^0^sxmo_state.sh set lock
$icon_lck Lock (Screen off)^0^sxmo_state.sh set screenoff
$icon_out Logout^0^confirm Logout && sxmo_power.sh logout
$icon_rld Reboot^0^confirm Reboot && sxmo_power.sh reboot
$icon_pwr Poweroff^0^confirm Poweroff && sxmo_power.sh poweroff"
;;
modem)
WINNAME="Modem"
CHOICES="$icon_plk Modem PIN^0^sxmo_unlocksim.sh
$icon_inf Modem Info^0^sxmo_modeminfo.sh
$icon_phl Modem Log^0^sxmo_modemlog.sh"
;;
config)
WINNAME="Config"
_bt_icon="$icon_tof"
bt_is_unblocked_fast && _bt_icon="$icon_ton"
_susp_icon="$icon_ton"
[ -e "${XDG_CACHE_HOME:-$HOME/.cache}/sxmo/sxmo.nosuspend" ] && _susp_icon="$icon_tof"
_idle_icon="$icon_ton"
[ -e "${XDG_CACHE_HOME:-$HOME/.cache}/sxmo/sxmo.noidle" ] && _idle_icon="$icon_tof"
CHOICES="$icon_aru Brightness^1^sxmo_brightness.sh up
$icon_ard Brightness^1^sxmo_brightness.sh down
$icon_cfg Toggle Bar^0^sxmo_wm.sh togglebar
$icon_bth Bluetooth $_bt_icon^1^doas sxmo_bluetoothtoggle.sh && sxmo_hook_statusbar.sh bluetooth
$icon_clk Change Timezone^1^sxmo_timezonechange.sh
$icon_zzz Auto-suspend $_susp_icon^1^(rm ${XDG_CACHE_HOME:-$HOME/.cache}/sxmo/sxmo.nosuspend 2>/dev/null || touch ${XDG_CACHE_HOME:-$HOME/.cache}/sxmo/sxmo.nosuspend)
$icon_zzz Auto-screen-off $_idle_icon^1^(rm ${XDG_CACHE_HOME:-$HOME/.cache}/sxmo/sxmo.noidle 2>/dev/null || touch ${XDG_CACHE_HOME:-$HOME/.cache}/sxmo/sxmo.noidle) && sxmo_state.sh set unlock
$icon_trm Hooks^0^sxmo_hookmenu.sh
$icon_cfg Suspend Blockers^0^sxmo_terminal.sh sxmo_debug_suspend.sh
$icon_inf Log^0^sxmo_terminal.sh tail -n 100 -f ${XDG_STATE_HOME:-$HOME}/sxmo.log
$icon_inf Version^0^sxmo_terminal.sh sxmo_version.sh --block"
;;
*)
RES="$(sxmo_hook_contextmenu.sh "$WMCLASS" "$WMNAME")"
if [ -n "$RES" ]; then
nl='
'
WINNAME="${RES%%"$nl"*}"
CHOICES="${RES#*"$nl"}"
fi
;;
esac
if [ "$WINNAME" = "Sys" ]; then
NNOTIFICATIONS="$(count_notifications)"
if [ "$NNOTIFICATIONS" -gt 0 ]; then
CHOICES="$icon_bel Notifications ($NNOTIFICATIONS)^0^sxmo_notifs.sh menu
$CHOICES"
fi
fi
if has_tracked_calls; then
CHOICES="$(call_entries)
$CHOICES"
fi
case "$WINNAME" in
*Sys*) ;;
*)
CHOICES="$CHOICES
$icon_mnu System Menu^0^sxmo_appmenu.sh sys"
;;
esac
CHOICES="$CHOICES
$icon_cls Close Menu^0^quit"
case "$WMCLASS" in
""|sys|applications|scripts|power|modem|config)
;;
*)
CHOICES="$(printf "%s\n" "$CHOICES" | awk 'NF {$1=$1; print}')"
;;
esac
}
quit() {
exit 0
}
mainloop() {
getprogchoices
PICKED="$(
printf "%s\n" "$CHOICES" |
cut -d'^' -f1 |
run_dmenu -i -p "$WINNAME"
)" || quit
CHOICE="$(printf "%s\n" "$CHOICES" | awk -F '^' -v picked="$PICKED" \
'$1 == picked || $1 == picked " " {print $2 "^" $3; exit}'
)"
LOOP="${CHOICE%%^*}"
CMD="${CHOICE#*^}"
CMD="${CMD#"${CMD%%[![:space:]]*}"}"
if [ -z "$CHOICE" ] || [ -z "$CMD" ]; then
printf "%s\n" "sxmo_appmenu: Fallback: unknown choice <$PICKED> to contextmenu_fallback hook">&2
sxmo_hook_contextmenu_fallback.sh "$WINNAME" "$PICKED"
quit
fi
case "$CMD" in
"sxmo_appmenu.sh "*)
set -- ${CMD#sxmo_appmenu.sh }
WMCLASS="$1"
WMNAME="$2"
return 0
;;
esac
eval "$CMD"
case "$LOOP" in
*1*) ;;
*) quit ;;
esac
}
if [ -z "$SHELLSPEC_PATH" ]; then
if [ $# -gt 0 ] ; then
WMCLASS="$1"
WMNAME="$2"
else
get_focused_window
fi
while true; do
mainloop
done
fi