#!/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