Files
owen 5c57ee20f7 Add Arch Wayland dotfiles: sway/waybar/kitty/nvim/zsh, idempotent installer
Auto-adapts sway workspace routing to however many monitors are
connected (laptop vs. desktop) instead of hardcoding output names.
2026-08-21 22:59:26 -05:00

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"