|
|
#!/bin/bash
|
|
|
|
|
|
# =================================================================
|
|
|
# CONFIGURATION – EDIT THESE TWO LINES
|
|
|
# =================================================================
|
|
|
SINK_G435="alsa_output.usb-Logitech_G_series_G435_Wireless_Gaming_Headset_202105190004-00.analog-stereo"
|
|
|
SINK_FALLBACK="alsa_output.pci-0000_03_00.1.hdmi-surround-extra3"
|
|
|
|
|
|
# Rapid‑volume‑up detection
|
|
|
RAPID_THRESHOLD=10 # number of VOLUMEUP events in the window
|
|
|
RAPID_WINDOW=3 # seconds
|
|
|
|
|
|
# =================================================================
|
|
|
# Find the G435 Consumer Control input device automatically
|
|
|
# =================================================================
|
|
|
find_g435_event() {
|
|
|
for link in /dev/input/by-id/*G435*event*; do
|
|
|
if [ -e "$link" ]; then
|
|
|
readlink -f "$link"
|
|
|
return 0
|
|
|
fi
|
|
|
done
|
|
|
return 1
|
|
|
}
|
|
|
|
|
|
DEVICE=""
|
|
|
while [ -z "$DEVICE" ]; do
|
|
|
DEVICE=$(find_g435_event)
|
|
|
if [ -z "$DEVICE" ]; then
|
|
|
echo "G435 input device not found – retrying in 2s..." >&2
|
|
|
sleep 2
|
|
|
fi
|
|
|
done
|
|
|
echo "Found G435 device: $DEVICE"
|
|
|
|
|
|
# =================================================================
|
|
|
# Switch function
|
|
|
# =================================================================
|
|
|
switch_to_sink() {
|
|
|
local target="$1"
|
|
|
pactl set-default-sink "$target"
|
|
|
for id in $(pactl list short sink-inputs | awk '{print $1}'); do
|
|
|
pactl move-sink-input "$id" "$target" 2>/dev/null
|
|
|
done
|
|
|
echo "Switched to: $target"
|
|
|
}
|
|
|
|
|
|
# =================================================================
|
|
|
# Event loop – grab the device exclusively
|
|
|
# =================================================================
|
|
|
up_timestamps=()
|
|
|
|
|
|
exec 3< <(stdbuf -oL evtest "$DEVICE")
|
|
|
|
|
|
while read -u 3 line; do
|
|
|
# Volume UP press (115)
|
|
|
if [[ "$line" == *"code 115 (KEY_VOLUMEUP)"*"value 1"* ]]; then
|
|
|
now=$(date +%s)
|
|
|
up_timestamps+=("$now")
|
|
|
# prune timestamps older than window
|
|
|
cutoff=$((now - RAPID_WINDOW))
|
|
|
new_ts=()
|
|
|
for ts in "${up_timestamps[@]}"; do
|
|
|
[ "$ts" -ge "$cutoff" ] && new_ts+=("$ts")
|
|
|
done
|
|
|
up_timestamps=("${new_ts[@]}")
|
|
|
count=${#up_timestamps[@]}
|
|
|
|
|
|
if [ "$count" -gt "$RAPID_THRESHOLD" ]; then
|
|
|
echo "Rapid VOLUMEUP ($count presses) – switching to FALLBACK"
|
|
|
switch_to_sink "$SINK_FALLBACK"
|
|
|
else
|
|
|
echo "Normal VOLUMEUP – switching to G435"
|
|
|
switch_to_sink "$SINK_G435"
|
|
|
fi
|
|
|
|
|
|
# Volume DOWN press (114) – always switch to G435
|
|
|
elif [[ "$line" == *"code 114 (KEY_VOLUMEDOWN)"*"value 1"* ]]; then
|
|
|
echo "VOLUMEDOWN – switching to G435"
|
|
|
switch_to_sink "$SINK_G435"
|
|
|
fi
|
|
|
done
|