aboutsummaryrefslogtreecommitdiffstats
path: root/bin
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-18 18:20:27 +0200
committerDanilo M. <danix@danix.xyz>2026-09-18 18:20:27 +0200
commit37cabe2fea2f86d481516aae6ddaeb14bac2e64f (patch)
tree1249429fa55c501f5b6fa74823ce6eba8130ea88 /bin
parent46d5607764fb29ae5dbbe001519571f934379917 (diff)
downloadconky-theme-udt-37cabe2fea2f86d481516aae6ddaeb14bac2e64f.tar.gz
conky-theme-udt-37cabe2fea2f86d481516aae6ddaeb14bac2e64f.zip
feat: add a breaktimer card
Replaces the Waybar module that used to show breaktimer.sh with a card on the dashboard. The card's big value is the phase countdown, coloured by phase with the same language the Waybar module used, and two rows name the phase and what the countdown leads to. Data comes from bin/breaktimer-sample.sh, run by conky at execi 5, which reads the daemon's runtime files into a cache. The sampler owns the kill -0 liveness check, because conky's Lua cannot run a process and a dead daemon must read as 'fermo' rather than a stale 'running'. Drops outside the work-hours window freeze the countdown while the phase stays 'working'. The sampler detects this from the remain file's age and the card reads it as 'outside working hours', which also covers a hung daemon. The phase words and colour roles live in data.breaktimer_parse so they are unit-tested; the card only draws the result.
Diffstat (limited to 'bin')
-rwxr-xr-xbin/breaktimer-sample.sh70
1 files changed, 70 insertions, 0 deletions
diff --git a/bin/breaktimer-sample.sh b/bin/breaktimer-sample.sh
new file mode 100755
index 0000000..2bd6f85
--- /dev/null
+++ b/bin/breaktimer-sample.sh
@@ -0,0 +1,70 @@
+#!/bin/bash
+# Sample breaktimer's state into a cache file, for widgets/breaktimer.lua.
+#
+# Conky's Lua cannot run a process, so it cannot call `kill -0` to learn whether
+# the daemon is alive, and shelling out every two seconds to ask breaktimer.sh
+# `status` would parse prose rather than read the four small files the daemon
+# already writes under $XDG_RUNTIME_DIR. Those files are the whole interface;
+# this script is the one place that interprets them.
+
+set -u
+
+CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/udt"
+CACHE="$CACHE_DIR/breaktimer.txt"
+
+umask 077
+mkdir -p "$CACHE_DIR"
+
+TMP="$CACHE.tmp.$$"
+trap 'rm -f "$TMP"' EXIT
+
+RUNTIME="${XDG_RUNTIME_DIR:-/tmp}"
+PID_FILE="$RUNTIME/breaktimer.pid"
+STATE_FILE="$RUNTIME/breaktimer.state"
+PHASE_FILE="$RUNTIME/breaktimer.phase"
+REMAIN_FILE="$RUNTIME/breaktimer.remain"
+
+# The daemon's own tick. Used only to decide how stale the remain file may be
+# before the clock counts as frozen.
+TICK=5
+
+running=no
+if [ -f "$PID_FILE" ] && kill -0 "$(cat "$PID_FILE" 2>/dev/null)" 2>/dev/null; then
+ running=yes
+fi
+
+state=stopped
+phase=stopped
+remain=0
+if [ "$running" = yes ]; then
+ state=$(cat "$STATE_FILE" 2>/dev/null)
+ phase=$(cat "$PHASE_FILE" 2>/dev/null)
+ remain=$(cat "$REMAIN_FILE" 2>/dev/null)
+fi
+[ -z "$state" ] && state=stopped
+[ -z "$phase" ] && phase=stopped
+case "$remain" in ''|*[!0-9]*) remain=0 ;; esac
+
+# Outside the work-hours window the daemon leaves the phase at 'working' without
+# decrementing, so the remain file stops being rewritten; its age is the honest
+# signal that the clock is frozen. Three ticks of slack, so a sample landing a
+# moment before the next tick never reads as frozen. A paused daemon freezes the
+# file too but reports 'paused' and is handled on its own, and a hung daemon
+# freezes it as well, which is a state worth showing rather than hiding.
+frozen=no
+if [ "$running" = yes ] && [ "$state" = running ] && [ "$phase" = working ] \
+ && [ -f "$REMAIN_FILE" ]; then
+ mt=$(stat -c %Y "$REMAIN_FILE" 2>/dev/null || echo 0)
+ [ $(( $(date +%s) - mt )) -gt $((TICK * 3)) ] && frozen=yes
+fi
+
+{
+ echo "generated $(date +%s)"
+ echo "running $running"
+ echo "state $state"
+ echo "phase $phase"
+ echo "remain $remain"
+ echo "frozen $frozen"
+} > "$TMP"
+
+mv -f "$TMP" "$CACHE"