180 lines
5.1 KiB
Bash
Executable File
180 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# enne2-caffeine — backend del widget Caffeine per KDE Plasma 6
|
|
#
|
|
# Blocca lo spegnimento/blocco dello schermo e la sospensione automatica usando
|
|
# systemd-inhibit (logind). PowerDevil/PolicyAgent onora le inibizioni logind:
|
|
# what=sleep -> InterruptSession (niente sospensione automatica)
|
|
# what=idle -> ChangeScreenSettings (niente dim/spegnimento schermo, niente blocco)
|
|
# L'inibizione vive in unità systemd utente, quindi sopravvive al riavvio di
|
|
# plasmashell e si rilascia da sola alla fine della sessione.
|
|
#
|
|
# Uso:
|
|
# caffeine.sh status
|
|
# caffeine.sh on <screen|sleep> [minuti]
|
|
# caffeine.sh switch <screen|sleep> # cambia modalità mantenendo il timer
|
|
# caffeine.sh off [notify]
|
|
# caffeine.sh toggle <screen|sleep> [minuti]
|
|
# caffeine.sh ensure-units <cartella-con-i-.service>
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
|
|
set -uo pipefail
|
|
|
|
UNIT_SCREEN="enne2-caffeine-screen.service"
|
|
UNIT_SLEEP="enne2-caffeine-sleep.service"
|
|
STATE_DIR="${XDG_STATE_HOME:-$HOME/.local/state}/enne2-caffeine"
|
|
DEADLINE_FILE="$STATE_DIR/deadline"
|
|
USER_UNIT_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user"
|
|
|
|
SYSTEMCTL="$(command -v systemctl 2>/dev/null || true)"
|
|
|
|
fail() {
|
|
echo "error=$1"
|
|
exit 1
|
|
}
|
|
|
|
# systemd utente disponibile e interrogabile?
|
|
systemd_ok() {
|
|
[ -n "$SYSTEMCTL" ] || return 1
|
|
case "$("$SYSTEMCTL" --user is-active "$UNIT_SCREEN" 2>/dev/null)" in
|
|
active|inactive|failed|activating|deactivating|unknown) return 0 ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
|
|
unit_state() {
|
|
"$SYSTEMCTL" --user is-active "$1" 2>/dev/null
|
|
}
|
|
|
|
active_unit() {
|
|
if [ "$(unit_state "$UNIT_SCREEN")" = "active" ]; then
|
|
printf '%s\n' "$UNIT_SCREEN"
|
|
elif [ "$(unit_state "$UNIT_SLEEP")" = "active" ]; then
|
|
printf '%s\n' "$UNIT_SLEEP"
|
|
fi
|
|
}
|
|
|
|
only_digits() {
|
|
case "${1:-}" in
|
|
''|*[!0-9]*) printf '0\n' ;;
|
|
*) printf '%s\n' "$1" ;;
|
|
esac
|
|
}
|
|
|
|
cmd_ensure_units() {
|
|
local src="${1:-}"
|
|
[ -n "$src" ] && [ -d "$src" ] || fail "unit-source-missing"
|
|
systemd_ok || fail "systemd-user-unavailable"
|
|
mkdir -p "$USER_UNIT_DIR" || fail "cannot-create-unit-dir"
|
|
local changed=0 f target
|
|
for f in "$src"/*.service; do
|
|
[ -e "$f" ] || continue
|
|
target="$USER_UNIT_DIR/$(basename "$f")"
|
|
if ! cmp -s "$f" "$target"; then
|
|
cp -f "$f" "$target" || fail "cannot-copy-unit"
|
|
changed=1
|
|
fi
|
|
done
|
|
if [ "$changed" = 1 ]; then
|
|
"$SYSTEMCTL" --user daemon-reload >/dev/null 2>&1
|
|
fi
|
|
echo "ok=1"
|
|
}
|
|
|
|
cmd_status() {
|
|
mkdir -p "$STATE_DIR" 2>/dev/null
|
|
if ! systemd_ok; then
|
|
echo "backend=unsupported"
|
|
echo "state=off"
|
|
echo "mode=none"
|
|
return 0
|
|
fi
|
|
echo "backend=systemd"
|
|
|
|
local unit
|
|
unit="$(active_unit)"
|
|
case "$unit" in
|
|
"$UNIT_SCREEN") echo "state=on"; echo "mode=screen" ;;
|
|
"$UNIT_SLEEP") echo "state=on"; echo "mode=sleep" ;;
|
|
*) echo "state=off"; echo "mode=none" ;;
|
|
esac
|
|
|
|
if [ -n "$unit" ] && [ -f "$DEADLINE_FILE" ]; then
|
|
local d
|
|
d="$(only_digits "$(cat "$DEADLINE_FILE" 2>/dev/null)")"
|
|
if [ "$d" -gt 0 ]; then
|
|
echo "deadline=$d"
|
|
else
|
|
rm -f "$DEADLINE_FILE"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
apply_mode() {
|
|
systemd_ok || fail "systemd-user-unavailable"
|
|
"$SYSTEMCTL" --user stop "$UNIT_SCREEN" "$UNIT_SLEEP" >/dev/null 2>&1
|
|
if [ "${1:-screen}" = "sleep" ]; then
|
|
"$SYSTEMCTL" --user start "$UNIT_SLEEP" >/dev/null 2>&1 || fail "start-failed"
|
|
else
|
|
"$SYSTEMCTL" --user start "$UNIT_SCREEN" >/dev/null 2>&1 || fail "start-failed"
|
|
fi
|
|
}
|
|
|
|
cmd_on() {
|
|
local mode="${1:-screen}"
|
|
local minutes
|
|
minutes="$(only_digits "${2:-0}")"
|
|
mkdir -p "$STATE_DIR" 2>/dev/null
|
|
apply_mode "$mode" || return 1
|
|
if [ "$minutes" -gt 0 ]; then
|
|
echo "$(( $(date +%s) + minutes * 60 ))" > "$DEADLINE_FILE"
|
|
else
|
|
rm -f "$DEADLINE_FILE"
|
|
fi
|
|
echo "ok=1"
|
|
cmd_status
|
|
}
|
|
|
|
cmd_switch() {
|
|
apply_mode "${1:-screen}" || return 1
|
|
echo "ok=1"
|
|
cmd_status
|
|
}
|
|
|
|
cmd_off() {
|
|
local notify="${1:-}"
|
|
if systemd_ok; then
|
|
"$SYSTEMCTL" --user stop "$UNIT_SCREEN" "$UNIT_SLEEP" >/dev/null 2>&1
|
|
fi
|
|
rm -f "$DEADLINE_FILE"
|
|
if [ "$notify" = "notify" ] && command -v notify-send >/dev/null 2>&1; then
|
|
notify-send -a "Caffeine" -i preferences-system-power-management \
|
|
"Caffeine disattivato" \
|
|
"Il timer è scaduto: schermo e sospensione tornano alla gestione automatica." || true
|
|
fi
|
|
echo "ok=1"
|
|
}
|
|
|
|
cmd_toggle() {
|
|
local mode="${1:-screen}"
|
|
local minutes
|
|
minutes="$(only_digits "${2:-0}")"
|
|
if systemd_ok && [ -n "$(active_unit)" ]; then
|
|
cmd_off
|
|
else
|
|
cmd_on "$mode" "$minutes"
|
|
fi
|
|
}
|
|
|
|
case "${1:-status}" in
|
|
status) cmd_status ;;
|
|
on|start) cmd_on "${2:-screen}" "${3:-0}" ;;
|
|
switch) cmd_switch "${2:-screen}" ;;
|
|
off|stop) cmd_off "${2:-}" ;;
|
|
toggle) cmd_toggle "${2:-screen}" "${3:-0}" ;;
|
|
ensure-units) cmd_ensure_units "${2:-}" ;;
|
|
version) echo "name=enne2-caffeine"; echo "version=1.0" ;;
|
|
*) fail "unknown-command" ;;
|
|
esac
|