Last active
July 6, 2019 22:27
-
-
Save ralt/b25095dcc1be680e581a9a53f2edcb43 to your computer and use it in GitHub Desktop.
How to make bluetooth flawless in gnome shell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# This shell script setups bluetooth to be flawless in gnome shell. | |
# Devices are now instantly connected when they're near the laptop. | |
# (It probably works as a service for random WMs too.) | |
# The issue is essentially that gnome-bluetooth is issuing the wrong | |
# dbus calls to connect the device immediately; org.bluez gets EAGAIN | |
# from the kernel when it processes gnome-bluetooth dbus calls (until | |
# it eventually succeeds, 20-30s later). However, bluetoothctl is | |
# flawless at it. Maybe some day gnome-bluetooth will fix this. In the | |
# meantime, this hack lets me have a seamless bluetooth experience. | |
# PS: I tried to report the bug to gnome-bluetooth but haven't figured | |
# out how. Apparently I need to register to 2 or 3 bug trackers? I may | |
# just be dense. | |
# To be able to run this hack, you need: bluez (which provides the | |
# bluetoothctl binary) and python3-gevent. | |
# Source: https://gist.github.com/ralt/b25095dcc1be680e581a9a53f2edcb43 | |
# License: MIT (is that even needed for such a small amount of code?) | |
set -e | |
# Start with checking the requirements. | |
python3 -c 'import gevent' &> /dev/null || echo 'You need python3-gevent' && exit 1 | |
which bluetoothctl &> /dev/null || echo 'You need bluez (for bluetoothctl)' && exit 1 | |
# And now the fun begins. | |
cd ~ | |
# Create a systemd user service for our hack. | |
cat > .config/systemd/user/fix-bluetooth.service <<EOF | |
[Unit] | |
Description=Fix bluetooth | |
[Service] | |
ExecStart=/home/$USER/bin/fix-bluetooth | |
[Install] | |
WantedBy=default.target | |
EOF | |
# Now put the hack in the ~/bin folder. | |
mkdir -p bin | |
cat > bin/fix-bluetooth <<EOF | |
#!/usr/bin/env python3 | |
import gevent.monkey | |
gevent.monkey.patch_all() | |
import subprocess | |
import time | |
import gevent | |
def _refresh(device): | |
while True: | |
try: | |
subprocess.check_call(["bluetoothctl", "connect", device]) | |
except subprocess.CalledProcessError: | |
time.sleep(1) | |
else: | |
time.sleep(10) | |
if __name__ == "__main__": | |
refreshers = {} | |
while True: | |
out = subprocess.check_output(["bluetoothctl", "devices"]) | |
devices = [] | |
for line in out.splitlines(): | |
try: | |
_, device, _ = line.split(b" ", 2) | |
except ValueError: | |
continue | |
devices.append(device) | |
for device in devices: | |
if device not in refreshers: | |
print("Taking care of device: {}".format(device)) | |
refreshers[device] = gevent.spawn(_refresh, device) | |
delete = [] | |
for device in refreshers: | |
if device not in devices: | |
print("Forgetting about device: {}".format(device)) | |
refreshers[device].kill() | |
delete.append(device) | |
for device in delete: | |
del refreshers[device] | |
time.sleep(60) | |
EOF | |
# Don't forget this or you look stupid. | |
chmod +x bin/fix-bluetooth | |
# Finally, enable and start our systemd user service. | |
systemctl --user enable fix-bluetooth | |
systemctl --user start fix-bluetooth |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment