Watch
1
0
Fork
You've already forked souveraine
0
souveraine/packaging/souveraine-button

68 lines
2.8 KiB
Text
Raw Permalink Normal View History

#!/bin/sh
# Report a hardware button edge to the session authority. That is all it does.
#
# It replaces `blueline-power-button`, which was policy in shell script: it read
# its own copy of the panel state, asked the SHELL to lock over `qs ipc`, polled
# `session state` twenty times at 100 ms grepping JSON for `"locked": true`, and
# then called `blueline-screen-toggle off` itself. Three separate problems:
#
# 1. It blanked the panel without going through sessiond's `request_blank()`,
# so LOCK-DPMS-LESSONS §1 ("every path to a dark panel routes through it —
# an invariant, not a coincidence") had a hole in it, and the hole was the
# most-used control on the device.
# 2. It carried its own copy of the lock-then-blank ordering, which is the
# exact duplication DEVICE-STATE-MACHINE §1 is about: seven blind actors,
# three of which can turn the screen off.
# 3. It could only ever see one edge, so it could never tell a tap from a
# hold. Gesture recognition needs time, and a process that exits cannot
# hold any.
#
# Now the machine owns all three. This reports `down` and `up`; sessiond
# accumulates them into tap / double / triple / hold and decides what, if
# anything, that means.
#
# Wire it up in hyprland.lua as a PAIR — press and release:
#
# hl.bind( "XF86PowerOff", hl.dsp.exec_cmd("souveraine-button power down"), { locked = true })
# hl.bindr("XF86PowerOff", hl.dsp.exec_cmd("souveraine-button power up"), { locked = true })
#
# Only reporting `down` gives you a machine that thinks the button is held
# forever: the hold threshold passes, `Hold` fires, and no `Tap` ever resolves.
set -eu
button=${1:-power}
edge=${2:-down}
case "$edge" in
down | up) ;;
*)
echo "usage: souveraine-button <power|volume_up|volume_down> <down|up>" >&2
exit 2
;;
esac
runtime=${XDG_RUNTIME_DIR:-/run/user/$(id -u)}
sock="$runtime/souveraine/sessiond.sock"
line="{\"op\":\"button\",\"button\":\"$button\",\"edge\":\"$edge\"}"
# Fire and forget, with a hard timeout. A button press must never block on the
# authority being slow — the user is holding the button and the phone must not
# feel stuck. Losing an edge degrades to a missed gesture, which is recoverable;
# hanging here is not.
#
# No nc/socat on this device (checked), so this is Python's stdlib or nothing.
exec timeout 1 python3 -c '
import socket, sys
sock, line = sys.argv[1], sys.argv[2]
try:
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.settimeout(0.8)
s.connect(sock)
s.sendall((line + "\n").encode())
except Exception:
# sessiond down. Say so in the journal and drop it: a button reporter that
# falls back to acting on its own is the thing this file exists to delete.
print("sessiond unreachable; button edge dropped: " + line, file=sys.stderr)
sys.exit(1)
' "$sock" "$line"