How to toggle Bluetooth with shortcut on Linux: the proper way

Julian Konchunas
3 min readFeb 5, 2019

--

Throughout my work day I am often switching between my table, bed and sofa with a laptop. I have a Bluetooth mouse and I want to use it when I’m at the table and rely on a touchpad when I am anywhere else. So I often have my bluetooth powered on when I’m not using it and it drains some of my battery juice (or at least I tend to think so). Turning it off by moving my finger and precisely tapping on the tray icon and then clicking to switch it off is quickly becoming tedious. Also when I’m coming back to the table, I want to immediately use my mouse so I have to repeat the same clunky actions again to turn bluetooth back on.

Naturally I’ve tried to search for a keyboard shortcut to make my life easier and found a solution which basically boils down to using rfkill to soft block your bluetooth device like this:

rfkill block hci0

And this actually helps, but also sucks at least on Elementary for the following reason:
This switch has a separate hidden state which cannot be controlled using panel popover. When this command is used, you cannot turn bluetooth on using GUI unless you unblock your interface using the same command. So I’ve decided to dig a bit into Wingpanel source code to find out how they switch bluetooth off and try to emulate it using terminal commands.

It appears that system applet communicates with bluez service using dbus commands. So here, after tinkering a bit with dbus-send command I am presenting the way to turn your bluetooth off the proper way, preserving GUI state and manipulating the same switch.

dbus-send --system --dest=org.bluez --print-reply /org/bluez/hci0 org.freedesktop.DBus.Properties.Set string:org.bluez.Adapter1 string:Powered variant:boolean:false

This is how you turn off your bluetooth switch. For turning it on just replace last word “false” into “true”.

If this command results in error you may need to go on and install DBus explorer to find a proper name for your adapter and interface. And then just replace corresponding fields of the command with your address and Adapter. On Ubuntu and derivatives you can do it by following command:

sudo apt-get install d-feet

And here is my org.bluez section opened in d-feet for the reference.

Here is how I found “hci0” and “Adapter1” names for specified command

For purpose of connecting this command to a shortcut I have written a small script which first reads current power state of your Bluetooth and the turns it on or off.

Here if you have a different adapter or interface you can easily replace those in corresponding variables in this script.

Now you have to save this script somewhere, assign the executable bit to it and bind it to a shortcut. In Elementary OS it can be done using:

System Settings -> Keyboard -> Shortcuts -> Custom -> +

That’s it. I’m pretty sure this approach will work for GNOME and rather confident it may work for KDE and others. Try it for yourself and tell me if it works on your system!

--

--

Julian Konchunas

Blockchain engineer at @madfish.solutions. Ex-Ubisoft. Telegram channel https://t.me/tenxer