diff options
| author | David T. Sadler <davidtsadler@googlemail.com> | 2026-07-01 14:42:07 +0100 |
|---|---|---|
| committer | David T. Sadler <davidtsadler@googlemail.com> | 2026-07-01 14:42:07 +0100 |
| commit | 9dd2fa87e55075887b2036246951169e0ae6e9ea (patch) | |
| tree | 40b208f865760a2acd72abaa0e76c52eed399f53 | |
| parent | a81384be8899621aad68826af5c2b648dceaf3e5 (diff) | |
| parent | 796e8cd52879f87220e76d71d512f2cc6a79a715 (diff) | |
Merge branch 'main' into howl
| -rwxr-xr-x | bin/.bin/bluetooth.sh | 140 | ||||
| -rw-r--r-- | bookmarks.txt | 3 | ||||
| -rw-r--r-- | nvim/.config/nvim/lua/plugins/conform.lua | 4 | ||||
| -rw-r--r-- | oxwm/.config/oxwm/config.lua | 10 |
4 files changed, 151 insertions, 6 deletions
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/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 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" }, + }, }, }) diff --git a/oxwm/.config/oxwm/config.lua b/oxwm/.config/oxwm/config.lua index 68a5b28..3b37a8c 100644 --- a/oxwm/.config/oxwm/config.lua +++ b/oxwm/.config/oxwm/config.lua @@ -261,11 +261,6 @@ oxwm.key.bind({ modkey, "Control", "Shift" }, "9", oxwm.tag.toggletag(8)) -- 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" } }, oxwm.spawn({ "add-bookmark.sh" })) @@ -280,6 +275,11 @@ oxwm.key.chord({ { {}, "p" } }, oxwm.spawn({ "power.sh" })) +oxwm.key.chord({ + { { modkey }, "Space" }, + { {}, "b" } +}, oxwm.spawn({ "bluetooth.sh" })) + ------------------------------------------------------------------------------- -- Autostart ------------------------------------------------------------------------------- |
