#!/usr/bin/env bash
# start.sh — apply KIOSK_DISPLAY_MODE (best-effort) then launch the kiosk app
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONF="$SCRIPT_DIR/kiosk.conf"
if [ -f "$CONF" ]; then
# shellcheck disable=SC1090
. "$CONF"
fi
MODE="${KIOSK_DISPLAY_MODE:-}"
apply_mode() {
local mode="$1"
# Accept WxH or WxH@Hz (e.g. 1280x720 or 1280x720@60.000000)
if [[ ! "$mode" =~ ^([0-9]+)x([0-9]+) ]]; then
echo "[start.sh] No valid mode specified: '$mode'"
return 1
fi
local W=${BASH_REMATCH[1]}
local H=${BASH_REMATCH[2]}
# Strip @Hz suffix for tools that don't accept it
local WH="${W}x${H}"
echo "[start.sh] Applying display mode $mode (best-effort)"
# Try X11 xrandr
if command -v xrandr >/dev/null 2>&1; then
OUT=$(xrandr --query 2>/dev/null | awk '/ connected/{print $1; exit}')
if [ -n "$OUT" ]; then
echo "[start.sh] Using xrandr on output $OUT"
if xrandr --output "$OUT" --mode "$WH" 2>/dev/null; then
echo "[start.sh] xrandr succeeded"
return 0
else
echo "[start.sh] xrandr failed to set mode"
fi
fi
fi
# Try sway (Wayland)
if command -v swaymsg >/dev/null 2>&1; then
echo "[start.sh] Trying swaymsg"
if swaymsg "output * mode ${W} ${H}" >/dev/null 2>&1; then
echo "[start.sh] swaymsg succeeded"
return 0
else
echo "[start.sh] swaymsg failed"
fi
fi
# Try wlr-randr
if command -v wlr-randr >/dev/null 2>&1; then
OUT=$(wlr-randr 2>/dev/null | awk 'NR==1{print $1}')
if [ -n "$OUT" ]; then
echo "[start.sh] Using wlr-randr on output $OUT"
if wlr-randr --output "$OUT" --mode "$WH" >/dev/null 2>&1; then
echo "[start.sh] wlr-randr succeeded"
return 0
else
echo "[start.sh] wlr-randr failed"
fi
fi
fi
echo "[start.sh] No supported display tool succeeded (this is best-effort)."
return 1
}
apply_audio() {
local index="$1"
if [[ ! "$index" =~ ^[0-9]+$ ]]; then
return 1
fi
if ! command -v pw-cli >/dev/null 2>&1; then
return 1
fi
echo "[start.sh] Applying audio profile index $index (best-effort)"
local dev_id
dev_id=$(pw-dump 2>/dev/null | python3 -c "
import sys, json
try:
for n in json.load(sys.stdin):
if n.get('type') == 'PipeWire:Interface:Device':
props = n.get('info', {}).get('props', {})
if props.get('media.class') == 'Audio/Device':
print(n['id'])
break
except Exception:
pass
" 2>/dev/null)
if [ -n "$dev_id" ]; then
if pw-cli s "$dev_id" Profile "{ index: $index }" >/dev/null 2>&1; then
echo "[start.sh] Audio profile applied (device $dev_id, index $index)"
return 0
else
echo "[start.sh] pw-cli failed to set audio profile"
fi
else
echo "[start.sh] No audio device found via pw-dump"
fi
return 1
}
if [ -n "$MODE" ]; then
apply_mode "$MODE" || echo "[start.sh] apply_mode failed, continuing to start app"
else
echo "[start.sh] No KIOSK_DISPLAY_MODE set in $CONF"
fi
AUDIO_INDEX="${KIOSK_AUDIO_PROFILE_INDEX:-}"
if [ -n "$AUDIO_INDEX" ]; then
apply_audio "$AUDIO_INDEX" || echo "[start.sh] apply_audio failed, continuing to start app"
else
echo "[start.sh] No KIOSK_AUDIO_PROFILE_INDEX set in $CONF"
fi
cd "$SCRIPT_DIR"
echo "[start.sh] Launching kiosk app"
exec python3 app.py