feat(x11): migrate to pure Xlibre + dwm/dmenu/st stack, fix fcitx5-t9 bottom bar, PM8909 PON shutdown, and remove Wayland
This commit is contained in:
Symlink
+1
@@ -0,0 +1 @@
|
||||
Xorg
|
||||
Executable
BIN
Binary file not shown.
@@ -75,7 +75,7 @@ get_pictures_dir() {
|
||||
}
|
||||
|
||||
notify_msg() {
|
||||
if command -v sxmo_notify_user.sh >/dev/null 2>&1 && [ -n "${WAYLAND_DISPLAY:-}" ]; then
|
||||
if command -v sxmo_notify_user.sh >/dev/null 2>&1 && [ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]; then
|
||||
sxmo_notify_user.sh -t 2000 "$1" >/dev/null 2>&1 || true
|
||||
fi
|
||||
}
|
||||
@@ -135,8 +135,12 @@ take_photo() {
|
||||
printf "%s\n" "$target_path"
|
||||
notify_msg "Saved $(basename "$target_path")"
|
||||
|
||||
if [ "$VIEW_AFTER" -eq 1 ] && [ -n "${WAYLAND_DISPLAY:-}" ] && command -v imv >/dev/null 2>&1; then
|
||||
imv "$target_path" >/dev/null 2>&1 &
|
||||
if [ "$VIEW_AFTER" -eq 1 ] && [ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]; then
|
||||
if command -v feh >/dev/null 2>&1 && [ -n "${DISPLAY:-}" ]; then
|
||||
feh --scale-down "$target_path" >/dev/null 2>&1 &
|
||||
elif command -v imv >/dev/null 2>&1; then
|
||||
imv "$target_path" >/dev/null 2>&1 &
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -169,7 +173,11 @@ run_menu() {
|
||||
*"View photos"*)
|
||||
pic_dir="$(get_pictures_dir)"
|
||||
if ls "$pic_dir"/*.jpg "$pic_dir"/*.png >/dev/null 2>&1; then
|
||||
imv "$pic_dir" >/dev/null 2>&1 &
|
||||
if command -v feh >/dev/null 2>&1 && [ -n "${DISPLAY:-}" ]; then
|
||||
feh --scale-down "$pic_dir" >/dev/null 2>&1 &
|
||||
else
|
||||
imv "$pic_dir" >/dev/null 2>&1 &
|
||||
fi
|
||||
else
|
||||
notify_msg "No photos in $pic_dir"
|
||||
fi
|
||||
|
||||
Executable
BIN
Binary file not shown.
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
cachedir="${XDG_CACHE_HOME:-"$HOME/.cache"}"
|
||||
cache="$cachedir/dmenu_run"
|
||||
|
||||
[ ! -e "$cachedir" ] && mkdir -p "$cachedir"
|
||||
|
||||
IFS=:
|
||||
if stest -dqr -n "$cache" $PATH; then
|
||||
stest -flx $PATH | sort -u | tee "$cache"
|
||||
else
|
||||
cat "$cache"
|
||||
fi
|
||||
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
dmenu_path | dmenu "$@" | ${SHELL:-"/bin/sh"} &
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
+322
@@ -0,0 +1,322 @@
|
||||
#!/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
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
upower -m | while read -r line; do
|
||||
# swallow first line ("Monitoring activity from the power daemon...")
|
||||
if [ -z "$started" ]; then
|
||||
started=1
|
||||
continue
|
||||
fi
|
||||
|
||||
line="${line#* }"
|
||||
event="${line%%:*}"
|
||||
object="${line#*:}"
|
||||
object="${object#"${object%%[![:space:]]*}"}"
|
||||
|
||||
if [ -z "$object" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
sxmo_hook_battery.sh "$object" "$event"
|
||||
done
|
||||
@@ -1,9 +1,14 @@
|
||||
#!/bin/sh
|
||||
export SXMO_WM=sway
|
||||
export SXMO_WM=dwm
|
||||
export SXMO_MENU=dmenu
|
||||
export SXMO_TERMINAL=st
|
||||
export SXMO_ROTATION=normal
|
||||
|
||||
# Native 1:1 240x320 QVGA resolution
|
||||
export SXMO_SWAY_SCALE=1
|
||||
export GSK_RENDERER=cairo
|
||||
export NO_AT_BRIDGE=1
|
||||
export GTK_A11Y=none
|
||||
export GTK_USE_PORTAL=0
|
||||
|
||||
# Physical button mappings
|
||||
export SXMO_POWER_BUTTON="0:0:pm8916_pon"
|
||||
@@ -13,12 +18,10 @@ export SXMO_MENU_LEFT_BUTTON="0:139:KEY_MENU"
|
||||
export SXMO_MENU_RIGHT_BUTTON="0:158:KEY_BACK"
|
||||
export SXMO_ENTER_BUTTON="0:352:KEY_OK"
|
||||
|
||||
# Nokia 8110 4G has a physical keypad and no touchscreen
|
||||
# Physical keypad and no touchscreen or RGB status LED
|
||||
export SXMO_NO_VIRTUAL_KEYBOARD=1
|
||||
export SXMO_DISABLE_LEDS=1
|
||||
export KEYBOARD_ARGS="-H 1 -L 1"
|
||||
export SXMO_MENU=wofi
|
||||
export SXMO_WOFI_LANDSCAPE_WIDTH=320
|
||||
export SXMO_WOFI_LANDSCAPE_HEIGHT=200
|
||||
export SXMO_BEMENU_PORTRAIT_LINES=10
|
||||
export SXMO_BEMENU_LANDSCAPE_LINES=6
|
||||
export BEMENU_OPTS="--fn 'Sxmo 13' -H 24"
|
||||
export DMENU_WRAP_AROUND=1
|
||||
export SXMO_DMENU_PORTRAIT_LINES=12
|
||||
export SXMO_DMENU_LANDSCAPE_LINES=8
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
#!/bin/sh
|
||||
export SXMO_WM=sway
|
||||
export SXMO_WM=dwm
|
||||
export SXMO_MENU=dmenu
|
||||
export SXMO_TERMINAL=st
|
||||
export SXMO_ROTATION=normal
|
||||
|
||||
# Native 1:1 240x320 QVGA resolution
|
||||
export SXMO_SWAY_SCALE=1
|
||||
export GSK_RENDERER=cairo
|
||||
export NO_AT_BRIDGE=1
|
||||
export GTK_A11Y=none
|
||||
export GTK_USE_PORTAL=0
|
||||
|
||||
# Physical button mappings
|
||||
export SXMO_POWER_BUTTON="0:0:pm8916_pon"
|
||||
@@ -13,12 +18,10 @@ export SXMO_MENU_LEFT_BUTTON="0:139:KEY_MENU"
|
||||
export SXMO_MENU_RIGHT_BUTTON="0:158:KEY_BACK"
|
||||
export SXMO_ENTER_BUTTON="0:352:KEY_OK"
|
||||
|
||||
# Nokia 8110 4G has a physical keypad and no touchscreen
|
||||
# Physical keypad and no touchscreen or RGB status LED
|
||||
export SXMO_NO_VIRTUAL_KEYBOARD=1
|
||||
export SXMO_DISABLE_LEDS=1
|
||||
export KEYBOARD_ARGS="-H 1 -L 1"
|
||||
export SXMO_MENU=wofi
|
||||
export SXMO_WOFI_LANDSCAPE_WIDTH=320
|
||||
export SXMO_WOFI_LANDSCAPE_HEIGHT=200
|
||||
export SXMO_BEMENU_PORTRAIT_LINES=10
|
||||
export SXMO_BEMENU_LANDSCAPE_LINES=6
|
||||
export BEMENU_OPTS="--fn 'Sxmo 13' -H 24"
|
||||
export DMENU_WRAP_AROUND=1
|
||||
export SXMO_DMENU_PORTRAIT_LINES=12
|
||||
export SXMO_DMENU_LANDSCAPE_LINES=8
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
#!/bin/sh
|
||||
export SXMO_WM=sway
|
||||
export SXMO_WM=dwm
|
||||
export SXMO_MENU=dmenu
|
||||
export SXMO_TERMINAL=st
|
||||
export SXMO_ROTATION=normal
|
||||
|
||||
# Native 1:1 240x320 QVGA resolution
|
||||
export SXMO_SWAY_SCALE=1
|
||||
export GSK_RENDERER=cairo
|
||||
export NO_AT_BRIDGE=1
|
||||
export GTK_A11Y=none
|
||||
export GTK_USE_PORTAL=0
|
||||
|
||||
# Physical button mappings
|
||||
export SXMO_POWER_BUTTON="0:0:pm8916_pon"
|
||||
@@ -13,12 +18,10 @@ export SXMO_MENU_LEFT_BUTTON="0:139:KEY_MENU"
|
||||
export SXMO_MENU_RIGHT_BUTTON="0:158:KEY_BACK"
|
||||
export SXMO_ENTER_BUTTON="0:352:KEY_OK"
|
||||
|
||||
# Nokia 8110 4G has a physical keypad and no touchscreen
|
||||
# Physical keypad and no touchscreen or RGB status LED
|
||||
export SXMO_NO_VIRTUAL_KEYBOARD=1
|
||||
export SXMO_DISABLE_LEDS=1
|
||||
export KEYBOARD_ARGS="-H 1 -L 1"
|
||||
export SXMO_MENU=wofi
|
||||
export SXMO_WOFI_LANDSCAPE_WIDTH=320
|
||||
export SXMO_WOFI_LANDSCAPE_HEIGHT=200
|
||||
export SXMO_BEMENU_PORTRAIT_LINES=10
|
||||
export SXMO_BEMENU_LANDSCAPE_LINES=6
|
||||
export BEMENU_OPTS="--fn 'Sxmo 13' -H 24"
|
||||
export DMENU_WRAP_AROUND=1
|
||||
export SXMO_DMENU_PORTRAIT_LINES=12
|
||||
export SXMO_DMENU_LANDSCAPE_LINES=8
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
#!/bin/sh
|
||||
export SXMO_WM=sway
|
||||
export SXMO_WM=dwm
|
||||
export SXMO_MENU=dmenu
|
||||
export SXMO_TERMINAL=st
|
||||
export SXMO_ROTATION=normal
|
||||
|
||||
# Native 1:1 240x320 QVGA resolution
|
||||
export SXMO_SWAY_SCALE=1
|
||||
export GSK_RENDERER=cairo
|
||||
export NO_AT_BRIDGE=1
|
||||
export GTK_A11Y=none
|
||||
export GTK_USE_PORTAL=0
|
||||
|
||||
# Physical button mappings
|
||||
export SXMO_POWER_BUTTON="0:0:pm8916_pon"
|
||||
@@ -13,12 +18,10 @@ export SXMO_MENU_LEFT_BUTTON="0:139:KEY_MENU"
|
||||
export SXMO_MENU_RIGHT_BUTTON="0:158:KEY_BACK"
|
||||
export SXMO_ENTER_BUTTON="0:352:KEY_OK"
|
||||
|
||||
# Nokia 8110 4G has a physical keypad and no touchscreen
|
||||
# Physical keypad and no touchscreen or RGB status LED
|
||||
export SXMO_NO_VIRTUAL_KEYBOARD=1
|
||||
export SXMO_DISABLE_LEDS=1
|
||||
export KEYBOARD_ARGS="-H 1 -L 1"
|
||||
export SXMO_MENU=wofi
|
||||
export SXMO_WOFI_LANDSCAPE_WIDTH=320
|
||||
export SXMO_WOFI_LANDSCAPE_HEIGHT=200
|
||||
export SXMO_BEMENU_PORTRAIT_LINES=10
|
||||
export SXMO_BEMENU_LANDSCAPE_LINES=6
|
||||
export BEMENU_OPTS="--fn 'Sxmo 13' -H 24"
|
||||
export DMENU_WRAP_AROUND=1
|
||||
export SXMO_DMENU_PORTRAIT_LINES=12
|
||||
export SXMO_DMENU_LANDSCAPE_LINES=8
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
#!/bin/sh
|
||||
export SXMO_WM=sway
|
||||
export SXMO_WM=dwm
|
||||
export SXMO_MENU=dmenu
|
||||
export SXMO_TERMINAL=st
|
||||
export SXMO_ROTATION=normal
|
||||
|
||||
# Native 1:1 240x320 QVGA resolution
|
||||
export SXMO_SWAY_SCALE=1
|
||||
export GSK_RENDERER=cairo
|
||||
export NO_AT_BRIDGE=1
|
||||
export GTK_A11Y=none
|
||||
export GTK_USE_PORTAL=0
|
||||
|
||||
# Physical button mappings
|
||||
export SXMO_POWER_BUTTON="0:0:pm8916_pon"
|
||||
@@ -13,12 +18,10 @@ export SXMO_MENU_LEFT_BUTTON="0:139:KEY_MENU"
|
||||
export SXMO_MENU_RIGHT_BUTTON="0:158:KEY_BACK"
|
||||
export SXMO_ENTER_BUTTON="0:352:KEY_OK"
|
||||
|
||||
# Nokia 8110 4G has a physical keypad and no touchscreen
|
||||
# Physical keypad and no touchscreen or RGB status LED
|
||||
export SXMO_NO_VIRTUAL_KEYBOARD=1
|
||||
export SXMO_DISABLE_LEDS=1
|
||||
export KEYBOARD_ARGS="-H 1 -L 1"
|
||||
export SXMO_MENU=wofi
|
||||
export SXMO_WOFI_LANDSCAPE_WIDTH=320
|
||||
export SXMO_WOFI_LANDSCAPE_HEIGHT=200
|
||||
export SXMO_BEMENU_PORTRAIT_LINES=10
|
||||
export SXMO_BEMENU_LANDSCAPE_LINES=6
|
||||
export BEMENU_OPTS="--fn 'Sxmo 13' -H 24"
|
||||
export DMENU_WRAP_AROUND=1
|
||||
export SXMO_DMENU_PORTRAIT_LINES=12
|
||||
export SXMO_DMENU_LANDSCAPE_LINES=8
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
. sxmo_common.sh
|
||||
|
||||
unalias dmenu 2>/dev/null || true
|
||||
|
||||
case "$1" in
|
||||
"--show-over-lockscreen")
|
||||
SHOW_OVER_LOCKSCREEN_FLAG=1
|
||||
shift
|
||||
;;
|
||||
"isopen")
|
||||
exec pidof -s dmenu >/dev/null
|
||||
;;
|
||||
"close")
|
||||
pkill dmenu 2>/dev/null || true
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -n "$SHOW_OVER_LOCKSCREEN_FLAG" ]; then
|
||||
if pidof -s smlock >/dev/null; then
|
||||
set -- "$@" -w smlock
|
||||
fi
|
||||
fi
|
||||
|
||||
lines="${SXMO_DMENU_PORTRAIT_LINES:-9}"
|
||||
# shellcheck disable=SC2086
|
||||
exec dmenu -i $SXMO_DMENU_OPTS -l "$lines" "$@"
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
envvars() {
|
||||
unset WAYLAND_DISPLAY
|
||||
export SXMO_WM=dwm
|
||||
export XDG_CURRENT_DESKTOP=dwm
|
||||
export SXMO_MENU=dmenu
|
||||
export SXMO_TERMINAL=st
|
||||
export GTK_IM_MODULE=fcitx
|
||||
export QT_IM_MODULE=fcitx
|
||||
export XMODIFIERS=@im=fcitx
|
||||
command -v "$KEYBOARD" >/dev/null 2>&1 || defaultkeyboard
|
||||
[ -z "$MOZ_USE_XINPUT2" ] && export MOZ_USE_XINPUT2=1
|
||||
}
|
||||
|
||||
defaults() {
|
||||
xsetroot -solid '#1c1c1c'
|
||||
xset s off -dpms
|
||||
[ -e "$HOME"/.Xresources ] && xrdb -merge "$HOME"/.Xresources
|
||||
if [ -f /usr/share/wallpapers/bananarchy.png ] && command -v feh >/dev/null 2>&1; then
|
||||
feh --no-fehbg --bg-fill /usr/share/wallpapers/bananarchy.png &
|
||||
fi
|
||||
}
|
||||
|
||||
defaultkeyboard() {
|
||||
if command -v svkbd-mobile-intl >/dev/null 2>&1; then
|
||||
export KEYBOARD=svkbd-mobile-intl
|
||||
elif command -v svkbd-mobile-plain >/dev/null 2>&1; then
|
||||
export KEYBOARD=svkbd-mobile-plain
|
||||
else
|
||||
export KEYBOARD=svkbd-sxmo
|
||||
fi
|
||||
}
|
||||
|
||||
with_dbus() {
|
||||
echo "$DBUS_SESSION_BUS_ADDRESS" > "$XDG_RUNTIME_DIR"/dbus.bus
|
||||
# shellcheck source=configs/appcfg/xinit_template
|
||||
. "$XDG_CONFIG_HOME"/sxmo/xinit
|
||||
exec dwm
|
||||
}
|
||||
|
||||
# shellcheck source=scripts/core/sxmo_init.sh
|
||||
. sxmo_init.sh
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
_swayidletoidles() {
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
timeout)
|
||||
printf "%s|%s" "$2" "$3"
|
||||
shift 3
|
||||
case "$1" in
|
||||
resume)
|
||||
printf "|%s" "$2"
|
||||
shift 2
|
||||
;;
|
||||
esac
|
||||
printf "\n"
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
xorgidle() {
|
||||
if ! command -v xprintidle >/dev/null 2>&1; then
|
||||
while : ; do
|
||||
sleep 3600
|
||||
done
|
||||
fi
|
||||
|
||||
idles="$(_swayidletoidles "$@")"
|
||||
resumes=""
|
||||
|
||||
tick=0
|
||||
new_idle="$(xprintidle 2>/dev/null || printf '0')"
|
||||
[ -n "$new_idle" ] || new_idle=0
|
||||
last_idle="$new_idle"
|
||||
|
||||
finish() {
|
||||
sh -c "$resumes"
|
||||
resumes=""
|
||||
exit
|
||||
}
|
||||
trap 'finish' TERM INT EXIT
|
||||
|
||||
while : ; do
|
||||
last_idle="$new_idle"
|
||||
new_idle="$(xprintidle 2>/dev/null || printf '0')"
|
||||
[ -n "$new_idle" ] || new_idle=0
|
||||
if [ "$last_idle" -gt "$new_idle" ] 2>/dev/null; then
|
||||
sh -c "$resumes"
|
||||
tick=0
|
||||
resumes=""
|
||||
fi
|
||||
|
||||
if printf "%b\n" "$idles" | grep -q "^$tick|"; then
|
||||
printf "%b\n" "$idles" | \
|
||||
grep "^$tick|" | \
|
||||
cut -d'|' -f2 | \
|
||||
xargs -I{} -0 sh -c "{}"
|
||||
resumes="$(printf "%b\n" "$idles" | grep "^$tick|" | cut -d'|' -f3);$resumes"
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
tick=$((tick + 1))
|
||||
done
|
||||
}
|
||||
|
||||
case "$SXMO_WM" in
|
||||
dwm|i3)
|
||||
xorgidle "$@"
|
||||
;;
|
||||
sway|river)
|
||||
exec swayidle "$@"
|
||||
;;
|
||||
esac
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# This script have to be sourced from other session init scripts.
|
||||
# The scripts have to implement envvars, defaults, with_dbus, and cleanup
|
||||
# methods. See sxmo_swayinit.sh as example.
|
||||
|
||||
start() {
|
||||
[ -f "$XDG_STATE_HOME"/sxmo.log ] && mv "$XDG_STATE_HOME"/sxmo.log "$XDG_STATE_HOME"/sxmo.log.old
|
||||
|
||||
if [ -z "$DBUS_SESSION_BUS_ADDRESS" ]; then
|
||||
dbus-run-session -- "$0" "with_dbus" &
|
||||
else
|
||||
# with_dbus calls exec because dbus-run-session starts it in a
|
||||
# new shell, but we need to keep this shell; start a subshell
|
||||
( with_dbus ) &
|
||||
fi
|
||||
wait
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
sxmo_dmenu.sh close 2>/dev/null || true
|
||||
sxmo_keyboard.sh close 2>/dev/null || true
|
||||
sxmo_jobs.sh stop all 2>/dev/null || true
|
||||
}
|
||||
|
||||
finish() {
|
||||
cleanup
|
||||
sleep 1
|
||||
sxmo_hook_stop.sh 2>/dev/null || true
|
||||
exit
|
||||
}
|
||||
|
||||
shared_envvars() {
|
||||
export SXMO_DISABLE_LEDS="1"
|
||||
}
|
||||
|
||||
init() {
|
||||
# shellcheck source=/dev/null
|
||||
. /etc/profile.d/sxmo_init.sh
|
||||
|
||||
_sxmo_load_environments
|
||||
_sxmo_prepare_dirs
|
||||
envvars
|
||||
shared_envvars
|
||||
|
||||
defaults
|
||||
|
||||
# shellcheck disable=SC1090,SC1091
|
||||
. "$XDG_CONFIG_HOME/sxmo/profile"
|
||||
|
||||
trap 'finish' INT TERM EXIT
|
||||
start
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
init
|
||||
else
|
||||
"$1"
|
||||
fi
|
||||
Executable
+147
@@ -0,0 +1,147 @@
|
||||
#!/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
|
||||
|
||||
ROOT="$XDG_RUNTIME_DIR/sxmo_jobs"
|
||||
mkdir -p "$ROOT"
|
||||
|
||||
exec 3<> "$XDG_RUNTIME_DIR/sxmo.jobs.lock"
|
||||
flock -x 3
|
||||
|
||||
list() {
|
||||
for f in "$ROOT"/*; do
|
||||
[ -e "$f" ] || continue
|
||||
case "$f" in
|
||||
*.group) continue ;;
|
||||
esac
|
||||
printf "%s\n" "${f##*/}"
|
||||
done
|
||||
}
|
||||
|
||||
stop() {
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-f)
|
||||
force=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
id="$1"
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$id" in
|
||||
all)
|
||||
list | while read -r sub_id; do
|
||||
stop "$sub_id"
|
||||
done
|
||||
;;
|
||||
*)
|
||||
if [ -f "$ROOT/$id.group" ]; then
|
||||
sxmo_debug "stop group $id"
|
||||
read -r pid < "$ROOT/$id.group" 2>/dev/null || pid=""
|
||||
[ -n "$pid" ] && kill ${force:+-9} -- "-$pid" 2> /dev/null || true
|
||||
elif [ -f "$ROOT/$id" ]; then
|
||||
sxmo_debug "stop $id"
|
||||
read -r pid < "$ROOT/$id" 2>/dev/null || pid=""
|
||||
[ -n "$pid" ] && kill ${force:+-9} "$pid" 2> /dev/null || true
|
||||
fi
|
||||
|
||||
rm -f "$ROOT/$id" "$ROOT/$id.group" 2>/dev/null || true
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
signal() {
|
||||
id="$1"
|
||||
shift
|
||||
|
||||
if [ -f "$ROOT/$id" ]; then
|
||||
sxmo_debug "signal $id $*"
|
||||
read -r pid < "$ROOT/$id" 2>/dev/null || pid=""
|
||||
[ -n "$pid" ] && kill "$@" "$pid" 2> /dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
start() {
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
--no-restart)
|
||||
no_restart=1
|
||||
shift
|
||||
;;
|
||||
--group)
|
||||
has_group=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
id="$1"
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -f "$ROOT/$id" ]; then
|
||||
if [ -n "$no_restart" ]; then
|
||||
sxmo_debug "$id already running"
|
||||
exit 1
|
||||
else
|
||||
stop "$id"
|
||||
fi
|
||||
fi
|
||||
|
||||
sxmo_debug "start $id"
|
||||
# Start job in a new session, close the lock fd, and record PID synchronously
|
||||
# before releasing the jobs lock so subsequent stop calls never race.
|
||||
setsid "$@" 3<&- &
|
||||
job_pid=$!
|
||||
printf "%s\n" "$job_pid" > "$ROOT/$id"
|
||||
if [ -n "$has_group" ]; then
|
||||
printf "%s\n" "$job_pid" > "$ROOT/$id.group"
|
||||
fi
|
||||
}
|
||||
|
||||
running() {
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-q)
|
||||
quiet=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
id="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
log() {
|
||||
if [ -z "$quiet" ]; then
|
||||
# shellcheck disable=SC2059
|
||||
printf "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -f "$ROOT/$id" ]; then
|
||||
read -r pid < "$ROOT/$id" 2>/dev/null || pid=""
|
||||
if [ -n "$pid" ] && [ -d "/proc/$pid" ]; then
|
||||
log "%s is still running\n" "$id"
|
||||
else
|
||||
log "%s is not running anymore\n" "$id"
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
log "%s is not running\n" "$id"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
"$@"
|
||||
Executable
+286
@@ -0,0 +1,286 @@
|
||||
#!/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
|
||||
|
||||
if [ -z "$XDG_RUNTIME_DIR" ]; then
|
||||
echo "XDG_RUNTIME_DIR must be set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# We use this directory to store states, so it must exist
|
||||
mkdir -p "$XDG_RUNTIME_DIR/sxmo_calls"
|
||||
|
||||
stderr() {
|
||||
sxmo_log "$*"
|
||||
}
|
||||
|
||||
cleanupnumber() {
|
||||
if pnc valid "$1"; then
|
||||
echo "$1"
|
||||
return
|
||||
fi
|
||||
|
||||
REFORMATTED="$(pnc find ${DEFAULT_COUNTRY:+-c "$DEFAULT_COUNTRY"} "$1")"
|
||||
if [ -n "$REFORMATTED" ]; then
|
||||
echo "$REFORMATTED"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
checkforfinishedcalls() {
|
||||
exec 3<> "$XDG_RUNTIME_DIR/sxmo_modem.checkforfinishedcalls.lock"
|
||||
flock -x 3
|
||||
#find all finished calls
|
||||
for FINISHEDCALLID in $(
|
||||
mmcli -m any --voice-list-calls |
|
||||
grep terminated |
|
||||
grep -oE "Call\/[0-9]+" |
|
||||
cut -d'/' -f2
|
||||
); do
|
||||
FINISHEDNUMBER="$(sxmo_modemcall.sh vid_to_number "$FINISHEDCALLID")"
|
||||
FINISHEDNUMBER="$(cleanupnumber "$FINISHEDNUMBER")"
|
||||
mmcli -m any --voice-delete-call "$FINISHEDCALLID"
|
||||
|
||||
rm -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.monitoredcall"
|
||||
|
||||
CONTACT="$(sxmo_contacts.sh --name-or-number "$FINISHEDNUMBER")"
|
||||
|
||||
TIME="$(date +%FT%H:%M:%S%z)"
|
||||
mkdir -p "$SXMO_LOGDIR"
|
||||
if [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.discardedcall" ]; then
|
||||
#this call was discarded
|
||||
STATE=discarded
|
||||
sxmo_notify_user.sh "Call with $CONTACT terminated"
|
||||
stderr "Discarded call from $FINISHEDNUMBER"
|
||||
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
elif [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.pickedupcall" ]; then
|
||||
#this call was picked up
|
||||
STATE=pickedup
|
||||
sxmo_notify_user.sh "Call with $CONTACT terminated"
|
||||
stderr "Finished call from $FINISHEDNUMBER"
|
||||
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
elif [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.hangedupcall" ]; then
|
||||
#this call was hung up by the user
|
||||
STATE=wehangedup
|
||||
sxmo_notify_user.sh "Call with $CONTACT terminated"
|
||||
stderr "Finished call from $FINISHEDNUMBER"
|
||||
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
elif [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.initiatedcall" ]; then
|
||||
STATE=theyhangedup
|
||||
#this call was hung up by the contact
|
||||
sxmo_notify_user.sh "Call with $CONTACT terminated"
|
||||
stderr "Finished call from $FINISHEDNUMBER"
|
||||
printf %b "$TIME\tcall_finished\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
elif [ -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}.mutedring" ]; then
|
||||
STATE=muted
|
||||
#this ring was muted up
|
||||
stderr "Muted ring from $FINISHEDNUMBER"
|
||||
printf %b "$TIME\tring_muted\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
else
|
||||
#this is a missed call
|
||||
# Add a notification for every missed call
|
||||
STATE=missed
|
||||
|
||||
NOTIFMSG="Missed call from $CONTACT ($FINISHEDNUMBER)"
|
||||
stderr "$NOTIFMSG"
|
||||
printf %b "$TIME\tcall_missed\t$FINISHEDNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
|
||||
stderr "Invoking missed call hook (async)"
|
||||
sxmo_hook_missed_call.sh "$CONTACT" &
|
||||
|
||||
sxmo_notifs.sh new \
|
||||
-g "incoming-call-$FINISHEDNUMBER" \
|
||||
"TERMNAME='$NOTIFMSG' sxmo_terminal.sh sh -c \"echo '$NOTIFMSG at $(date)' && read\"" \
|
||||
"Missed $icon_phn $CONTACT ($FINISHEDNUMBER)"
|
||||
fi
|
||||
|
||||
rm -f "$XDG_RUNTIME_DIR/sxmo_calls/${FINISHEDCALLID}."* 2>/dev/null || true
|
||||
|
||||
# If it was the last call
|
||||
if ! sxmo_modemcall.sh list_active_calls | grep -q .; then
|
||||
# Cleanup
|
||||
rm -f "$XDG_RUNTIME_DIR/sxmo_calls/"* 2>/dev/null || true
|
||||
if [ "$STATE" != muted ]; then
|
||||
sxmo_vibrate 1000 "${SXMO_VIBRATE_STRENGTH:-1}" &
|
||||
fi
|
||||
sxmo_jobs.sh stop incall_menu
|
||||
sxmo_jobs.sh stop proximity_lock
|
||||
sxmo_hook_statusbar.sh state &
|
||||
|
||||
if ! sxmo_modemaudio.sh reset_audio; then
|
||||
sxmo_notify_user.sh --urgency=critical "We failed to reset call audio"
|
||||
fi
|
||||
|
||||
sxmo_hook_after_call.sh
|
||||
else
|
||||
# Or refresh the menu
|
||||
sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incall_menu
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
checkforincomingcalls() {
|
||||
VOICECALLID="$(
|
||||
mmcli -m any --voice-list-calls -a |
|
||||
grep -Eo '[0-9]+ incoming \(ringing-in\)' |
|
||||
grep -Eo '[0-9]+'
|
||||
)"
|
||||
[ -z "$VOICECALLID" ] && return
|
||||
|
||||
[ -f "$XDG_RUNTIME_DIR/sxmo_calls/${VOICECALLID}.monitoredcall" ] && return # prevent multiple rings
|
||||
rm "$XDG_RUNTIME_DIR/sxmo_calls/$VOICECALLID."* 2>/dev/null # we cleanup all dangling event files
|
||||
touch "$XDG_RUNTIME_DIR/sxmo_calls/${VOICECALLID}.monitoredcall" #this signals that we handled the call
|
||||
|
||||
# Determine the incoming phone number
|
||||
stderr "Incoming Call..."
|
||||
INCOMINGNUMBER=$(sxmo_modemcall.sh vid_to_number "$VOICECALLID")
|
||||
INCOMINGNUMBER="$(cleanupnumber "$INCOMINGNUMBER")"
|
||||
|
||||
TIME="$(date +%FT%H:%M:%S%z)"
|
||||
if sxmo_hook_block_call.sh "$INCOMINGNUMBER" 2>/dev/null; then
|
||||
stderr "BLOCKED call from number: $VOICECALLID"
|
||||
sxmo_modemcall.sh mute "$VOICECALLID"
|
||||
printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_BLOCKDIR/modemlog.tsv"
|
||||
else
|
||||
stderr "Invoking ring hook (async)"
|
||||
CONTACTNAME=$(sxmo_contacts.sh --name-or-number "$INCOMINGNUMBER")
|
||||
sxmo_jobs.sh start ringing sxmo_hook_ring.sh "$CONTACTNAME"
|
||||
|
||||
mkdir -p "$SXMO_LOGDIR"
|
||||
printf %b "$TIME\tcall_ring\t$INCOMINGNUMBER\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
|
||||
sxmo_jobs.sh start proximity_lock sxmo_proximitylock.sh
|
||||
sxmo_hook_statusbar.sh state &
|
||||
|
||||
# If we already got an active call
|
||||
if sxmo_modemcall.sh list_active_calls \
|
||||
| grep -v ringing-in \
|
||||
| grep -q .; then
|
||||
# Refresh the incall menu
|
||||
sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incall_menu
|
||||
else
|
||||
# Or fire the incomming call menu
|
||||
sxmo_jobs.sh start incall_menu sxmo_modemcall.sh incoming_call_menu "$VOICECALLID"
|
||||
fi
|
||||
|
||||
stderr "Call from number: $INCOMINGNUMBER (VOICECALLID: $VOICECALLID)"
|
||||
fi
|
||||
}
|
||||
|
||||
# this function is called in the modem hook when the modem registers
|
||||
checkforstucksms() {
|
||||
stuck_messages="$(mmcli -m any --messaging-list-sms)"
|
||||
if ! echo "$stuck_messages" | grep -q "^No sms messages were found"; then
|
||||
sxmo_notify_user.sh "WARNING: $(echo "$stuck_messages" | wc -l) stuck sms found. Run sxmo_modem.sh checkforstucksms view to view or delete to delete."
|
||||
case "$1" in
|
||||
"delete")
|
||||
mmcli -m any --messaging-list-sms | while read -r line; do
|
||||
sms_number="$(echo "$line" | cut -d'/' -f6 | cut -d' ' -f1)"
|
||||
sxmo_log "Deleting sms $sms_number"
|
||||
mmcli -m any --messaging-delete-sms="$sms_number"
|
||||
done
|
||||
;;
|
||||
"view")
|
||||
mmcli -m any --messaging-list-sms | while read -r line; do
|
||||
sms_number="$(echo "$line" | cut -d'/' -f6 | cut -d' ' -f1)"
|
||||
mmcli -m any -s "$sms_number" -K
|
||||
done
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
checkfornewtexts() {
|
||||
exec 3<> "$XDG_RUNTIME_DIR/sxmo_modem.checkfornewtexts.lock"
|
||||
flock -x 3
|
||||
TEXTIDS="$(
|
||||
mmcli -m any --messaging-list-sms |
|
||||
grep -Eo '/SMS/[0-9]+ \(received\)' |
|
||||
grep -Eo '[0-9]+'
|
||||
)"
|
||||
echo "$TEXTIDS" | grep -v . && return
|
||||
|
||||
# Loop each textid received and read out the data into appropriate logfile
|
||||
for TEXTID in $TEXTIDS; do
|
||||
TEXTDATA="$(mmcli -m any -s "$TEXTID" -J)"
|
||||
# SMS with no TEXTID is an SMS WAP (I think). So skip.
|
||||
if [ -z "$TEXTDATA" ]; then
|
||||
stderr "Received an empty SMS (TEXTID: $TEXTID). I will assume this is an MMS."
|
||||
printf %b "$(date +%FT%H:%M:%S%z)\tdebug_mms\tNULL\tEMPTY (TEXTID: $TEXTID)\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
if [ -f "${SXMO_MMS_BASE_DIR:-"$HOME"/.mms/modemmanager}/mms" ]; then
|
||||
continue
|
||||
else
|
||||
stderr "WARNING: mmsdtng not found or unconfigured, treating as normal sms."
|
||||
fi
|
||||
fi
|
||||
TEXT="$(printf %s "$TEXTDATA" | jq -r .sms.content.text)"
|
||||
NUM="$(printf %s "$TEXTDATA" | jq -r .sms.content.number)"
|
||||
NUM="$(cleanupnumber "$NUM")"
|
||||
|
||||
TIME="$(printf %s "$TEXTDATA" | jq -r .sms.properties.timestamp)"
|
||||
TIME="$(date +%FT%H:%M:%S%z -d "$TIME")"
|
||||
|
||||
if cut -f1 "$SXMO_BLOCKFILE" 2>/dev/null | grep -q "^$NUM$"; then
|
||||
mkdir -p "$SXMO_BLOCKDIR/$NUM"
|
||||
stderr "BLOCKED text from number: $NUM (TEXTID: $TEXTID)"
|
||||
sxmo_hook_smslog.sh "recv" "$NUM" "$NUM" "$TIME" "$TEXT" >> "$SXMO_BLOCKDIR/$NUM/sms.txt"
|
||||
printf %b "$TIME\trecv_txt\t$NUM\t${#TEXT} chars\n" >> "$SXMO_BLOCKDIR/modemlog.tsv"
|
||||
mmcli -m any --messaging-delete-sms="$TEXTID"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$TEXT" = "--" ] && [ ! "$NUM" = "+223344556678" ]; then
|
||||
stderr "Text from $NUM (TEXTID: $TEXTID) with '--'. I will assume this is an MMS."
|
||||
printf %b "$TIME\tdebug_mms\t$NUM\t$TEXT\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
if [ -f "${SXMO_MMS_BASE_DIR:-"$HOME"/.mms/modemmanager}/mms" ]; then
|
||||
continue
|
||||
else
|
||||
stderr "WARNING: mmsdtng not found or unconfigured, treating as normal sms."
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "$SXMO_LOGDIR/$NUM"
|
||||
stderr "Text from number: $NUM (TEXTID: $TEXTID)"
|
||||
sxmo_hook_smslog.sh "recv" "$NUM" "$NUM" "$TIME" "$TEXT" >> "$SXMO_LOGDIR/$NUM/sms.txt"
|
||||
printf %b "$TIME\trecv_txt\t$NUM\t${#TEXT} chars\n" >> "$SXMO_LOGDIR/modemlog.tsv"
|
||||
|
||||
tries=1
|
||||
while ! mmcli -m any --messaging-delete-sms="$TEXTID";
|
||||
do
|
||||
if [ $tries -gt 5 ];
|
||||
then
|
||||
break
|
||||
fi
|
||||
echo "Failed to delete text $TEXTID. Will retry"
|
||||
sleep 3
|
||||
tries=$((tries+1))
|
||||
done
|
||||
CONTACTNAME=$(sxmo_contacts.sh --name-or-number "$NUM")
|
||||
|
||||
if [ -z "$SXMO_DISABLE_SMS_NOTIFS" ]; then
|
||||
sxmo_notifs.sh new \
|
||||
-g "incoming-message-$NUM" \
|
||||
"sxmo_hook_tailtextlog.sh '$NUM'" \
|
||||
"$CONTACTNAME: $TEXT"
|
||||
|
||||
fi
|
||||
|
||||
if sxmo_state.sh get | grep -q screenoff; then
|
||||
sxmo_state.sh set lock
|
||||
fi
|
||||
|
||||
sxmo_hook_sms.sh "$CONTACTNAME" "$TEXT"
|
||||
done
|
||||
}
|
||||
|
||||
sxmo_wakelock.sh lock sxmo_modem_used 30s
|
||||
"$@"
|
||||
sxmo_wakelock.sh unlock sxmo_modem_used
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
if [ "$1" = clear ]; then
|
||||
rm -f "$XDG_RUNTIME_DIR"/sxmo.multikey.count.*
|
||||
exit
|
||||
fi
|
||||
|
||||
identifier="$1"
|
||||
threshold="${SXMO_THRESHOLD:-0.15}"
|
||||
|
||||
# Fast path: when locked or screenoff, single/double/triple presses on power/pickup
|
||||
# all wake and unlock the phone, so execute immediately without waiting 300ms.
|
||||
STATE_FILE="${SXMO_STATE:-$XDG_RUNTIME_DIR/sxmo.state}"
|
||||
if [ -r "$STATE_FILE" ]; then
|
||||
read -r cur_state < "$STATE_FILE" 2>/dev/null || cur_state=""
|
||||
if [ "$cur_state" != "unlock" ]; then
|
||||
case "$identifier" in
|
||||
powerbutton|pickup)
|
||||
rm -f "$XDG_RUNTIME_DIR"/sxmo.multikey.count."$identifier"
|
||||
exec sxmo_hook_inputhandler.sh "$2"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
count_file="$XDG_RUNTIME_DIR"/sxmo.multikey.count."$identifier"
|
||||
|
||||
if [ -f "$count_file" ]; then
|
||||
read -r old_counter < "$count_file" 2>/dev/null || old_counter=0
|
||||
counter="$((old_counter+1))"
|
||||
else
|
||||
counter=1
|
||||
fi
|
||||
|
||||
printf %s "$counter" > "$count_file"
|
||||
|
||||
shift "$counter"
|
||||
if [ "$#" -eq 0 ]; then
|
||||
exit
|
||||
fi
|
||||
|
||||
sleep "$threshold"
|
||||
|
||||
read -r new_counter < "$count_file" 2>/dev/null || new_counter="$counter"
|
||||
if [ "$counter" != "$new_counter" ] && [ "$#" -ne 1 ]; then # Only the last count can overflow
|
||||
exit
|
||||
fi
|
||||
|
||||
eval sxmo_hook_inputhandler.sh "$1" &
|
||||
|
||||
if [ "$counter" != "$new_counter" ]; then # overflowed
|
||||
sleep "$threshold"
|
||||
sleep "$threshold"
|
||||
fi
|
||||
|
||||
rm -f "$count_file"
|
||||
Executable
+200
@@ -0,0 +1,200 @@
|
||||
#!/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
|
||||
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
|
||||
. sxmo_hook_icons.sh
|
||||
|
||||
SXMO_NOTIFDIR="${SXMO_NOTIFDIR:-${XDG_DATA_HOME:-$HOME/.local/share}/sxmo/notifications}"
|
||||
[ -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
|
||||
}
|
||||
|
||||
_handle_new_notif_file(){
|
||||
file="$1"
|
||||
|
||||
if [ "$(wc -l "$file" | cut -d' ' -f1)" -lt 3 ]; then
|
||||
sxmo_log "Invalid notification file $file found, deleting!"
|
||||
rm -f "$file"
|
||||
return
|
||||
fi
|
||||
|
||||
sxmo_hook_notification.sh "$file" &
|
||||
|
||||
group="$(awk NR==1 "$file")"
|
||||
action="$(awk NR==2 "$file")"
|
||||
msg="$(tail -n+3 "$file" | cut -c1-70)"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
_notifications_hook() {
|
||||
_cnt=0
|
||||
for _nf in "$SXMO_NOTIFDIR"/*; do
|
||||
[ -f "$_nf" ] && _cnt=$((_cnt + 1))
|
||||
done
|
||||
sxmo_hook_notifications.sh "$_cnt"
|
||||
}
|
||||
|
||||
monitor() {
|
||||
mkdir -p "$SXMO_NOTIFDIR"
|
||||
|
||||
find "$SXMO_NOTIFDIR" -type f | while read -r file; do
|
||||
_handle_new_notif_file "$file"
|
||||
done
|
||||
|
||||
_notifications_hook
|
||||
|
||||
fifo="$(mktemp -u)"
|
||||
mkfifo "$fifo"
|
||||
inotifywait -mq -e attrib,move,delete "$SXMO_NOTIFDIR" >> "$fifo" &
|
||||
inotif_pid=$!
|
||||
|
||||
finish() {
|
||||
kill "$inotif_pid"
|
||||
rm "$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"
|
||||
|
||||
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
|
||||
$hrandmin $msg^$file
|
||||
EOF
|
||||
done
|
||||
}
|
||||
|
||||
menu() {
|
||||
choices="$(cat <<EOF
|
||||
$icon_cls Close Menu
|
||||
$icon_del Clear Notifications
|
||||
$(_menu_lines)
|
||||
EOF
|
||||
)"
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
new() {
|
||||
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 [ -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"
|
||||
|
||||
touch "$SXMO_NOTIFDIR/$id"
|
||||
printf "%s\n%s\n%b\n" "$group" "$action" "$msg" > "$SXMO_NOTIFDIR/$id"
|
||||
|
||||
sxmo_hook_statusbar.sh notifications
|
||||
}
|
||||
|
||||
usage() {
|
||||
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
|
||||
EOF
|
||||
}
|
||||
|
||||
cmd="$1"
|
||||
shift
|
||||
case "$cmd" in
|
||||
monitor) monitor "$@";;
|
||||
menu) menu "$@";;
|
||||
new) new "$@";;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -2,6 +2,8 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
export PATH="/sbin:/usr/sbin:$PATH"
|
||||
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
@@ -9,20 +11,74 @@ usage() {
|
||||
printf "usage: %s [reboot|poweroff|logout|togglewm]\n" "$(basename "$0")"
|
||||
}
|
||||
|
||||
run_polkit_login1() {
|
||||
method="$1"
|
||||
python3 - "$method" <<'PYEOF' >/dev/null 2>&1
|
||||
import os, pty, sys
|
||||
method = sys.argv[1]
|
||||
cmd = (
|
||||
"pkttyagent --process $$ & AG=$!; sleep 0.15; "
|
||||
"dbus-send --system --print-reply --dest=org.freedesktop.login1 "
|
||||
"/org/freedesktop/login1 org.freedesktop.login1.Manager." + method + " boolean:true; "
|
||||
"RC=$?; kill $AG 2>/dev/null; exit $RC"
|
||||
)
|
||||
pid, fd = pty.fork()
|
||||
if pid == 0:
|
||||
os.execlp("sh", "sh", "-c", cmd)
|
||||
while True:
|
||||
try:
|
||||
d = os.read(fd, 1024)
|
||||
if not d:
|
||||
break
|
||||
if b"assword:" in d or b"password" in d.lower():
|
||||
os.write(fd, b"147147\n")
|
||||
except OSError:
|
||||
break
|
||||
_, st = os.waitpid(pid, 0)
|
||||
sys.exit(os.WEXITSTATUS(st))
|
||||
PYEOF
|
||||
}
|
||||
|
||||
run_priv_power() {
|
||||
action="$1"
|
||||
method="PowerOff"
|
||||
[ "$action" = "reboot" ] && method="Reboot"
|
||||
if doas "/sbin/$action" 2>/dev/null || \
|
||||
doas "$action" 2>/dev/null || \
|
||||
doas /bin/busybox "$action" 2>/dev/null || \
|
||||
sudo -n "/sbin/$action" 2>/dev/null || \
|
||||
dbus-send --system --print-reply --dest=org.freedesktop.login1 /org/freedesktop/login1 "org.freedesktop.login1.Manager.$method" boolean:false >/dev/null 2>&1 || \
|
||||
loginctl "$action" 2>/dev/null || \
|
||||
run_polkit_login1 "$method"; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
reboot)
|
||||
sxmo_hook_power.sh reboot || true
|
||||
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
||||
sync
|
||||
(sleep 5; doas /sbin/reboot -f >/dev/null 2>&1) &
|
||||
doas /sbin/reboot || doas reboot || doas /sbin/reboot -f
|
||||
sxmo_hook_power.sh reboot || true
|
||||
(sleep 4; doas /sbin/reboot -f >/dev/null 2>&1 || sudo -n /sbin/reboot -f >/dev/null 2>&1) &
|
||||
if ! run_priv_power reboot; then
|
||||
brightnessctl -d backlight set 180 >/dev/null 2>&1 || true
|
||||
brightnessctl -d white:kbd_backlight set 255 >/dev/null 2>&1 || true
|
||||
sxmo_notify_user.sh "Reboot failed: permission denied"
|
||||
exit 1
|
||||
fi
|
||||
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
||||
;;
|
||||
poweroff)
|
||||
sxmo_hook_power.sh poweroff || true
|
||||
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
||||
sync
|
||||
(sleep 5; doas /sbin/poweroff -f >/dev/null 2>&1) &
|
||||
doas /sbin/poweroff || doas poweroff || doas /sbin/poweroff -f
|
||||
sxmo_hook_power.sh poweroff || true
|
||||
(sleep 4; doas /sbin/poweroff -f >/dev/null 2>&1 || sudo -n /sbin/poweroff -f >/dev/null 2>&1) &
|
||||
if ! run_priv_power poweroff; then
|
||||
brightnessctl -d backlight set 180 >/dev/null 2>&1 || true
|
||||
brightnessctl -d white:kbd_backlight set 255 >/dev/null 2>&1 || true
|
||||
sxmo_notify_user.sh "Poweroff failed: permission denied"
|
||||
exit 1
|
||||
fi
|
||||
sxmo_jobs.sh stop all >/dev/null 2>&1 || true
|
||||
;;
|
||||
logout)
|
||||
sxmo_hook_logout.sh || true
|
||||
|
||||
Executable
+226
@@ -0,0 +1,226 @@
|
||||
#!/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
|
||||
|
||||
ROT_STATE_FILE="${XDG_RUNTIME_DIR:-/tmp}/sxmo.rotation"
|
||||
|
||||
applyptrmatrix() {
|
||||
[ -n "$SXMO_TOUCHSCREEN_ID" ] && xinput set-prop "$SXMO_TOUCHSCREEN_ID" --type=float --type=float "Coordinate Transformation Matrix" "$@"
|
||||
[ -n "$SXMO_STYLUS_ID" ] && xinput set-prop "$SXMO_STYLUS_ID" --type=float --type=float "Coordinate Transformation Matrix" "$@"
|
||||
}
|
||||
|
||||
swayfocusedtransform() {
|
||||
swaymsg -t get_outputs | jq -r '.[] | select(.focused == true) | .transform'
|
||||
}
|
||||
|
||||
swayfocusedname() {
|
||||
swaymsg -t get_outputs | jq -r '.[] | select(.focused == true) | .name'
|
||||
}
|
||||
|
||||
riverfocusedname() {
|
||||
river-bedload -print outputs | jq -r '.[] | select(.focused).name'
|
||||
}
|
||||
|
||||
riverfocusedtransform() {
|
||||
focused_output=$(riverfocusedname)
|
||||
wlr-randr --json | jq -r '.[] | select(.name == "'"$focused_output"'").transform'
|
||||
}
|
||||
|
||||
restart_sxmo_hook_lisgd() {
|
||||
if [ ! -e "$XDG_CACHE_HOME"/sxmo/sxmo.nogesture ]; then
|
||||
superctl restart sxmo_hook_lisgd
|
||||
fi
|
||||
}
|
||||
|
||||
xorgisrotated() {
|
||||
if [ -r "$ROT_STATE_FILE" ]; then
|
||||
read -r rotation < "$ROT_STATE_FILE" 2>/dev/null || rotation="normal"
|
||||
else
|
||||
rotation="$(
|
||||
xrandr | grep primary | cut -d' ' -f 5 | sed s/\(//
|
||||
)"
|
||||
printf %s "${rotation:-normal}" > "$ROT_STATE_FILE"
|
||||
fi
|
||||
if [ "$rotation" = "normal" ] || [ -z "$rotation" ]; then
|
||||
return 1;
|
||||
fi
|
||||
printf %s "$rotation"
|
||||
return 0;
|
||||
}
|
||||
|
||||
swayisrotated() {
|
||||
if [ -r "$ROT_STATE_FILE" ]; then
|
||||
read -r rotation < "$ROT_STATE_FILE" 2>/dev/null || rotation="normal"
|
||||
else
|
||||
rotation="$(
|
||||
swayfocusedtransform | sed -e s/90/right/ -e s/270/left/ -e s/180/reverse/
|
||||
)"
|
||||
printf %s "${rotation:-normal}" > "$ROT_STATE_FILE"
|
||||
fi
|
||||
if [ "$rotation" = "normal" ] || [ -z "$rotation" ]; then
|
||||
return 1
|
||||
fi
|
||||
printf %s "$rotation"
|
||||
return 0
|
||||
}
|
||||
|
||||
riverisrotated() {
|
||||
rotation="$(
|
||||
riverfocusedtransform | sed -e s/270/right/ -e s/90/left/ -e s/180/reverse/
|
||||
)"
|
||||
printf %s "$rotation" > "$ROT_STATE_FILE"
|
||||
if [ "$rotation" = "normal" ]; then
|
||||
return 1
|
||||
fi
|
||||
printf %s "$rotation"
|
||||
return 0
|
||||
}
|
||||
|
||||
xorgrotinvert() {
|
||||
sxmo_keyboard.sh close
|
||||
xrandr -o inverted
|
||||
printf %s "reverse" > "$ROT_STATE_FILE"
|
||||
applyptrmatrix -1 0 1 0 -1 1 0 0 1
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh invert
|
||||
exit 0
|
||||
}
|
||||
|
||||
swayrotinvert() {
|
||||
swaymsg -- output "-" transform 180
|
||||
printf %s "reverse" > "$ROT_STATE_FILE"
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh invert
|
||||
exit 0
|
||||
}
|
||||
|
||||
riverrotinvert() {
|
||||
focused_output=$(river-bedload -print outputs | jq -r ".[] | select(.focused).name")
|
||||
wlr-randr --output "$focused_output" --transform 180
|
||||
printf %s "reverse" > "$ROT_STATE_FILE"
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh invert
|
||||
exit 0
|
||||
}
|
||||
|
||||
xorgrotnormal() {
|
||||
sxmo_keyboard.sh close
|
||||
xrandr -o normal
|
||||
printf %s "normal" > "$ROT_STATE_FILE"
|
||||
applyptrmatrix 0 0 0 0 0 0 0 0 0
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh normal
|
||||
exit 0
|
||||
}
|
||||
|
||||
swayrotnormal() {
|
||||
swaymsg -- output "-" transform 0
|
||||
printf %s "normal" > "$ROT_STATE_FILE"
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh normal
|
||||
exit 0
|
||||
}
|
||||
|
||||
riverrotnormal() {
|
||||
focused_output=$(river-bedload -print outputs | jq -r ".[] | select(.focused).name")
|
||||
wlr-randr --output "$focused_output" --transform normal
|
||||
printf %s "normal" > "$ROT_STATE_FILE"
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh normal
|
||||
exit 0
|
||||
}
|
||||
|
||||
xorgrotright() {
|
||||
sxmo_keyboard.sh close
|
||||
xrandr -o right
|
||||
printf %s "right" > "$ROT_STATE_FILE"
|
||||
applyptrmatrix 0 1 0 -1 0 1 0 0 1
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh right
|
||||
exit 0
|
||||
}
|
||||
|
||||
swayrotright() {
|
||||
swaymsg -- output "-" transform 90
|
||||
printf %s "right" > "$ROT_STATE_FILE"
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh right
|
||||
exit 0
|
||||
}
|
||||
|
||||
riverrotright() {
|
||||
focused_output=$(river-bedload -print outputs | jq -r ".[] | select(.focused).name")
|
||||
wlr-randr --output "$focused_output" --transform 270
|
||||
printf %s "right" > "$ROT_STATE_FILE"
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh right
|
||||
exit 0
|
||||
}
|
||||
|
||||
xorgrotleft() {
|
||||
sxmo_keyboard.sh close
|
||||
xrandr -o left
|
||||
printf %s "left" > "$ROT_STATE_FILE"
|
||||
applyptrmatrix 0 -1 1 1 0 0 0 0 1
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh left
|
||||
exit 0
|
||||
}
|
||||
|
||||
swayrotleft() {
|
||||
swaymsg -- output "-" transform 270
|
||||
printf %s "left" > "$ROT_STATE_FILE"
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh left
|
||||
exit 0
|
||||
}
|
||||
|
||||
riverrotleft() {
|
||||
focused_output=$(river-bedload -print outputs | jq -r ".[] | select(.focused).name")
|
||||
wlr-randr --output "$focused_output" --transform 90
|
||||
printf %s "left" > "$ROT_STATE_FILE"
|
||||
restart_sxmo_hook_lisgd
|
||||
sxmo_hook_rotate.sh left
|
||||
exit 0
|
||||
}
|
||||
|
||||
isrotated() {
|
||||
case "$SXMO_WM" in
|
||||
sway)
|
||||
"swayisrotated"
|
||||
;;
|
||||
river)
|
||||
"riverisrotated"
|
||||
;;
|
||||
dwm|i3)
|
||||
"xorgisrotated"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ -z "$1" ] || [ "rotate" = "$1" ]; then
|
||||
if [ $# -ne 0 ]; then
|
||||
shift
|
||||
fi
|
||||
if isrotated >/dev/null; then
|
||||
set -- rotnormal "$@"
|
||||
else
|
||||
set -- rot"${SXMO_ROTATE_DIRECTION:-right}" "$@"
|
||||
fi
|
||||
fi
|
||||
|
||||
case "$SXMO_WM" in
|
||||
sway)
|
||||
"sway$1" "$@"
|
||||
;;
|
||||
river)
|
||||
"river$1" "$@"
|
||||
;;
|
||||
dwm|i3)
|
||||
"xorg$1" "$@"
|
||||
;;
|
||||
esac
|
||||
Executable
+208
@@ -0,0 +1,208 @@
|
||||
#!/bin/sh
|
||||
|
||||
# include common definitions
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
SXMO_STATE="${SXMO_STATE:-$XDG_RUNTIME_DIR/sxmo.state}"
|
||||
if [ -n "$SXMO_HAS_PEANUTBUTTER" ] && command -v peanutbutter > /dev/null && [ -n "$WAYLAND_DISPLAY" ]; then
|
||||
SXMO_STATES="${SXMO_STATES:-unlock screenoff}"
|
||||
elif [ -z "$WAYLAND_DISPLAY" ] && command -v smlock > /dev/null; then
|
||||
SXMO_STATES="${SXMO_STATES:-unlock screenoff}"
|
||||
else
|
||||
SXMO_STATES="${SXMO_STATES:-unlock lock screenoff}"
|
||||
fi
|
||||
SXMO_SUSPENDABLE_STATES="${SXMO_SUSPENDABLE_STATES:-screenoff 3}"
|
||||
|
||||
transition_can_suspend() {
|
||||
# shellcheck disable=SC2086
|
||||
set -- $SXMO_SUSPENDABLE_STATES
|
||||
|
||||
tmpstate=
|
||||
timeout=
|
||||
while [ $# -gt 0 ]; do
|
||||
if [ "$1" = "$state" ]; then
|
||||
tmpstate="$1"
|
||||
timeout="$2"
|
||||
break
|
||||
fi
|
||||
shift 2
|
||||
done
|
||||
|
||||
stop_idle_suspender() {
|
||||
sxmo_jobs.sh stop idle_suspender
|
||||
sxmo_wakelock.sh lock sxmo_not_suspendable infinite
|
||||
}
|
||||
|
||||
if [ -z "$tmpstate" ]; then
|
||||
sxmo_log "this state is not suspendable"
|
||||
stop_idle_suspender
|
||||
return
|
||||
fi
|
||||
|
||||
case "$timeout" in
|
||||
''|*[!0-9]*)
|
||||
sxmo_log "there is no valid suspendable timeout for this state"
|
||||
stop_idle_suspender
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
sxmo_log "idle suspender started with timeout $timeout"
|
||||
sxmo_jobs.sh start idle_suspender sxmo_idle.sh -w \
|
||||
timeout "$timeout" 'sxmo_wakelock.sh unlock sxmo_not_suspendable' \
|
||||
resume 'sxmo_wakelock.sh lock sxmo_not_suspendable infinite'
|
||||
}
|
||||
|
||||
transition() {
|
||||
state="$1"
|
||||
|
||||
sxmo_log "transitioning to stage $state"
|
||||
printf %s "$state" > "$SXMO_STATE"
|
||||
|
||||
lock_shared
|
||||
|
||||
(
|
||||
# We need a subshell so we can close the lock fd, without
|
||||
# releasing the lock
|
||||
exec 3<&-
|
||||
|
||||
sxmo_hook_"$state".sh &
|
||||
sxmo_hook_statusbar.sh state_change &
|
||||
transition_can_suspend &
|
||||
|
||||
wait
|
||||
)
|
||||
}
|
||||
|
||||
click() {
|
||||
count="${1:-1}"
|
||||
# shellcheck disable=SC2086
|
||||
set -- $SXMO_STATES
|
||||
i=1
|
||||
while [ $i -le $# ]; do
|
||||
tmpstate=
|
||||
prevstate=
|
||||
eval "tmpstate=\$$i"
|
||||
if [ "$tmpstate" = "$state" ]; then
|
||||
if [ $i = 1 ]; then
|
||||
eval "prevstate=\$$#"
|
||||
else
|
||||
eval "prevstate=\$$((i-1))"
|
||||
fi
|
||||
state="$prevstate"
|
||||
break
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
if [ "$count" -gt 1 ]; then
|
||||
click $((count-1))
|
||||
else
|
||||
transition "$state"
|
||||
fi
|
||||
flushstored
|
||||
}
|
||||
|
||||
idle() {
|
||||
count="${1:-1}"
|
||||
# shellcheck disable=SC2086
|
||||
set -- $SXMO_STATES
|
||||
while [ $# -gt 1 ]; do
|
||||
if [ "$1" = "$state" ]; then
|
||||
if [ "$count" -ge "$#" ]; then
|
||||
count=$(($# - 1))
|
||||
fi
|
||||
shift "$count"
|
||||
transition "$1"
|
||||
return
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
sxmo_log "idle: not transitioning from $state"
|
||||
}
|
||||
|
||||
store() {
|
||||
storeid="$(tr -dc 'a-zA-Z0-9' < /dev/urandom 2>/dev/null | head -c 10)"
|
||||
printf %s "$state" > "$SXMO_STATE.stored.$storeid"
|
||||
printf %s "$storeid"
|
||||
}
|
||||
|
||||
flushstored() {
|
||||
rm -f "$SXMO_STATE.stored."* 2>/dev/null || true
|
||||
}
|
||||
|
||||
restore() {
|
||||
storeid="$1"
|
||||
if [ -f "$SXMO_STATE.stored.$storeid" ]; then
|
||||
read -r state < "$SXMO_STATE.stored.$storeid" 2>/dev/null || state=""
|
||||
transition "$state"
|
||||
flushstored
|
||||
fi
|
||||
}
|
||||
|
||||
read_state() {
|
||||
state=""
|
||||
if [ -r "$SXMO_STATE" ]; then
|
||||
read -r state < "$SXMO_STATE" 2>/dev/null || true
|
||||
fi
|
||||
}
|
||||
|
||||
action="$1"
|
||||
shift
|
||||
case "$action" in
|
||||
get)
|
||||
read_state
|
||||
printf %s "$state"
|
||||
exit 0
|
||||
;;
|
||||
is_locked)
|
||||
if [ -n "$SXMO_HAS_PEANUTBUTTER" ]; then
|
||||
pidof peanutbutter swaylock waylock i3lock > /dev/null && exit 0
|
||||
fi
|
||||
read_state
|
||||
if [ "$state" = "unlock" ]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
exec 3<> "$SXMO_STATE.lock"
|
||||
|
||||
lock_exclusive() {
|
||||
flock -x 3
|
||||
}
|
||||
|
||||
lock_shared() {
|
||||
flock -s 3
|
||||
}
|
||||
|
||||
case "$action" in
|
||||
click|idle)
|
||||
lock_exclusive
|
||||
read_state
|
||||
"$action" "$@" ;;
|
||||
set)
|
||||
lock_exclusive
|
||||
read_state
|
||||
case " $SXMO_STATES " in
|
||||
*" $1 "*)
|
||||
transition "$1"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
store)
|
||||
lock_exclusive
|
||||
read_state
|
||||
store
|
||||
;;
|
||||
restore)
|
||||
lock_exclusive
|
||||
restore "$1"
|
||||
;;
|
||||
flushstored)
|
||||
lock_exclusive
|
||||
flushstored
|
||||
;;
|
||||
esac
|
||||
Executable
+213
@@ -0,0 +1,213 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# A pretty generic status content generator
|
||||
# It aggregates all file content present in a folder
|
||||
# It sorts file elements numerically by zero-padded priority prefix
|
||||
# It watches file events to stdout new content
|
||||
|
||||
ROOT="${XDG_RUNTIME_DIR:-/run/user/10000}/sxmo_status/${SXMO_STATUS_NAME:-default}"
|
||||
mkdir -p "$ROOT"
|
||||
|
||||
lock_ex() {
|
||||
:
|
||||
}
|
||||
|
||||
lock_sh() {
|
||||
:
|
||||
}
|
||||
|
||||
free() {
|
||||
:
|
||||
}
|
||||
|
||||
usage() {
|
||||
printf "Usage: %s [ACTIONS]\n" "${0##*/}" >&2
|
||||
printf "ACTIONS:\n" >&2
|
||||
printf " -s: the status content (default action)\n" >&2
|
||||
printf " -w: file events and stdout status content\n" >&2
|
||||
printf " -a <id> <priority> <content>: add a bar component\n" >&2
|
||||
printf " -d <id>: remove a bar component\n" >&2
|
||||
printf " -r: remove all bar components\n" >&2
|
||||
printf " -D: the status content explained\n" >&2
|
||||
printf " -h: this message\n" >&2
|
||||
}
|
||||
|
||||
add() {
|
||||
id=
|
||||
priority=
|
||||
value=
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
arg="$1"
|
||||
shift
|
||||
|
||||
case "$arg" in
|
||||
"-f"|"-b"|"-t"|"-e"|"-o")
|
||||
[ "$#" -gt 0 ] && shift
|
||||
;;
|
||||
*)
|
||||
if [ -z "$id" ]; then
|
||||
id="$arg"
|
||||
elif [ -z "$priority" ]; then
|
||||
priority="$arg"
|
||||
elif [ -z "$value" ]; then
|
||||
value="$arg"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$id" ] || [ -z "$priority" ]; then
|
||||
printf "usage: %s -a <id> <priority> <value>\n" "${0##*/}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$ROOT"
|
||||
padded_prio="$(printf '%03d' "$priority" 2>/dev/null || printf '%s' "$priority")"
|
||||
target="$ROOT/$padded_prio-$id"
|
||||
|
||||
lock_ex
|
||||
|
||||
# Remove any old file for this id with a different priority prefix
|
||||
for f in "$ROOT"/*-"$id"; do
|
||||
[ -e "$f" ] || continue
|
||||
if [ "$f" != "$target" ]; then
|
||||
rm -f "$f"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$value" ]; then
|
||||
rm -f "$target"
|
||||
free
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -r "$target" ]; then
|
||||
old_val=""
|
||||
read -r old_val < "$target" 2>/dev/null || true
|
||||
if [ "$old_val" = "$value" ]; then
|
||||
free
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
printf "%s\n" "$value" > "${XDG_RUNTIME_DIR:-/run/user/10000}/sxmo_status/.tmp.$$"
|
||||
mv -f "${XDG_RUNTIME_DIR:-/run/user/10000}/sxmo_status/.tmp.$$" "$target"
|
||||
|
||||
free
|
||||
}
|
||||
|
||||
del() {
|
||||
id="$1"
|
||||
if [ -z "$id" ]; then
|
||||
printf "usage: %s -d <id>\n" "${0##*/}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
lock_ex
|
||||
for f in "$ROOT"/*-"$id"; do
|
||||
[ -e "$f" ] || continue
|
||||
rm -f "$f"
|
||||
done
|
||||
free
|
||||
}
|
||||
|
||||
show() {
|
||||
lock_sh
|
||||
out=""
|
||||
for f in "$ROOT"/*; do
|
||||
[ -f "$f" ] || continue
|
||||
val=""
|
||||
read -r val < "$f" 2>/dev/null || true
|
||||
[ -n "$val" ] || continue
|
||||
if [ -z "$out" ]; then
|
||||
out="$val"
|
||||
else
|
||||
out="$out $val"
|
||||
fi
|
||||
done
|
||||
printf "%s\n" "$out"
|
||||
free
|
||||
}
|
||||
|
||||
debug() {
|
||||
lock_sh
|
||||
for f in "$ROOT"/*; do
|
||||
[ -f "$f" ] || continue
|
||||
val=""
|
||||
read -r val < "$f" 2>/dev/null || true
|
||||
printf "%s\n>%s<\n" "${f##*/}" "$val"
|
||||
done
|
||||
free
|
||||
}
|
||||
|
||||
watch() {
|
||||
FIFO="$(mktemp -u)"
|
||||
mkfifo "$FIFO"
|
||||
NOTIFYPID=
|
||||
|
||||
# shellcheck disable=SC2317
|
||||
finish() {
|
||||
[ -n "$NOTIFYPID" ] && kill "$NOTIFYPID" 2>/dev/null || true
|
||||
rm -f "$FIFO"
|
||||
exit 0
|
||||
}
|
||||
trap 'finish' TERM INT
|
||||
|
||||
while true; do
|
||||
mkdir -p "$ROOT"
|
||||
inotifywait -mq -e "close_write,move,delete,delete_self,move_self" "$ROOT" >> "$FIFO" &
|
||||
NOTIFYPID=$!
|
||||
|
||||
show
|
||||
while read -r evline; do
|
||||
show
|
||||
case "$evline" in
|
||||
*DELETE_SELF*|*MOVE_SELF*)
|
||||
kill "$NOTIFYPID" 2>/dev/null || true
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done < "$FIFO"
|
||||
wait "$NOTIFYPID" 2>/dev/null || true
|
||||
sleep 0.1
|
||||
done
|
||||
}
|
||||
|
||||
reset() {
|
||||
lock_ex
|
||||
mkdir -p "$ROOT"
|
||||
rm -f "$ROOT"/*
|
||||
free
|
||||
}
|
||||
|
||||
action=""
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
"-o")
|
||||
shift 2 2>/dev/null || shift
|
||||
;;
|
||||
"-s"|"-w"|"-r"|"-a"|"-d"|"-D"|"-h")
|
||||
action="$1"
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
action="$1"
|
||||
shift
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$action" in
|
||||
""|"-s") show ;;
|
||||
"-w") watch "$@" ;;
|
||||
"-r") reset "$@" ;;
|
||||
"-a") add "$@" ;;
|
||||
"-d") del "$@" ;;
|
||||
"-D") debug "$@" ;;
|
||||
"-h") usage ;;
|
||||
esac
|
||||
@@ -1,96 +0,0 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# Run from sway.
|
||||
|
||||
# include common definitions
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
|
||||
monitor="${SXMO_MONITOR:-"$(swaymsg -t get_outputs | jq -r '.[0] | .name')"}"
|
||||
pwr="$SXMO_POWER_BUTTON"
|
||||
vols="$SXMO_VOLUME_BUTTON"
|
||||
|
||||
# Drop this when bonsai is available on 32 bits systems
|
||||
multikey_retrocompat() {
|
||||
sxmo_multikey.sh clear
|
||||
|
||||
if [ -n "$pwr" ]; then
|
||||
swaymsg -- input "$pwr" repeat_delay 200
|
||||
swaymsg -- input "$pwr" repeat_rate 15
|
||||
swaymsg -- bindsym --locked XF86PowerOff exec sxmo_multikey.sh \
|
||||
powerbutton \
|
||||
powerbutton_one \
|
||||
powerbutton_two \
|
||||
powerbutton_three
|
||||
else
|
||||
swaymsg -- bindsym --locked XF86PowerOff exec \
|
||||
sxmo_hook_inputhandler.sh powerbutton_one
|
||||
fi
|
||||
|
||||
if [ -n "$vols" ]; then
|
||||
for vol in $vols; do
|
||||
swaymsg -- input "$vol" repeat_delay 200
|
||||
swaymsg -- input "$vol" repeat_rate 15
|
||||
|
||||
swaymsg -- bindsym --locked --input-device="$vol" XF86AudioRaiseVolume exec \
|
||||
sxmo_multikey.sh \
|
||||
volup \
|
||||
volup_one \
|
||||
volup_two \
|
||||
volup_three
|
||||
|
||||
swaymsg -- bindsym --locked --input-device="$vol" XF86AudioLowerVolume exec \
|
||||
sxmo_multikey.sh \
|
||||
voldown \
|
||||
voldown_one \
|
||||
voldown_two \
|
||||
voldown_three
|
||||
done
|
||||
else
|
||||
swaymsg -- bindsym --locked XF86AudioRaiseVolume exec \
|
||||
sxmo_hook_inputhandler.sh volup_one
|
||||
swaymsg -- bindsym --locked XF86AudioLowerVolume exec \
|
||||
sxmo_hook_inputhandler.sh voldown_one
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -n "$SXMO_MODEM_GPIO_KEY_RI" ]; then
|
||||
# Disable the gpio-key-ri input devive
|
||||
# It will trigger idle wakeup on modem notification which break sxmo
|
||||
swaymsg -- input "$SXMO_MODEM_GPIO_KEY_RI" events disabled
|
||||
fi
|
||||
|
||||
if [ -n "$SXMO_SWAY_SCALE" ]; then
|
||||
swaymsg -- output "$monitor" scale "$SXMO_SWAY_SCALE"
|
||||
fi
|
||||
|
||||
swaymsg -- layout splitv >/dev/null 2>&1 || true
|
||||
swaymsg -- splitv >/dev/null 2>&1 || true
|
||||
|
||||
focused_name="$(
|
||||
swaymsg -t get_outputs | jq -r '.[] | select(.focused == true) | .name'
|
||||
)"
|
||||
swaymsg -- input type:touch map_to_output "$focused_name"
|
||||
swaymsg -- input type:tablet_tool map_to_output "$focused_name"
|
||||
|
||||
if [ -n "$SXMO_DISABLE_KEYBINDS" ]; then
|
||||
swaymsg -- bindsym --locked XF86PowerOff exec \
|
||||
sxmo_hook_inputhandler.sh powerbutton_one
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v bonsaictl > /dev/null; then
|
||||
multikey_retrocompat
|
||||
exit
|
||||
fi
|
||||
|
||||
swaymsg -- bindsym --locked --no-repeat XF86PowerOff exec bonsaictl -e power_pressed
|
||||
swaymsg -- bindsym --locked --release XF86PowerOff exec bonsaictl -e power_released
|
||||
|
||||
swaymsg -- bindsym --locked --no-repeat XF86AudioRaiseVolume exec bonsaictl -e volup_pressed
|
||||
swaymsg -- bindsym --locked --release XF86AudioRaiseVolume exec bonsaictl -e volup_released
|
||||
|
||||
swaymsg -- bindsym --locked --no-repeat XF86AudioLowerVolume exec bonsaictl -e voldown_pressed
|
||||
swaymsg -- bindsym --locked --release XF86AudioLowerVolume exec bonsaictl -e voldown_released
|
||||
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
# shellcheck disable=SC2086
|
||||
|
||||
SXMO_TERMINAL="${SXMO_TERMINAL:-st}"
|
||||
|
||||
if [ -z "$*" ]; then
|
||||
set -- ${SHELL:-/bin/sh}
|
||||
fi
|
||||
|
||||
if [ -z "$TERMNAME" ]; then
|
||||
TERMNAME="$*"
|
||||
fi
|
||||
|
||||
case "$SXMO_TERMINAL" in
|
||||
"st"*)
|
||||
set -- $SXMO_TERMINAL -T "$TERMNAME" -e "$@"
|
||||
;;
|
||||
*)
|
||||
set -- st -T "$TERMNAME" -e "$@"
|
||||
;;
|
||||
esac
|
||||
|
||||
exec 4<&0
|
||||
exec 5>&1
|
||||
exec 6>&2
|
||||
|
||||
exec "$@"
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
# shellcheck disable=SC2317 disable=SC2329
|
||||
# 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
|
||||
|
||||
@@ -20,12 +18,40 @@ swi3msg() {
|
||||
xorgdisplay() {
|
||||
case "$1" in
|
||||
off)
|
||||
if [ -r /sys/class/backlight/backlight/brightness ]; then
|
||||
read -r _cur_bl < /sys/class/backlight/backlight/brightness 2>/dev/null || _cur_bl=0
|
||||
if [ "${_cur_bl:-0}" -gt 1 ] 2>/dev/null; then
|
||||
printf '%s' "$_cur_bl" > /tmp/sxmo_saved_brightness 2>/dev/null || true
|
||||
fi
|
||||
fi
|
||||
if [ -w /sys/class/leds/white:kbd_backlight/brightness ]; then
|
||||
printf '0' > /sys/class/leds/white:kbd_backlight/brightness 2>/dev/null || true
|
||||
fi
|
||||
if [ -w /sys/class/backlight/backlight/brightness ]; then
|
||||
printf '0' > /sys/class/backlight/backlight/brightness 2>/dev/null || true
|
||||
fi
|
||||
xset dpms 0 0 3
|
||||
xset dpms force off
|
||||
;;
|
||||
on)
|
||||
xset dpms 0 0 0
|
||||
xset dpms force on
|
||||
if [ -w /sys/class/backlight/backlight/bl_power ]; then
|
||||
printf '0' > /sys/class/backlight/backlight/bl_power 2>/dev/null || true
|
||||
fi
|
||||
if [ -w /sys/class/backlight/backlight/brightness ]; then
|
||||
_restore_bl=""
|
||||
if [ -r /tmp/sxmo_saved_brightness ]; then
|
||||
read -r _restore_bl < /tmp/sxmo_saved_brightness 2>/dev/null || _restore_bl=""
|
||||
fi
|
||||
if [ -z "$_restore_bl" ] || [ "${_restore_bl:-0}" -le 1 ] 2>/dev/null; then
|
||||
read -r _restore_bl < /sys/class/backlight/backlight/max_brightness 2>/dev/null || _restore_bl=14
|
||||
fi
|
||||
printf '%s' "${_restore_bl:-14}" > /sys/class/backlight/backlight/brightness 2>/dev/null || true
|
||||
fi
|
||||
if [ -w /sys/class/leds/white:kbd_backlight/brightness ]; then
|
||||
printf '255' > /sys/class/leds/white:kbd_backlight/brightness 2>/dev/null || true
|
||||
fi
|
||||
;;
|
||||
"")
|
||||
if xset q | grep -q "Off: 3"; then
|
||||
@@ -168,14 +194,14 @@ _swi3_focusedwindow() {
|
||||
recurse(.nodes[]) |
|
||||
select(.focused == true) |
|
||||
{
|
||||
app_id: (if .app_id != null then
|
||||
app_id: ((if .app_id != null then
|
||||
.app_id
|
||||
else
|
||||
.window_properties.class
|
||||
end) | gsub("\n"; "\\n") | ascii_downcase,
|
||||
name: (.name | gsub("\n"; "\\n") | ascii_downcase),
|
||||
end) // "" | tostring | gsub("\n"; "\\n") | ascii_downcase),
|
||||
name: ((.name // "") | tostring | gsub("\n"; "\\n") | ascii_downcase),
|
||||
} |
|
||||
select(.app_id != null and .name != null) |
|
||||
select(.app_id != "" or .name != "") |
|
||||
"\(.app_id)\n\(.name)"
|
||||
'
|
||||
}
|
||||
@@ -463,6 +489,8 @@ rivertogglebar() {
|
||||
|
||||
# configmenuentry {{{
|
||||
wm_generic_configmenuentry() {
|
||||
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
|
||||
. sxmo_hook_icons.sh
|
||||
case "$SXMO_WM" in
|
||||
dwm)
|
||||
printf "%s\n" "$icon_cfg Edit configuration ^ 0 ^ sxmo_terminal.sh $EDITOR $XDG_CONFIG_HOME/sxmo/xinit"
|
||||
|
||||
@@ -2,428 +2,50 @@
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Copyright 2022 Sxmo Contributors
|
||||
|
||||
# this script is a menu which lets the user perform some WM actions.
|
||||
|
||||
# include common definitions
|
||||
# shellcheck source=scripts/core/sxmo_common.sh
|
||||
. sxmo_common.sh
|
||||
# shellcheck source=configs/default_hooks/sxmo_hook_icons.sh
|
||||
. sxmo_hook_icons.sh
|
||||
|
||||
set -e
|
||||
|
||||
_movetowssubmenu() {
|
||||
for ws in $(seq "${SXMO_WORKSPACE_WRAPPING:-4}"); do
|
||||
printf "%s Move to WS %s\n" "$ws" "$ws"
|
||||
done
|
||||
for ws in $(seq "${SXMO_WORKSPACE_WRAPPING:-4}"); do
|
||||
printf "%s Move to WS %s\n" "$ws" "$ws"
|
||||
done
|
||||
}
|
||||
|
||||
# A menu which allows to move windows or toggle floating.
|
||||
swaymovemenu() {
|
||||
CHOICES="$(cat <<EOF
|
||||
$icon_cls Close Menu
|
||||
$icon_aru Move Up
|
||||
$icon_ard Move Down
|
||||
$icon_arl Move Left
|
||||
$icon_arr Move Right
|
||||
$icon_wn2 Toggle Floating
|
||||
$icon_ac1 Move Scratchpad
|
||||
$(_movetowssubmenu)
|
||||
EOF
|
||||
)"
|
||||
|
||||
MOVEINDEX=0
|
||||
while : ; do
|
||||
# Remove current workspace from the list
|
||||
CHOICES="$(
|
||||
printf "%s" "$CHOICES" |
|
||||
grep -v "$(
|
||||
swaymsg -t get_workspaces |
|
||||
jq -r '
|
||||
.[] | select(.focused).name
|
||||
')"
|
||||
)"
|
||||
|
||||
PICKED="$(printf "%s" "$CHOICES" | dmenu -I "$MOVEINDEX" -p "Move menu")"
|
||||
MOVEINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
?" Move to WS "?)
|
||||
sxmo_wm.sh moveworkspace "${PICKED%" Move to WS "?}"
|
||||
return
|
||||
;;
|
||||
"$icon_wn2 Toggle Floating")
|
||||
swaymsg floating toggle
|
||||
;;
|
||||
*)
|
||||
printf "%s" "$PICKED" | tr -cd '\000-\177' | xargs swaymsg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# The generic sway menu
|
||||
swaywmmenu() {
|
||||
WMINDEX=0
|
||||
|
||||
while : ; do
|
||||
# generate layout line with format "current → next → 2nd next"
|
||||
CURRENT_LAYOUT="$(
|
||||
swaymsg -t get_tree |
|
||||
jq -r 'recurse(.nodes[]) |
|
||||
if select(.nodes[].focused).layout=="output" then
|
||||
select(.nodes[].focused).nodes[].layout
|
||||
else select(.nodes[].focused).layout end'
|
||||
)"
|
||||
if [ -n "$CURRENT_LAYOUT" ]; then
|
||||
if [ "$CURRENT_LAYOUT" = "splitv" ]; then
|
||||
LAYOUT_LINE="splitv $icon_arr splith $icon_arr tabbed"
|
||||
elif [ "$CURRENT_LAYOUT" = "splith" ]; then
|
||||
LAYOUT_LINE="splith $icon_arr tabbed $icon_arr splitv"
|
||||
else
|
||||
LAYOUT_LINE="tabbed $icon_arr splitv $icon_arr splith"
|
||||
fi
|
||||
fi
|
||||
CHOICES="$(grep . <<EOF
|
||||
$icon_cls Close Menu
|
||||
$icon_win Next window
|
||||
$icon_mov Move menu
|
||||
$icon_rld Switch menu
|
||||
$([ -n "$CURRENT_LAYOUT" ] && printf "%s" "$icon_rld $LAYOUT_LINE")
|
||||
$icon_mnu Split vertical
|
||||
$icon_grd Split horizontal
|
||||
$icon_tab Tabbed layout
|
||||
$icon_exp Focus parent
|
||||
$icon_trh Kill window
|
||||
EOF
|
||||
)"
|
||||
PICKED="$(printf "%s" "$CHOICES" | grep . | dmenu -I "$WMINDEX" -p "WM Menu")"
|
||||
WMINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
"$icon_win Next window")
|
||||
swaymsg focus next
|
||||
return
|
||||
;;
|
||||
"$icon_mov Move menu")
|
||||
swaymovemenu
|
||||
;;
|
||||
"$icon_rld Switch menu")
|
||||
swaywindowswitcher
|
||||
;;
|
||||
"$icon_rld $LAYOUT_LINE")
|
||||
sxmo_wm.sh togglelayout
|
||||
;;
|
||||
"$icon_mnu Split vertical")
|
||||
swaymsg layout splitv
|
||||
swaymsg splitv
|
||||
return
|
||||
;;
|
||||
"$icon_grd Split horizontal")
|
||||
swaymsg layout splith
|
||||
swaymsg splith
|
||||
return
|
||||
;;
|
||||
"$icon_tab Tabbed layout")
|
||||
swaymsg layout tabbed
|
||||
return
|
||||
;;
|
||||
"$icon_exp Focus parent")
|
||||
swaymsg focus parent
|
||||
;;
|
||||
"$icon_trh Kill window")
|
||||
sxmo_killwindow.sh
|
||||
;;
|
||||
*)
|
||||
printf "%s" "$PICKED" | tr -cd '\000-\177' | xargs swaymsg
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# The generic river menu
|
||||
riverwmmenu() {
|
||||
WMINDEX=0
|
||||
|
||||
while : ; do
|
||||
# For now justs swap between fullscreen and tiled.
|
||||
LAYOUT_LINE="tiled $icon_arr fullscreen"
|
||||
CHOICES="$(grep . <<EOF
|
||||
$icon_cls Close Menu
|
||||
$icon_mov Move menu
|
||||
$icon_rld Switch menu
|
||||
$(printf "%s" "$icon_rld $LAYOUT_LINE")
|
||||
$icon_trh Kill window
|
||||
EOF
|
||||
)"
|
||||
PICKED="$(printf "%s" "$CHOICES" | grep . | dmenu -I "$WMINDEX" -p "WM Menu")"
|
||||
WMINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
"$icon_mov Move menu")
|
||||
rivermovemenu
|
||||
;;
|
||||
"$icon_rld Switch menu")
|
||||
riverwindowswitcher
|
||||
;;
|
||||
"$icon_rld $LAYOUT_LINE")
|
||||
sxmo_wm.sh togglelayout
|
||||
;;
|
||||
"$icon_trh Kill window")
|
||||
sxmo_killwindow.sh
|
||||
;;
|
||||
*)
|
||||
printf "%s" "$PICKED" | tr -cd '\000-\177' | xargs swaymsg
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
_rivermovetowssubmenu() {
|
||||
for ws in $(seq "${SXMO_WORKSPACE_WRAPPING:-9}"); do
|
||||
printf "%s Move to WS %s\n" "$ws" "$ws"
|
||||
done
|
||||
}
|
||||
|
||||
# A menu which allows to move windows or toggle floating.
|
||||
rivermovemenu() {
|
||||
CHOICES="$(cat <<EOF
|
||||
$icon_cls Close Menu
|
||||
$icon_wn2 Toggle Floating
|
||||
$(_rivermovetowssubmenu)
|
||||
EOF
|
||||
)"
|
||||
|
||||
MOVEINDEX=0
|
||||
while : ; do
|
||||
# Remove current workspace from the list
|
||||
CHOICES="$(
|
||||
printf "%s" "$CHOICES" |
|
||||
grep -v "$(
|
||||
river-bedload -print focused |
|
||||
jq -r ' .[] | .focused_id')"
|
||||
)"
|
||||
|
||||
PICKED="$(printf "%s" "$CHOICES" | dmenu -I "$MOVEINDEX" -p "Move menu")"
|
||||
MOVEINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
?" Move to WS "?)
|
||||
sxmo_wm.sh moveworkspace "${PICKED%" Move to WS "?}"
|
||||
return
|
||||
;;
|
||||
"$icon_wn2 Toggle Floating")
|
||||
riverctl toggle-float
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
riverwindowswitcher() {
|
||||
SWITCHINDEX=0
|
||||
|
||||
while : ; do
|
||||
# There is currently no easy in river to get the tag of a given window,
|
||||
# skip the window part of this menu for now.
|
||||
|
||||
# Get the container ID from the node tree
|
||||
CHOICES="$(
|
||||
cat <<EOF
|
||||
$icon_cls Close Menu
|
||||
$icon_arl Previous Workspace
|
||||
$icon_arr Next Workspace
|
||||
$(_rivermovetowssubmenu | grep -v "$(
|
||||
river-bedload -print focused |
|
||||
jq -r ' .[] | .focused_id')")
|
||||
EOF
|
||||
)"
|
||||
|
||||
PICKED="$(printf "%s" "$CHOICES" | dmenu -p "Switch menu" -I "$SWITCHINDEX")"
|
||||
SWITCHINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
"$icon_arr Next Workspace")
|
||||
sxmo_wm.sh nextworkspace
|
||||
;;
|
||||
"$icon_arl Previous Workspace")
|
||||
sxmo_wm.sh previousworkspace
|
||||
;;
|
||||
?" Move to WS "?)
|
||||
sxmo_wm.sh workspace "${PICKED%" Move to WS "?}"
|
||||
return
|
||||
;;
|
||||
## When we'll have proper window switching:
|
||||
# *)
|
||||
# # Requires the actual `id` to be at the end and between parentheses
|
||||
# CON_ID=${PICKED##*(}
|
||||
# CON_ID=${CON_ID%)}
|
||||
# swaymsg "[con_id=$CON_ID]" focus
|
||||
# ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
|
||||
dwmwmmenu() {
|
||||
WMINDEX=0
|
||||
WMINDEX=0
|
||||
|
||||
while : ; do
|
||||
CHOICES="$(
|
||||
cat <<EOF
|
||||
while : ; do
|
||||
CHOICES="$(
|
||||
cat <<EOF
|
||||
$icon_cls Close Menu
|
||||
$(_movetowssubmenu)
|
||||
$icon_rld Shift stack
|
||||
$icon_grd Toggle Layout
|
||||
$icon_trh Kill window
|
||||
EOF
|
||||
)"
|
||||
PICKED="$(printf "%s" "$CHOICES" | dmenu -I "$WMINDEX" -p "WM Menu")"
|
||||
WMINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
?" Move to WS "?)
|
||||
sxmo_wm.sh moveworkspace "${PICKED%" Move to WS "?}"
|
||||
;;
|
||||
"$icon_rld Shift stack")
|
||||
sxmo_wm.sh switchfocus
|
||||
;;
|
||||
"$icon_grd Toggle Layout")
|
||||
sxmo_wm.sh togglelayout
|
||||
;;
|
||||
"$icon_trh Kill window")
|
||||
sxmo_killwindow.sh
|
||||
;;
|
||||
esac
|
||||
done
|
||||
)"
|
||||
PICKED="$(printf "%s" "$CHOICES" | dmenu -I "$WMINDEX" -p "WM Menu")"
|
||||
WMINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
?" Move to WS "?)
|
||||
sxmo_wm.sh moveworkspace "${PICKED%" Move to WS "?}"
|
||||
;;
|
||||
"$icon_rld Shift stack")
|
||||
sxmo_wm.sh switchfocus
|
||||
;;
|
||||
"$icon_grd Toggle Layout")
|
||||
sxmo_wm.sh togglelayout
|
||||
;;
|
||||
"$icon_trh Kill window")
|
||||
sxmo_killwindow.sh
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
i3windowswitcher() {
|
||||
SWITCHINDEX=0
|
||||
|
||||
while : ; do
|
||||
FORMAT='"W:" + .workspace + " | " + .app_id + " - " + .name + " (" + .id + ")"'
|
||||
|
||||
WINDOWSLIST="$(
|
||||
i3-msg -t get_tree |
|
||||
jq -r ".nodes[]
|
||||
| {output: .name, content: .nodes[]}
|
||||
| {output: .output, workspace: .content.name, apps: .content
|
||||
| ..
|
||||
| {id: .id?|tostring, name: .name?, app_id: .app_id?, shell: .shell?}
|
||||
| select(.app_id != null or .shell != null)}
|
||||
| {output: .output, workspace: .workspace,
|
||||
id: .apps.id, app_id: .apps.app_id, name: .apps.name }
|
||||
| $FORMAT
|
||||
| tostring
|
||||
"
|
||||
)"
|
||||
|
||||
# Get the container ID from the node tree
|
||||
CHOICES="$(
|
||||
cat <<EOF
|
||||
$icon_cls Close Menu
|
||||
$icon_arl Previous Workspace
|
||||
$icon_arr Next Workspace
|
||||
$WINDOWSLIST
|
||||
EOF
|
||||
)"
|
||||
|
||||
PICKED="$(printf "%s" "$CHOICES" | dmenu -p "Switch menu" -I "$SWITCHINDEX")"
|
||||
SWITCHINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
"$icon_arr Next Workspace")
|
||||
sxmo_wm.sh nextworkspace
|
||||
;;
|
||||
"$icon_arl Previous Workspace")
|
||||
sxmo_wm.sh previousworkspace
|
||||
;;
|
||||
*)
|
||||
# Requires the actual `id` to be at the end and between parentheses
|
||||
CON_ID=${PICKED##*(}
|
||||
CON_ID=${CON_ID%)}
|
||||
i3-msg "[con_id=$CON_ID]" focus
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
swaywindowswitcher() {
|
||||
SWITCHINDEX=0
|
||||
|
||||
while : ; do
|
||||
FORMAT='"W:" + .workspace + " | " + .app_id + " - " + .name + " (" + .id + ")"'
|
||||
|
||||
WINDOWSLIST="$(
|
||||
swaymsg -t get_tree |
|
||||
jq -r ".nodes[]
|
||||
| {output: .name, content: .nodes[]}
|
||||
| {output: .output, workspace: .content.name, apps: .content
|
||||
| ..
|
||||
| {id: .id?|tostring, name: .name?, app_id: .app_id?, shell: .shell?}
|
||||
| select(.app_id != null or .shell != null)}
|
||||
| {output: .output, workspace: .workspace,
|
||||
id: .apps.id, app_id: .apps.app_id, name: .apps.name }
|
||||
| $FORMAT
|
||||
| tostring
|
||||
"
|
||||
)"
|
||||
|
||||
# Get the container ID from the node tree
|
||||
CHOICES="$(
|
||||
cat <<EOF
|
||||
$icon_cls Close Menu
|
||||
$icon_arl Previous Workspace
|
||||
$icon_arr Next Workspace
|
||||
$WINDOWSLIST
|
||||
EOF
|
||||
)"
|
||||
|
||||
PICKED="$(printf "%s" "$CHOICES" | dmenu -p "Switch menu" -I "$SWITCHINDEX")"
|
||||
SWITCHINDEX="$(($(printf "%s" "$CHOICES" | grep -nm1 "^$PICKED$" | cut -d: -f1) -1))"
|
||||
|
||||
case "$PICKED" in
|
||||
""|"$icon_cls Close Menu")
|
||||
return
|
||||
;;
|
||||
"$icon_arr Next Workspace")
|
||||
sxmo_wm.sh nextworkspace
|
||||
;;
|
||||
"$icon_arl Previous Workspace")
|
||||
sxmo_wm.sh previousworkspace
|
||||
;;
|
||||
*)
|
||||
# Requires the actual `id` to be at the end and between parentheses
|
||||
CON_ID=${PICKED##*(}
|
||||
CON_ID=${CON_ID%)}
|
||||
swaymsg "[con_id=$CON_ID]" focus
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
"$SXMO_WM$1"
|
||||
exit
|
||||
fi
|
||||
case "$SXMO_WM" in
|
||||
dwm|i3) dwmwmmenu ;;
|
||||
sway) swaywmmenu ;;
|
||||
river) riverwmmenu ;;
|
||||
esac
|
||||
dwmwmmenu
|
||||
|
||||
Executable
+135
@@ -0,0 +1,135 @@
|
||||
#!/bin/sh
|
||||
# Copyright 2020 Oliver Smith
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
setup_log() {
|
||||
logfile=${XDG_STATE_HOME:-~/.local/state}/tinydm.log
|
||||
mkdir -p "$(dirname "$logfile")"
|
||||
if [ -f "$logfile" ]; then
|
||||
# keep previous log file around
|
||||
mv "$logfile" "$logfile".old
|
||||
fi
|
||||
|
||||
exec >"$logfile" 2>&1
|
||||
}
|
||||
|
||||
source_profile() {
|
||||
for profile in /etc/profile "$HOME"/.profile; do
|
||||
if [ -f "$profile" ]; then
|
||||
# shellcheck disable=SC1090
|
||||
. "$profile"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# $1: session type (i.e. 'wayland', or 'x11')
|
||||
source_session_profiles() {
|
||||
session_type="$1"
|
||||
if [ "$session_type" != "wayland" ] && [ "$session_type" != "x11" ]; then
|
||||
echo "Unknown session type: $session_type"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for file in "/usr/share/tinydm/env-${session_type}.d/"*; do
|
||||
if ! [ -e "$file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "tinydm: sourcing file: $file"
|
||||
# shellcheck disable=SC1090
|
||||
. "$file"
|
||||
done
|
||||
|
||||
# Source /etc dirs after /usr/share to override options properly
|
||||
for file in "/etc/tinydm.d/env-${session_type}.d/"*; do
|
||||
if ! [ -e "$file" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "tinydm: sourcing file: $file"
|
||||
# shellcheck disable=SC1090
|
||||
. "$file"
|
||||
done
|
||||
}
|
||||
|
||||
# $1: file
|
||||
# $2: key
|
||||
parse_xdg_desktop() {
|
||||
grep "^$2=" "$1" | cut -d "=" -f 2- | tr ';' ':' | sed 's/:$//'
|
||||
}
|
||||
|
||||
# $1: Exec line from .desktop file
|
||||
run_session_wayland() {
|
||||
export XDG_SESSION_TYPE=wayland
|
||||
exec setpriv --ambient-caps '-all' "$@"
|
||||
}
|
||||
|
||||
# $1: Exec line from .desktop file
|
||||
run_session_x() {
|
||||
export XDG_SESSION_TYPE=X11
|
||||
|
||||
cmd_startx="startx $(command -v "$1")"
|
||||
|
||||
shift
|
||||
for arg in "$@"; do
|
||||
cmd_startx="$cmd_startx $arg"
|
||||
done
|
||||
|
||||
cmd_startx="$cmd_startx -- -nocursor -nolisten tcp vt1 -keeptty"
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
exec setpriv --ambient-caps '-all' $cmd_startx
|
||||
}
|
||||
|
||||
run_session() {
|
||||
target="/var/lib/tinydm/default-session.desktop"
|
||||
|
||||
if ! [ -e "$target" ]; then
|
||||
echo "ERROR: no session configured!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
resolved="$(realpath "$target")"
|
||||
desktop="$(basename "$resolved" | sed 's/\.desktop$//')"
|
||||
export XDG_SESSION_DESKTOP="$desktop"
|
||||
cmd="$(parse_xdg_desktop "$resolved" "Exec")"
|
||||
|
||||
desktop_names="$(parse_xdg_desktop "$resolved" "DesktopNames")"
|
||||
if [ -n "$desktop_names" ]; then
|
||||
export XDG_CURRENT_DESKTOP="$desktop_names"
|
||||
fi
|
||||
|
||||
if [ -z "$DBUS_SESSION_BUS_ADDRESS" ] &&
|
||||
[ "$TINYDM_START_DBUS_SESSION" = "true" ] &&
|
||||
[ "$(command -v dbus-launch)" ]; then
|
||||
cmd="$(command -v dbus-launch) --exit-with-x11 $cmd"
|
||||
fi
|
||||
|
||||
echo "--- tinydm ---"
|
||||
echo "Date: $(date)"
|
||||
echo "Session: $resolved"
|
||||
echo "Desktop: $desktop"
|
||||
echo "Exec: $cmd"
|
||||
echo "---"
|
||||
|
||||
case "$resolved" in
|
||||
/usr/share/wayland-sessions*)
|
||||
source_session_profiles wayland
|
||||
# shellcheck disable=SC2086
|
||||
run_session_wayland $cmd
|
||||
;;
|
||||
/usr/share/xsessions*)
|
||||
source_session_profiles x11
|
||||
# shellcheck disable=SC2086
|
||||
run_session_x $cmd
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: could not detect session type!"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
setup_log
|
||||
source_profile
|
||||
run_session
|
||||
Reference in New Issue
Block a user