Files
kde-caffeine/contents/scripts/caffeine.sh
T

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