diff options
Diffstat (limited to 'desktop/modules/status/statusctl')
| -rwxr-xr-x | desktop/modules/status/statusctl | 45 |
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 ;; *) |
