When I connect a Bluetooth device, it isn't automatically selected as the new output device in GNOME 49.
Solution: Auto switch to new connected BT Device
Tested:
mkdir -p ~/.config/pipewire/pipewire-pulse.conf.d/
echo 'pulse.cmd = [{ cmd = "load-module" args = "module-switch-on-connect" }]' > ~/.config/pipewire/pipewire-pulse.conf.d/50-bt-switch.conf
systemctl --user restart pipewire pipewire-pulse wireplumber
The module now automatically switches to the headset upon Bluetooth connection (A2DP preferred, if available).
Also the bug is related to the following issue: If you connect a bt device and last volume was set above mute, the selected audio output is not changed (my monitor in that case) but it uses the sound volume of newly connected device / 100 or what ever. Blew me literally away multiple times until I muted the monitors with their volume buttons.
Part 2 - totally optional
Sometimes only handsfree mode is available than a simple reconnect often fixed the issue.
crap below dont waste time reading - will comeback once i have to time to focus on this.
The idea was that a udev rule is triggered when the device connects,
it checks the mode and reconnects if headset is not available.
sudo echo 'SUBSYSTEM=="bluetooth", ACTION=="add", RUN+="/home/$USER/bt-reconnect.sh"' > /etc/udev/rules.d/99-bt-headset.rules
since udev does not work in this case (if it does let me know)
using a systemd service which checks the path '/sys/class/bluetooth/*/device' for new bt devices
and then executes as soon as a change is detected. But I couldn't get it to work.
Maybe / hopefully I test this later - be aware
sudo nano /etc/systemd/system/bt-device.path
[Unit]
Description=Watch for Bluetooth device appearance
[Path]
# Watch the Bluetooth device directory (adjust if your device shows up elsewhere)
PathExistsGlob=/sys/class/bluetooth/*/device
Unit=bt-device.service
[Install]
WantedBy=multi-user.target
Updated: Initial version did not work - I got 'Could not connect to PipeWire' as response.
I changed it to restart user level pipewire services and it did work.
systemctl --user restart pipewire
systemctl --user restart pipewire-pulse
bt-reconnect.sh
#!/bin/bash
sleep 3
NEW_DEVICE=$(bluetoothctl devices Connected | grep -o '[0-9A-Fa-f:]\{17\}' | head -1)
STATE_FILE="/tmp/bt-reconnect-$NEW_DEVICE"
if [ -n "$NEW_DEVICE" ]; then
echo "$(date) Checking $NEW_DEVICE..." >> /tmp/bt-reconnect.log
# Skip if already set as default
CURRENT_SINK=$(wpctl status | grep '\*' | grep -o '[0-9]\+' | head -1)
CURRENT_SINK_NAME=$(wpctl inspect "$CURRENT_SINK" 2>/dev/null | grep -i bluez | grep -o '[0-9A-Fa-f:]\{17\}' || echo "none")
[[ "$CURRENT_SINK_NAME" == "$NEW_DEVICE" ]] && { echo "Already default → Skipping"; exit 0; }
# Check if only Handsfree (HSP/HFP) is available
INFO=$(bluetoothctl info "$NEW_DEVICE")
HAS_A2DP=$(echo "$INFO" | grep -q "UUID: Audio Sink" && echo 1 || echo 0)
if [ "$HAS_A2DP" = "1" ]; then
# Set as default immediately
NEW_SINK=$(wpctl status | sed 's/│/|/g' | grep -i "$NEW_DEVICE" | grep -v source | sed 's/|/ /g' | awk '{for(i=1;i<=NF;i++) if($i ~ /^[0-9]+$/) {print $i; exit}}' | head -1)
[[ "$NEW_SINK" =~ ^[0-9]+$ ]] && wpctl set-default "$NEW_SINK"
exit 0
fi
# AUTO-RECONNECT LOGIC (3x max)
ATTEMPTS=$(cat "$STATE_FILE" 2>/dev/null || echo "0")
ATTEMPTS=$((ATTEMPTS + 1))
if [ "$ATTEMPTS" -le 3 ]; then
echo "$(date) -> Attempt ${ATTEMPTS}/3..." >> /tmp/bt-reconnect.log
echo "$ATTEMPTS" > "$STATE_FILE"
bluetoothctl disconnect "$NEW_DEVICE"
systemctl --user restart pipewire
systemctl --user restart pipewire-pulse
sleep 1
bluetoothctl connect "$NEW_DEVICE"
sleep 3
# Check success after reconnect
NEW_INFO=$(bluetoothctl info "$NEW_DEVICE")
if echo "$NEW_INFO" | grep -q "UUID: Audio Sink"; then
echo "A2DP successful after ${ATTEMPTS} attempts!" >> /tmp/bt-reconnect.log
rm -f "$STATE_FILE"
# Set sink logic would follow here if needed...
fi
else
echo "$(date) MAX 3 attempts reached!" >> /tmp/bt-reconnect.log
rm -f "$STATE_FILE"
# GNOME Notification
notify-send "Bluetooth Headphone Mode unavailable" "Please turn your Bluetooth Device off and on to reset connection" -u critical -t 10000
bluetoothctl disconnect "$NEW_DEVICE"
fi
fi
When I connect a Bluetooth device, it isn't automatically selected as the new output device in GNOME 49.
Solution: Auto switch to new connected BT Device
Tested:
The module now automatically switches to the headset upon Bluetooth connection (A2DP preferred, if available).
Also the bug is related to the following issue: If you connect a bt device and last volume was set above mute, the selected audio output is not changed (my monitor in that case) but it uses the sound volume of newly connected device / 100 or what ever. Blew me literally away multiple times until I muted the monitors with their volume buttons.
Part 2 - totally optional
Sometimes only handsfree mode is available than a simple reconnect often fixed the issue.
crap below dont waste time reading - will comeback once i have to time to focus on this.
The idea was that a udev rule is triggered when the device connects,
it checks the mode and reconnects if headset is not available.
since udev does not work in this case (if it does let me know)
using a systemd service which checks the path '/sys/class/bluetooth/*/device' for new bt devices
and then executes as soon as a change is detected. But I couldn't get it to work.
Maybe / hopefully I test this later - be aware
sudo nano /etc/systemd/system/bt-device.pathUpdated: Initial version did not work - I got 'Could not connect to PipeWire' as response.
I changed it to restart user level pipewire services and it did work.
bt-reconnect.sh