"""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)
    * bluetooth.dbus_destination : dbus destination (defaults to org.blueman.Mechanism)
    * bluetooth.dbus_destination_path : dbus destination path (defaults to /)

"""


import os
import re
import bumblebee.input
import bumblebee.output
import bumblebee.engine
import bumblebee.util
import bumblebee.popup
import logging


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.popup)

    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 popup(self, widget):
        """Show a popup menu."""
        menu = bumblebee.popup.PopupMenu()
        if self._status == "On":
            menu.add_menuitem('Disable Bluetooth')
        elif self._status == "Off":
            menu.add_menuitem('Enable Bluetooth')
        else:
            return

        # show menu and get return code
        ret = menu.show(widget)
        if ret == 0:
            logging.debug('bt: toggling bluetooth')
            # first (and only) item selected.
            self._toggle()

    def _toggle(self):
        """Toggle bluetooth state."""
        if self._status == "On":
            state = "false"
        else:
            state = "true"

        dst = self.parameter("dbus_destination", "org.blueman.Mechanism")
        dst_path = self.parameter("dbus_destination_path", "/")

        cmd = "dbus-send --system --print-reply --dest={}"\
              " {} org.blueman.Mechanism.SetRfkillState"\
              " boolean:{}".format(dst, dst_path, 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

@@ -470,16 +470,105 @@
 ts to /)
+%0A    * bluetooth.right_click_popup : use popup menu when right-clicked (defaults to True)
 %0A%0A%22%22%22%0A%0A%0A
@@ -1378,24 +1378,248 @@
 lf.manager)%0A
+%0A        # determine whether to use pop-up menu or simply toggle the device on/off%0A        right_click_popup = bumblebee.util.asbool(%0A            self.parameter(%22right_click_popup%22, True))%0A%0A        if right_click_popup:%0A    
         engi
@@ -1651,16 +1651,20 @@
 k(self,%0A
+    
         
@@ -1761,32 +1761,36 @@
                 
+    
 cmd=self.popup)%0A
@@ -1788,16 +1788,219 @@
 f.popup)
+%0A        else:%0A            engine.input.register_callback(self,%0A                                           button=bumblebee.input.RIGHT_MOUSE,%0A                                           cmd=self._toggle)
 %0A%0A    de
@@ -3468,60 +3468,8 @@
  0:%0A
-            logging.debug('bt: toggling bluetooth')%0A
     
@@ -3558,16 +3558,29 @@
 gle(self
+, widget=None
 ):%0A     
@@ -4026,24 +4026,72 @@
 th, state)%0A%0A
+        logging.debug('bt: toggling bluetooth')%0A
         bumb

add a parameter to control bluetooth popup menu