summaryrefslogtreecommitdiffstats
path: root/desktop/modules/status/statusctl
diff options
context:
space:
mode:
Diffstat (limited to 'desktop/modules/status/statusctl')
-rwxr-xr-xdesktop/modules/status/statusctl45
1 files changed, 42 insertions, 3 deletions
diff --git a/desktop/modules/status/statusctl b/desktop/modules/status/statusctl
index 571beef..531951b 100755
--- a/desktop/modules/status/statusctl
+++ b/desktop/modules/status/statusctl
@@ -82,15 +82,34 @@ tooltip() {
case "$1" in
activated) printf '%s: on' "$mode" ;;
deactivated) printf '%s: off' "$mode" ;;
+ gaming) printf '%s: on (game running)' "$mode" ;;
esac
}
+# The shell's game detector owns status.gaming and presentation is the OR of
+# the two, so the CLI has to read it to agree with the shell. It is not a mode
+# in MODES: nothing here may write it, and only presentation is affected.
+gaming_on() {
+ local v=""
+ [[ -e "$DIR/status.gaming" ]] && v="$(tr -d '[:space:]' < "$DIR/status.gaming" 2>/dev/null)"
+ [[ "$v" == "1" ]]
+}
+
# A missing file is the off state, not a distinct condition: read_mode already
# reads it as 0, and this is the same path `get` uses. There is no "down": a
# file cannot report whether a watcher is alive, and a missing one is exactly
# what a fresh session looks like.
+#
+# A running game reports its own state rather than plain activated, so the
+# widget can show why the mode is on and that a click will not turn it off.
state_now() {
- [[ "$(read_mode)" == "1" ]] && printf 'activated' || printf 'deactivated'
+ if [[ "$mode" == "presentation" ]] && gaming_on; then
+ printf 'gaming'
+ elif [[ "$(read_mode)" == "1" ]]; then
+ printf 'activated'
+ else
+ printf 'deactivated'
+ fi
}
case "$action" in
@@ -106,6 +125,15 @@ case "$action" in
esac
;;
toggle)
+ # A running game pins presentation on and the detector reasserts it
+ # within its poll, so a toggle here would flip back on its own. Refuse
+ # it instead of writing a value that does not stick. `set` still works:
+ # it is the explicit verb, and the manual half is worth setting for
+ # when the game exits.
+ if [[ "$mode" == "presentation" ]] && gaming_on; then
+ printf '%s: presentation held on by a running game\n' "${0##*/}" >&2
+ exit 1
+ fi
[[ "$(read_mode)" == "1" ]] && write_mode 0 || write_mode 1
;;
watch)
@@ -123,9 +151,20 @@ case "$action" in
exec 3< <(inotifywait -q -m -e close_write,moved_to,delete --format '%f' "$DIR" 2>/dev/null)
watcher=$!
trap 'kill "$watcher" 2>/dev/null' EXIT TERM INT
+ # Presentation also follows status.gaming, so a game starting or
+ # ending redraws the widget. Emitting only on a real change keeps a
+ # write of an unchanged value from firing a duplicate line.
+ last="$(state_now)"
while read -r changed <&3; do
- [[ "$changed" == "status.$mode" ]] || continue
- emit "$(state_now)"
+ case "$changed" in
+ "status.$mode") ;;
+ status.gaming) [[ "$mode" == "presentation" ]] || continue ;;
+ *) continue ;;
+ esac
+ now="$(state_now)"
+ [[ "$now" == "$last" ]] && continue
+ last="$now"
+ emit "$now"
done
;;
*)