Should headphones be detected automatically

Hey friends! I have just received my reform and noticed that when I plug in my headphones the audio keeps playing through the speakers. I have to explicitly set headphones as output device in pavucontrol.

I’m not sure if it is configured this way or is it something that needs troubleshooting. Has anyone had this issue?

Thanks!

I experience the same thing. It looks like loading “module-switch-on-connect” is supposed to do the trick, but no luck here with my wired headphones.

It’s not been much of a hassle for me, but I might just wire a “toggle sink” script of some kind to a keyboard shortcut, similar to what Veazer did in that thread I linked.

Yeah you need to set it through pavucontrol, BUT I kind of like that functionality. I mean it tracks that when you plug in headphones you would like to use them, but there are times where maybe you need to let someone else listen, and it is nice that you don’t have to unplug them to accomplish that.

Here’s the script I just wrote to toggle between the headphone and speaker ports:

#!/bin/sh

pacmd list | grep -q "active port: <analog-output-speaker>" \
	&& pacmd set-sink-port 0 analog-output-headphones \
	|| pacmd set-sink-port 0 analog-output-speaker

Which I’m keeping at ~/intramuros/scripts/toggle-audio-port.sh and have connected to Mod+F6 using this line in ~/.config/sway/config:

bindsym $mod+F6 exec ~/intramuros/scripts/toggle-audio-port.sh
3 Likes

Thank you for your replies folks! Thanks @lykso for the script :slight_smile:

It’s a good point that automatically switching the output is not necessarily the right way it should work.

1 Like

Lukas pointed out on IRC, that the hardware for detecting whether headphones are plugged in or not is wired as it should. Detecting it is a software problem that nobody sat down and solved yet.

Alas, until this is solved, let me present another solution that toggles between speakers and headphones using waybar, based on the solution by @lykso. Here is my diff of my ~/.config/waybar/config:

--- /etc/skel/.config/waybar/config	2022-10-23 13:04:34.000000000 +0200
+++ /home/josch/.config/waybar/config	2022-11-19 16:40:12.239605516 +0100
@@ -6,7 +6,7 @@
     // Choose the order of the modules
     "modules-left": ["sway/workspaces", "sway/mode", "sway/window"],
     "modules-center": [],
-    "modules-right": ["tray", "network", "custom/stat", "memory", "temperature", "pulseaudio", "clock"],
+    "modules-right": ["tray", "network", "custom/stat", "memory", "temperature", "custom/patoggle", "pulseaudio", "clock"],
     "sway/window": {
     },
     "sway/mode": {
@@ -61,5 +63,13 @@
         "interval": 0,
         "exec": "reform-compstat -d 1 -i 0.3",
         "on-click": "gnome-system-monitor"
+    },
+    "custom/patoggle": {
+        "format": "{}",
+        "interval": "once",
+        "return-type": "json",
+        "exec": "patoggle status",
+        "on-click": "patoggle",
+        "signal": 8
     }
 }

And here is my ~/.local/bin/patoggle script:

#!/bin/sh
set -eu
ret=0
pacmd list | grep -q "active port: <analog-output-speaker>" || ret=$?
if [ "${1:-}" = "status" ]; then
	if [ "$ret" -eq 0 ]; then
		echo '{"text": "🔈", "tooltip": "speakers"}'
	else
		echo '{"text": "🎧", "tooltip": "headphones"}'
	fi
else
	if [ "$ret" -eq 0 ]; then
		pacmd set-sink-port 0 analog-output-headphones
	else
		pacmd set-sink-port 0 analog-output-speaker
	fi
	pkill -SIGRTMIN+8 waybar
fi

Essentially, the script can be called with or without the status argument. If it’s walled with status as the first argument it outputs json as can be interpreted by waybar, setting the icon and tooltip text to the currently selected output sink, either :speaker: for speakers or :headphones: for headphones. In all other cases it toggles the output between headphones and speakers and sends a signal to waybar, forcing the update of the icon to the current value. That way, I can also set up a sway keybinding which will toggle the audio sink and update the icon in waybar:

bindsym $mod+F6 exec patoggle

The only thing that my current setup cannot do is to switch the icon of the output sink gets changed in any other way, for example by using pavucontrol. This could be fixed letting waybar call patoggle status in regular intervals. So set interval from once to a number of seconds if you need that.

5 Likes

Installing pipewire breaks my script above. It seems that pacmd is not ready for pipewire and that pactl (which also comes from pulseaudio-utils) should be used instead. Here is a bug from 2020 about the issue: What is missing for pacmd to work with pipewire? (#357) · Issues · PipeWire / pipewire · GitLab

Indeed pulseaudio devs seem to advise to migrate from pacmd to pactl (due to missing pipewire support) even giving a migration guide:

So I adapted my script. Another advantage is, that pactl can output in json which makes the script much more robust compared to using grep on the output.

#!/bin/sh

set -eu

active_port=$(pactl --format=json list sinks | jq -r '.[] | select(.name == "alsa_output.platform-sound.stereo-fallback") | .active_port')

if [ "${1:-}" = "status" ]; then
	case $active_port in
	analog-output-speaker) echo '{"text": "🔈", "tooltip": "speakers"}';;
	analog-output-headphones) echo '{"text": "🎧", "tooltip": "headphones"}';;
	esac
else
	case $active_port in
	analog-output-speaker) pactl set-sink-port alsa_output.platform-sound.stereo-fallback analog-output-headphones;;
	analog-output-headphones) pactl set-sink-port alsa_output.platform-sound.stereo-fallback analog-output-speaker;;
	esac
	pkill -SIGRTMIN+8 waybar
fi
3 Likes