From a00ad450bfac9f2dd109a7645d5dc24a9d314f66 Mon Sep 17 00:00:00 2001 From: KK Date: Thu, 18 Jun 2026 15:12:10 +0200 Subject: [PATCH] Add script for scratchpad to ask stuff --- bin/pi-voice-query | 95 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100755 bin/pi-voice-query diff --git a/bin/pi-voice-query b/bin/pi-voice-query new file mode 100755 index 0000000..f8fd436 --- /dev/null +++ b/bin/pi-voice-query @@ -0,0 +1,95 @@ +#!/bin/sh +set -eu + +SESSION="pi-voice" +APP_ID="pi-voice" +TITLE="Pi Voice" +OUT="${XDG_RUNTIME_DIR:-/tmp}/pi-voice-query.txt" +STATUS_SCRIPT="$HOME/.config/sway/status.sh" + +refresh_bar() { + pkill -USR1 -f "$STATUS_SCRIPT" 2>/dev/null || true +} + +position_pi_window() { + # Size scratchpad window to 60% of the focused output using absolute pixels. + # Doing this here is more reliable than a for_window percentage resize. + set -- $(swaymsg -t get_outputs 2>/dev/null | python3 -c ' +import json, sys +outs = json.load(sys.stdin) +out = next((o for o in outs if o.get("focused")), None) or next((o for o in outs if o.get("active")), None) +rect = (out or {}).get("rect", {}) +w = int(rect.get("width", 1200) * 0.6) +h = int(rect.get("height", 800) * 0.6) +print(w, h) +') + w=${1:-1200} + h=${2:-800} + swaymsg '[app_id="'"$APP_ID"'"] border pixel 2, resize set width '"$w"' px height '"$h"' px, move position center' >/dev/null 2>&1 || true +} + +ensure_pi_terminal() { + if ! tmux has-session -t "$SESSION" 2>/dev/null; then + tmux new-session -d -s "$SESSION" 'pi' + fi + + if command -v swaymsg >/dev/null 2>&1; then + if ! swaymsg -t get_tree 2>/dev/null | grep -q '"app_id": "'"$APP_ID"'"'; then + foot --app-id="$APP_ID" --title="$TITLE" \ + --override=main.resize-by-cells=no \ + --override=colors.alpha=1.0 \ + --override=main.pad=0x0 \ + tmux attach-session -t "$SESSION" >/dev/null 2>&1 & + # Give the window a moment to appear before trying to show/focus it. + sleep 0.5 + fi + swaymsg '[app_id="'"$APP_ID"'"] scratchpad show, focus' >/dev/null 2>&1 || true + position_pi_window + fi +} + +send_to_pi() { + text=$1 + [ -n "$text" ] || exit 0 + + ensure_pi_terminal + + # Paste literally, then press Enter to submit to pi. + printf '%s' "$text" | tmux load-buffer - + tmux paste-buffer -t "$SESSION" + tmux send-keys -t "$SESSION" Enter +} + +case "${1:-}" in + start) + ensure_pi_terminal + : > "$OUT" + voxtype record start --file="$OUT" + refresh_bar + ;; + stop) + voxtype record stop + refresh_bar + + # Wait for transcription to land in OUT. Stop early once voxtype is idle + # and the file has text, otherwise allow slower large-model runs. + i=0 + while [ "$i" -lt 180 ]; do + if [ -s "$OUT" ]; then + break + fi + state=$(voxtype status 2>/dev/null || true) + [ "$state" = idle ] && [ "$i" -gt 2 ] && break + sleep 0.5 + i=$((i + 1)) + done + refresh_bar + + text=$(cat "$OUT" 2>/dev/null || true) + send_to_pi "$text" + ;; + *) + echo "usage: $0 start|stop" >&2 + exit 2 + ;; +esac