Auto-adapts sway workspace routing to however many monitors are connected (laptop vs. desktop) instead of hardcoding output names.
52 lines
1.6 KiB
Bash
Executable File
52 lines
1.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -Eeuo pipefail
|
|
|
|
sink_ids=()
|
|
current_index=-1
|
|
|
|
while IFS=$'\t' read -r id is_default; do
|
|
[[ -n "$id" ]] || continue
|
|
sink_ids+=("$id")
|
|
[[ "$is_default" == true ]] && current_index=$((${#sink_ids[@]} - 1))
|
|
done < <(
|
|
wpctl status -n | awk '
|
|
/^Audio$/ {in_audio = 1; next}
|
|
/^Video$/ {in_audio = 0; in_sinks = 0}
|
|
in_audio && /Sinks:/ {in_sinks = 1; next}
|
|
/Sources:/ {in_sinks = 0}
|
|
in_audio && in_sinks && match($0, /[0-9]+\./) {
|
|
id = substr($0, RSTART, RLENGTH - 1)
|
|
print id "\t" (index($0, "*") ? "true" : "false")
|
|
}
|
|
'
|
|
)
|
|
|
|
((${#sink_ids[@]} > 0)) || exit 0
|
|
next_index=$(((current_index + 1) % ${#sink_ids[@]}))
|
|
next_sink_id="${sink_ids[$next_index]}"
|
|
wpctl set-default "$next_sink_id"
|
|
|
|
# Move existing playback streams too; set-default alone only affects new ones.
|
|
while read -r stream_id; do
|
|
[[ -n "$stream_id" ]] || continue
|
|
if wpctl inspect "$stream_id" 2>/dev/null | grep -q 'media.class = "Stream/Output/Audio"'; then
|
|
wpctl set-target "$stream_id" "$next_sink_id" 2>/dev/null || true
|
|
fi
|
|
done < <(
|
|
wpctl status -n | awk '
|
|
/^Audio$/ {in_audio = 1; next}
|
|
/^Video$/ {in_audio = 0; in_streams = 0}
|
|
in_audio && /Streams:/ {in_streams = 1; next}
|
|
in_audio && in_streams && match($0, /[0-9]+\./) {
|
|
print substr($0, RSTART, RLENGTH - 1)
|
|
}
|
|
'
|
|
)
|
|
|
|
sink_name=$(
|
|
wpctl inspect "$next_sink_id" \
|
|
| awk -F' = ' '/node.nick/ {gsub(/^"|"$/, "", $2); print $2; exit}'
|
|
)
|
|
[[ -n "$sink_name" ]] || sink_name="Output $next_sink_id"
|
|
notify-send -a Waybar -u low -r 9102 "Audio output changed" "$sink_name"
|