69 lines
1.8 KiB
Bash
Executable File
69 lines
1.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# rofi-audio-switch: pick a PulseAudio/PipeWire sink via rofi
|
|
|
|
set -euo pipefail
|
|
|
|
awesome-client 'show_dim()' >/dev/null 2>&1
|
|
trap 'awesome-client "hide_dim()" >/dev/null 2>&1' EXIT
|
|
|
|
# Get list of sinks: index, name, description
|
|
mapfile -t sinks < <(pactl list sinks | awk -F': ' '
|
|
/^Sink #/ { idx=$2 }
|
|
/Name:/ { name=$2 }
|
|
/Description:/ { desc=$2; print idx"\t"name"\t"desc }
|
|
')
|
|
|
|
if [ "${#sinks[@]}" -eq 0 ]; then
|
|
notify-send "Audio Switch" "No sinks found"
|
|
exit 1
|
|
fi
|
|
|
|
current_sink=$(pactl get-default-sink)
|
|
|
|
# Build rofi menu: show description, mark current with a star
|
|
menu=""
|
|
for line in "${sinks[@]}"; do
|
|
name=$(echo "$line" | cut -f2)
|
|
desc=$(echo "$line" | cut -f3)
|
|
if [ "$name" = "$current_sink" ]; then
|
|
menu+="* $desc\n"
|
|
else
|
|
menu+=" $desc\n"
|
|
fi
|
|
done
|
|
|
|
chosen=$(echo -e "$menu" | rofi -dmenu -i -p "Audio Output" -markup-rows \
|
|
-theme-str 'listview { lines: 3; }' \
|
|
-theme-str 'window { height: 220px; }')
|
|
|
|
[ -z "$chosen" ] && exit 0
|
|
|
|
# Strip the leading marker to match description text
|
|
chosen_desc=$(echo "$chosen" | sed 's/^[* ] //')
|
|
|
|
# Find matching sink name for that description
|
|
target_name=""
|
|
for line in "${sinks[@]}"; do
|
|
desc=$(echo "$line" | cut -f3)
|
|
if [ "$desc" = "$chosen_desc" ]; then
|
|
target_name=$(echo "$line" | cut -f2)
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -z "$target_name" ]; then
|
|
notify-send "Audio Switch" "Could not resolve selection"
|
|
exit 1
|
|
fi
|
|
|
|
# Set as default sink
|
|
pactl set-default-sink "$target_name"
|
|
|
|
# Move all currently running streams to the new sink
|
|
mapfile -t inputs < <(pactl list short sink-inputs | cut -f1)
|
|
for input in "${inputs[@]}"; do
|
|
pactl move-sink-input "$input" "$target_name"
|
|
done
|
|
|
|
notify-send "Audio Switch" "Switched to: $chosen_desc"
|