Skip to content

Conversation

@Haletran
Copy link

@Haletran Haletran commented Jun 2, 2025

Hey, really loved your scripts, so i decide to make some changes to the dmenu_audioswitch_prev script with improved audio device switching capabilities and broader compatibility.

Changes

  • PipeWire Support: Added native PipeWire compatibility alongside existing PulseAudio support
  • Bluetooth Integration: Implemented automatic Bluetooth device connectivity handling
  • Code Refactoring: Restructured script for better modularity, readability, and maintainability

Testing

  • Tested successfully on my dmenu rice
  • Would appreciate testing on other configurations to ensure compatibility

Impact

These changes make the script more versatile for modern Linux audio setups while maintaining backward compatibility with existing PulseAudio workflows.

@Haletran
Copy link
Author

Haletran commented Jun 4, 2025

Thanks @alpheratz0 for your reviews — I’ve applied the suggested changes to my code.

@Haletran Haletran requested a review from alpheratz0 June 4, 2025 09:34
enable_and_connect "DEVICE NAME"
set_source "SET SINK NAME OR DEVICE ID"
# the source ID will change every time you connect a bluetooth device, so you may need to change this often
# might need to do a function to get the source ID or name dynamically

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe find a workaround for this? is this only a problem for pipewire users?

Copy link
Author

@Haletran Haletran Jun 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have found a workaround for this, just need to test on both audio server. And no its for both audio server not only pipewire (the id change everytime I disabled bluetooth and re-enable it)

Here is the workaround to get the id:

get_sink_number() {
  local DEVICE_NAME="$1"

  if systemctl --user is-active pipewire >/dev/null 2>&1; then
    wpctl status | awk -v target="$DEVICE_NAME" '/Sinks:/, /Sink endpoints:/ {
      if ($2 == "*") {
        if ($4 == target) print $3
      } else {
        if ($3 == target) print $2
      }
    }' | tr -d '.'
  
  elif systemctl --user is-active pulseaudio >/dev/null 2>&1; then
    pactl list sinks | awk -v dev="$DEVICE_NAME" '
      /Sink #/ { sink = substr($2, 2) }
      $0 ~ dev { print sink; exit }
    '
  else
    notify-send "No audio system detected. Please ensure PipeWire or PulseAudio is running."
    return 1
  fi
}

And here how I plan to use it :

bluetooth () { \
  enable_and_connect "WH-1000XM4"
  local sink_num=$(get_sink_number "WH-1000XM4")
  set_source "$sink_num"
  notify-send  -h string:bgcolor:#88c0d0 "Audio switched to bluetooth!"
}

@BreadOnPenguins
Copy link
Owner

Hey, thanks for your work on this!

For compatibility, it may be better to avoid calling systemctl, for those who don't use systemd. Could instead just check to see if a pid exists for either process.

Sadly atm I don't have a bluetooth device to check with, for the workaround with id. I'll leave this open for now if anyone does feel like testing that or improving further :)

@MGross21
Copy link

MGross21 commented Jul 7, 2025

Can try with pgrep to check for the audio server

if pgrep -x pipewire >/dev/null 2>&1; then
    # code ...
elif pgrep -x pulseaudio >/dev/null 2>&1; then
    # code ...
else
    # code ...
fi

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants