diff --git a/bumblebee/modules/bluetooth.py b/bumblebee/modules/bluetooth.py new file mode 100644 index 0000000..323df9d --- /dev/null +++ b/bumblebee/modules/bluetooth.py @@ -0,0 +1,96 @@ +"""Displays bluetooth status (Bluez). Left mouse click launches manager app, +right click toggles bluetooth. Needs dbus-send to toggle bluetooth state. + +Parameters: + * bluetooth.device : the device to read state from (default is hci0) + * bluetooth.manager : application to launch on click (blueman-manager) + +""" + + +import os +import re +import bumblebee.input +import bumblebee.output +import bumblebee.engine +import bumblebee.util + + +class Module(bumblebee.engine.Module): + """Bluetooth module.""" + + def __init__(self, engine, config): + """Initialize.""" + super(Module, self).__init__(engine, config, + bumblebee.output.Widget( + full_text=self.status)) + + device = self.parameter("device", "hci0") + self.manager = self.parameter("manager", "blueman-manager") + self._path = "/sys/class/bluetooth/{}".format(device) + self._status = "Off" + + engine.input.register_callback(self, button=bumblebee.input.LEFT_MOUSE, + cmd=self.manager) + engine.input.register_callback(self, + button=bumblebee.input.RIGHT_MOUSE, + cmd=self.toggle) + + def status(self, widget): + """Get status.""" + return self._status + + def update(self, widgets): + """Update current state.""" + if not os.path.exists(self._path): + self._status = "?" + return + + # search for whichever rfkill directory available + try: + dirnames = next(os.walk(self._path))[1] + for dirname in dirnames: + m = re.match(r"rfkill[0-9]+", dirname) + if m is not None: + with open(os.path.join(self._path, + dirname, + 'state'), 'r') as f: + state = int(f.read()) + if state == 1: + self._status = "On" + else: + self._status = "Off" + return + + except IOError: + self._status = "?" + + def manager(self, widget): + """Launch manager.""" + bumblebee.util.execute(self.manager) + + def toggle(self, widget): + """Toggle bluetooth state.""" + if self._status == "On": + state = "false" + else: + state = "true" + + cmd = "dbus-send --system --dest=org.blueman.Mechanism"\ + " / org.blueman.Mechanism.SetRfkillState"\ + " boolean:{}".format(state) + + bumblebee.util.execute(cmd) + + def state(self, widget): + """Get current state.""" + state = [] + + if self._status == "?": + state = ["unknown"] + elif self._status == "On": + state = ["ON"] + else: + state = ["OFF"] + + return state diff --git a/themes/gruvbox-powerline.json b/themes/gruvbox-powerline.json index 5cbfdc0..528ac97 100644 --- a/themes/gruvbox-powerline.json +++ b/themes/gruvbox-powerline.json @@ -37,5 +37,11 @@ "fg": "#1d2021", "bg": "#b8bb26" } - } + }, + "bluetooth": { + "ON": { + "fg": "#1d2021", + "bg": "#b8bb26" + } + } } diff --git a/themes/gruvbox.json b/themes/gruvbox.json index eee93c1..e2b3002 100644 --- a/themes/gruvbox.json +++ b/themes/gruvbox.json @@ -37,5 +37,11 @@ "fg": "#1d2021", "bg": "#b8bb26" } + }, + "bluetooth": { + "ON": { + "fg": "#1d2021", + "bg": "#b8bb26" + } } } diff --git a/themes/icons/awesome-fonts.json b/themes/icons/awesome-fonts.json index 907b3f6..eff16e0 100644 --- a/themes/icons/awesome-fonts.json +++ b/themes/icons/awesome-fonts.json @@ -54,6 +54,11 @@ "tunnel-up": { "prefix": "" }, "tunnel-down": { "prefix": "" } }, + "bluetooth": { + "ON": { "prefix": "" }, + "OFF": { "prefix": "" }, + "?": { "prefix": "" } + }, "battery": { "charged": { "prefix": "", "suffix": "" }, "AC": { "suffix": "" },