#!/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 dev in /dev/input/event*; do event=${dev##*/} name_file="/sys/class/input/$event/device/name" if [[ -r "$name_file" ]] && [[ "$(<"$name_file")" == "Logitech G series G435 Wireless Gaming Headset Consumer Control" ]]; then echo "$dev" break 2 fi done sleep 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 echo "$line"; # 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