bluetooth: conectar los conocidos aunque no estén emparejados

El menú solo enseñaba los dispositivos con Paired: yes, así que un
auricular de confianza que había perdido el emparejamiento no salía, y
volver a emparejarlo fallaba porque bluetoothctl no tenía agente. Ahora
salen los emparejados y los de confianza; al elegir uno se empareja si hace
falta (agente NoInputNoOutput), se busca unos segundos si no está a la
vista, y si falla lo dice (también si wireplumber no está en marcha).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C5v1qWDwgkaVM5kjVHGGh8
This commit is contained in:
Alejandro Guerrero 2026-09-28 15:48:16 +02:00
parent 3864c31ba1
commit 20cb3ae4a6
Signed by: alejandrogs73
GPG key ID: 1CFF10953BEE333C

View file

@ -1,8 +1,9 @@
#!/bin/sh #!/bin/sh
# Menú de bluetooth con dmenu (clic izquierdo en BT de la barra): conectar o # Menú de bluetooth con dmenu (clic izquierdo en BT de la barra). Arriba, los
# desconectar los dispositivos emparejados (󰂱 = conectado), buscar y # dispositivos conocidos (emparejados o de confianza; 󰂱 = conectado): elegir
# emparejar uno nuevo y apagar el adaptador. Si está apagado, ofrece # uno lo desconecta si está conectado y, si no, lo busca y se conecta (y lo
# encenderlo. # vuelve a emparejar si hace falta). Debajo, buscar y emparejar uno nuevo y
# apagar el adaptador. Si está apagado, ofrece encenderlo.
avisar() { avisar() {
notify-send -h string:x-dunst-stack-tag:bluetooth -i bluetooth "Bluetooth" "$1" notify-send -h string:x-dunst-stack-tag:bluetooth -i bluetooth "Bluetooth" "$1"
@ -11,6 +12,36 @@ avisar() {
# "Device AA:BB:CC:DD:EE:FF Nombre" -> "Nombre (AA:BB:CC:DD:EE:FF)" # "Device AA:BB:CC:DD:EE:FF Nombre" -> "Nombre (AA:BB:CC:DD:EE:FF)"
lista() { sed -n 's/^Device \([^ ]*\) \(.*\)/\2 (\1)/p'; } lista() { sed -n 's/^Device \([^ ]*\) \(.*\)/\2 (\1)/p'; }
mac() { printf '%s\n' "$1" | sed 's/.*(\([^)]*\))$/\1/'; } mac() { printf '%s\n' "$1" | sed 's/.*(\([^)]*\))$/\1/'; }
buscar() { bluetoothctl --timeout "$1" scan on >/dev/null; }
# Sin agente, bluetoothctl no puede emparejar; los auriculares no piden PIN.
emparejar() {
bluetoothctl --agent NoInputNoOutput pair "$1" >/dev/null &&
bluetoothctl trust "$1" >/dev/null
}
# conectar MAC: si no está emparejado lo empareja; si no está a la vista, lo
# busca unos segundos y lo vuelve a intentar.
conectar() {
if ! bluetoothctl info "$1" | grep -q 'Paired: yes'; then
emparejar "$1" || { buscar 8 && emparejar "$1"; } || return 1
fi
bluetoothctl connect "$1" >/dev/null ||
{ buscar 8 && bluetoothctl connect "$1" >/dev/null; }
}
# conectar_y_avisar "Nombre (MAC)"
conectar_y_avisar() {
nombre=${1% (*}
avisar "Conectando: $nombre..."
if conectar "$(mac "$1")"; then
avisar "Conectado: $nombre"
elif ! pgrep -x wireplumber >/dev/null; then
avisar "No se pudo conectar $nombre: wireplumber no está en marcha (sin él no hay audio)"
else
avisar "No se pudo conectar $nombre: ¿está encendido y cerca?"
fi
}
if ! bluetoothctl show | grep -q 'Powered: yes'; then if ! bluetoothctl show | grep -q 'Powered: yes'; then
[ "$(echo Encender | menu -p Bluetooth:)" = Encender ] || exit 0 [ "$(echo Encender | menu -p Bluetooth:)" = Encender ] || exit 0
@ -19,10 +50,10 @@ if ! bluetoothctl show | grep -q 'Powered: yes'; then
fi fi
conectados=$(bluetoothctl devices Connected | lista) conectados=$(bluetoothctl devices Connected | lista)
emparejados=$(bluetoothctl devices Paired | lista) conocidos=$({ bluetoothctl devices Paired; bluetoothctl devices Trusted; } | lista | sort -u)
opcion=$( opcion=$(
printf '%s\n' "$emparejados" | while IFS= read -r d; do printf '%s\n' "$conocidos" | while IFS= read -r d; do
[ -n "$d" ] || continue [ -n "$d" ] || continue
if printf '%s\n' "$conectados" | grep -qxF "$d"; then if printf '%s\n' "$conectados" | grep -qxF "$d"; then
echo "󰂱 $d" echo "󰂱 $d"
@ -42,29 +73,19 @@ case $opcion in
;; ;;
*" Buscar dispositivos") *" Buscar dispositivos")
avisar "Buscando dispositivos durante 10 s..." avisar "Buscando dispositivos durante 10 s..."
bluetoothctl --timeout 10 scan on >/dev/null buscar 10
nuevo=$(bluetoothctl devices | lista | awk -v e="$emparejados" ' nuevo=$(bluetoothctl devices | lista | awk -v e="$conocidos" '
BEGIN { n = split(e, a, "\n"); for (i = 1; i <= n; i++) visto[a[i]] } BEGIN { n = split(e, a, "\n"); for (i = 1; i <= n; i++) visto[a[i]] }
!($0 in visto)' | menu -p Emparejar:) !($0 in visto)' | menu -p Emparejar:)
[ -n "$nuevo" ] || exit 0 [ -n "$nuevo" ] || exit 0
m=$(mac "$nuevo") conectar_y_avisar "$nuevo"
if bluetoothctl pair "$m" >/dev/null && bluetoothctl trust "$m" >/dev/null &&
bluetoothctl connect "$m" >/dev/null; then
avisar "Conectado: $nuevo"
else
avisar "No se pudo emparejar: $nuevo"
fi
;; ;;
"󰂱 "*) "󰂱 "*)
bluetoothctl disconnect "$(mac "$opcion")" >/dev/null && bluetoothctl disconnect "$(mac "$opcion")" >/dev/null &&
avisar "Desconectado: ${opcion#"󰂱 "}" avisar "Desconectado: ${opcion#"󰂱 "}"
;; ;;
*) *)
if bluetoothctl connect "$(mac "$opcion")" >/dev/null; then conectar_y_avisar "${opcion#" "}"
avisar "Conectado: ${opcion#" "}"
else
avisar "No se pudo conectar: ${opcion#" "}"
fi
;; ;;
esac esac
pkill -USR1 -x slstatus pkill -USR1 -x slstatus