manually setting the default sink isn’t sticking or isn’t being respected by some applications. Let’s try a more direct approach to prevent audio from being routed to your monitor’s HDMI/DisplayPort output.

Since you’re using Sway window manager, we can leverage Sway’s configuration to handle this automatically. Here are a few approaches to try:

Solution 1: Disable HDMI Audio Output

One direct solution is to simply blacklist the HDMI audio outputs:

# Create a configuration file to blacklist HDMI audio
sudo tee /etc/modprobe.d/blacklist-hdmi-audio.conf << 'EOF'
# Disable HDMI audio
blacklist snd_hda_codec_hdmi
EOF
 
# Update initramfs (might need to adjust command for Fedora)
sudo dracut -f

This would require a reboot to take effect, and it’s a bit aggressive as it completely disables HDMI audio.

Solution 2: Using PipeWire/WirePlumber Rules

Let’s create a more robust WirePlumber configuration file that will explicitly disable the HDMI outputs:

mkdir -p ~/.config/wireplumber/main.lua.d/
 
cat > ~/.config/wireplumber/main.lua.d/51-disable-hdmi-audio.lua << 'EOF'
-- Disable HDMI/DisplayPort audio outputs
hdmi_disable_rule = {
  matches = {
    {
      { "node.name", "matches", "*HDMI*" },
      { "node.name", "matches", "*DisplayPort*" },
    },
  },
  apply_properties = {
    ["node.disabled"] = true,
  },
}
 
table.insert(alsa_monitor.rules, hdmi_disable_rule)
 
-- Make sure headphones are prioritized and enabled
headphones_rule = {
  matches = {
    {
      { "node.name", "matches", "*Headphones*" },
    },
  },
  apply_properties = {
    ["node.disabled"] = false,
    ["priority.session"] = 3000,
    ["priority.driver"] = 3000,
  },
}
 
table.insert(alsa_monitor.rules, headphones_rule)
EOF
 
# Restart WirePlumber
systemctl --user restart wireplumber

Solution 3: Using Sway Configuration

Add an autostart command to your Sway config to disable HDMI audio when it appears:

# Add to ~/.config/sway/config
cat >> ~/.config/sway/config << 'EOF'
 
# Script to disable HDMI audio and ensure headphones are default
exec_always {
    # Monitor for new audio devices and set the default to headphones
    bash -c "sleep 2 && for hdmi in $(wpctl status | grep -i 'HDMI\|DisplayPort' | grep -oP '^\s*\K\d+'); do wpctl set-profile $hdmi off; done; wpctl set-default $(wpctl status | grep -i 'Headphones' | grep -oP '^\s*\K\d+')"
}
 
# When a display is connected/disconnected
exec_always {
    bash -c "swaymsg -t subscribe '[\"output\"]' -m | while read -r _; do sleep 1; for hdmi in $(wpctl status | grep -i 'HDMI\|DisplayPort' | grep -oP '^\s*\K\d+'); do wpctl set-profile $hdmi off; done; wpctl set-default $(wpctl status | grep -i 'Headphones' | grep -oP '^\s*\K\d+'); done"
}
EOF

Solution 4: Create a udev Rule

Create a udev rule to handle the monitor connection event:

sudo tee /etc/udev/rules.d/90-hdmi-audio.rules << 'EOF'
ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/usr/bin/su jenny -c '/usr/bin/bash -c \"sleep 2 && /usr/bin/wpctl set-default $(/usr/bin/wpctl status | grep -i Headphones | grep -oP \"^\s*\K\d+\")\"'"
EOF
 
# Reload udev rules
sudo udevadm control --reload-rules

Solution 5: Check if the Display Manager is the Culprit

Some display managers can affect audio routing. If you’re using a display manager with Sway, it might be interfering with your audio settings.

Try this more direct approach using pactl:

# Create a script that will handle audio routing
mkdir -p ~/bin
cat > ~/bin/fix-audio.sh << 'EOF'
#!/bin/bash
 
# Disable all HDMI sinks
for sink in $(pactl list short sinks | grep -i 'HDMI\|DisplayPort' | cut -f1)
do
  pactl set-sink-mute $sink 1
  # Set HDMI volumes to 0
  pactl set-sink-volume $sink 0%
done
 
# Enable and set headphones as default
HEADPHONE_SINK=$(pactl list short sinks | grep -i 'Headphones' | cut -f1)
if [ ! -z "$HEADPHONE_SINK" ]; then
  pactl set-sink-mute $HEADPHONE_SINK 0
  pactl set-default-sink $HEADPHONE_SINK
fi
EOF
 
chmod +x ~/bin/fix-audio.sh
 
# Add to Sway config to run when a display changes
echo 'exec_always ~/bin/fix-audio.sh' >> ~/.config/sway/config
echo 'exec_always swaymsg -t subscribe "[\\"output\\"]" -m | while read -r _; do ~/bin/fix-audio.sh; done' >> ~/.config/sway/config

After implementing any of these solutions, you’ll likely need to reload Sway (swaymsg reload) or log out and back in for the changes to take effect.

Would you like to try one of these approaches? Let me know if you need more information about any particular solution.