From b4c94d4d3b8db95167e611bc5d9e1e8b0ed1fe33 Mon Sep 17 00:00:00 2001 From: "David T. Sadler" Date: Tue, 30 Jun 2026 20:28:21 +0100 Subject: Add Bluetooth rofi script --- bin/.bin/bluetooth.sh | 140 +++++++++++++++++++++++++++++++++++++++++++ oxwm/.config/oxwm/config.lua | 10 ++-- 2 files changed, 145 insertions(+), 5 deletions(-) create mode 100755 bin/.bin/bluetooth.sh diff --git a/bin/.bin/bluetooth.sh b/bin/.bin/bluetooth.sh new file mode 100755 index 0000000..5ae5281 --- /dev/null +++ b/bin/.bin/bluetooth.sh @@ -0,0 +1,140 @@ +#!/usr/bin/env bash +set -uo pipefail # Keep -e off so our self-healing logic can handle error codes safely + +# Define the Rofi menu layout. +declare -a order=( + "⚡ Power On Bluetooth" + "🛑 Power Off Bluetooth" + "🔌 Disconnect All Devices" + "---" + "Speaker" + "Earphones" + "Earphones Left" + "Living Room" +) + +# Map profiles to hardware MAC addresses. +declare -A devices +devices[Speaker]="A0:E9:DB:0E:43:79" +devices[Earphones]="98:52:3D:F2:6E:3E" +devices["Earphones Left"]="98:52:3D:F2:36:78" +devices["Living Room"]="42:46:9F:D0:2C:53" + +# Prompt User via Rofi. +MENU_OPTIONS=$(printf "%s\n" "${order[@]}") +SELECTION=$(echo "$MENU_OPTIONS" | rofi -dmenu -p "Bluetooth Menu:") + +# Exit gracefully if the user hits Escape. +if [ -z "$SELECTION" ] || [ "$SELECTION" = "---" ]; then + exit 0 +fi + +if [ "$SELECTION" = "⚡ Power On Bluetooth" ]; then + notify-send "BT" "Powering adapter on..." + bluetoothctl power on + exit 0 +fi + +if [ "$SELECTION" = "🛑 Power Off Bluetooth" ]; then + notify-send "BT" "Powering adapter off..." + bluetoothctl power off + exit 0 +fi + +if [ "$SELECTION" = "🔌 Disconnect All Devices" ]; then + notify-send "BT" "Clearing all active connections..." + for name in "${!devices[@]}"; do + bluetoothctl disconnect "${devices[$name]}" >/dev/null 2>&1 || true + done + notify-send "BT" "All devices disconnected." + exit 0 +fi + +if [ -z "${devices[$SELECTION]:-}" ]; then + notify-send "ERROR" "Invalid choice: $SELECTION" + exit 1 +fi + +TARGET_MAC="${devices[$SELECTION]}" + +# Ensure controller is actually powered up before trying to connect. +if ! bluetoothctl show | grep -q "Powered: yes"; then + notify-send "BT" "Waking up Bluetooth adapter..." + bluetoothctl power on + sleep 2 +fi + +# Force controller runtime options to accept incoming passthroughs. +bluetoothctl pairable on >/dev/null 2>&1 || true +bluetoothctl discoverable on >/dev/null 2>&1 || true + +# Disconnect existing targets to free up the system audio pipelines. +for name in "${!devices[@]}"; do + bluetoothctl disconnect "${devices[$name]}" >/dev/null 2>&1 || true +done + +# Query the machine's local hardware database cache. +DEVICE_CHECK=$(bluetoothctl info "$TARGET_MAC" 2>&1 || true) + +if echo "$DEVICE_CHECK" | grep -q "not available"; then + notify-send "BT: Provisioning" "Device missing from system cache. Probing airwaves..." + + # Run a targeted background scan pass to register device metadata. + bluetoothctl --timeout 5 scan on >/dev/null 2>&1 & + SCAN_PID=$! + sleep 4 + kill "$SCAN_PID" 2>/dev/null || true + wait "$SCAN_PID" 2>/dev/null || true + sleep 1 + + notify-send "BT: Provisioning" "Exchanging encryption keys..." + bluetoothctl pair "$TARGET_MAC" + bluetoothctl trust "$TARGET_MAC" +fi + +# Attempt targeted connection sequence. +notify-send "BT Switch" "Routing audio to $SELECTION..." +CONNECT_OUT=$(bluetoothctl connect "$TARGET_MAC" 2>&1 || true) +echo "$CONNECT_OUT" + +if echo "$CONNECT_OUT" | grep -q "Connection successful"; then + bluetoothctl trust "$TARGET_MAC" >/dev/null 2>&1 || true + + # WirePlumber Sinks Syncing Engine. + CLEAN_MAC="${TARGET_MAC//:/_}" + SINK_NAME=$(wpctl status | grep -o "bluez_output\.[^\ ]*${CLEAN_MAC}[^\ ]*" | head -n 1 || true) + + if [ ! -z "$SINK_NAME" ]; then + wpctl set-default "$SINK_NAME" + # Set a safe volumne just in case we connect to earphones. + wpctl set-volume "$SINK_NAME" 0.10 + fi + + notify-send "BT Switch" "$SELECTION connected successfully!" + +# Handle key synchronization issues seamlessly.... +elif echo "$CONNECT_OUT" | grep -q "br-connection-key-missing"; then + notify-send "BT Error" "Key mismatch! Purging and re-pairing..." + + bluetoothctl remove "$TARGET_MAC" >/dev/null 2>&1 || true + sleep 1 + + bluetoothctl --timeout 5 scan on >/dev/null 2>&1 & + SCAN_PID=$! + sleep 4 + kill "$SCAN_PID" 2>/dev/null || true + wait "$SCAN_PID" 2>/dev/null || true + sleep 1 + + notify-send "BT Recovery" "Put device in pairing mode!" + bluetoothctl pair "$TARGET_MAC" + bluetoothctl trust "$TARGET_MAC" + + if bluetoothctl connect "$TARGET_MAC"; then + notify-send "BT Switch" "$SELECTION repaired and connected!" + else + notify-send "BT ERROR" "Repair fallback routing failed." + fi +else + notify-send "BT ERROR" "Failed to link with $SELECTION. Check pairing state or other devices." +fi diff --git a/oxwm/.config/oxwm/config.lua b/oxwm/.config/oxwm/config.lua index 3818b14..09e5909 100644 --- a/oxwm/.config/oxwm/config.lua +++ b/oxwm/.config/oxwm/config.lua @@ -275,11 +275,6 @@ oxwm.key.bind({ modkey, "Control", "Shift" }, "9", oxwm.tag.toggletag(8)) -- Keychords allow you to bind multiple-key sequences (like Emacs or Vim) -- Format: {{modifiers}, key1}, {{modifiers}, key2}, ... -- Example: Press Mod4+Space, then release and press T to spawn a terminal without auto starting anything. -oxwm.key.chord({ - { { modkey }, "Space" }, - { {}, "B" } -}, oxwm.spawn({ "firefox" })) - oxwm.key.chord({ { { modkey }, "b" }, { {}, "a" } @@ -295,6 +290,11 @@ oxwm.key.chord({ { {}, "p" } }, oxwm.spawn({ "power.sh" })) +oxwm.key.chord({ + { { modkey }, "Space" }, + { {}, "b" } +}, oxwm.spawn({ "bluetooth.sh" })) + ------------------------------------------------------------------------------- -- Autostart ------------------------------------------------------------------------------- -- cgit v1.2.3-13-gbd6f From 47834ead372c86e5df0afc6e909aed8b92d8f30c Mon Sep 17 00:00:00 2001 From: "David T. Sadler" Date: Tue, 30 Jun 2026 21:44:21 +0100 Subject: Update bookmarks --- bookmarks.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bookmarks.txt b/bookmarks.txt index d6954be..4b45d46 100644 --- a/bookmarks.txt +++ b/bookmarks.txt @@ -1,2 +1,3 @@ -Gemini|https://gemini.google.com/app +gemini|https://gemini.google.com/app davidtsadler.com|https://davidtsadler.com/ +jellyfin|http://192.168.1.11:8096/web -- cgit v1.2.3-13-gbd6f From 796e8cd52879f87220e76d71d512f2cc6a79a715 Mon Sep 17 00:00:00 2001 From: "David T. Sadler" Date: Tue, 30 Jun 2026 21:52:14 +0100 Subject: Fix issue with bash formatting treat scripts as sh instead of bash --- nvim/.config/nvim/lua/plugins/conform.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/nvim/.config/nvim/lua/plugins/conform.lua b/nvim/.config/nvim/lua/plugins/conform.lua index 365fb2d..94bdb06 100644 --- a/nvim/.config/nvim/lua/plugins/conform.lua +++ b/nvim/.config/nvim/lua/plugins/conform.lua @@ -22,5 +22,9 @@ require("conform").setup({ command = "biome", args = { "format", "--stdin-file-path", "$FILENAME" }, }, + -- Force shfmt to always use the bash parser variant. + shfmt = { + prepend_args = { "-ln", "bash" }, + }, }, }) -- cgit v1.2.3-13-gbd6f