[gnome-shell] bluetooth: Show the Bluetooth menu when there were setup devices



commit 8ceae3b0548efcd7f514c2dd7b365f261654cbb6
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Nov 13 10:58:35 2014 +0100

    bluetooth: Show the Bluetooth menu when there were setup devices
    
    If we detected that Bluetooth devices were setup, show the Bluetooth
    menu so that users can easily turn Bluetooth back on.
    
    This is a bit of a hack, as we cannot detect whether there is a
    Bluetooth adapter at all when it's disabled, so we cannot tell whether
    there were any Bluetooth devices setup, at some point. This state is
    saved in the gnome-shell GSettings in the had-bluetooth-devices-setup
    key.
    
    Checking whether we saw Bluetooth devices at one point is a good
    enough guess of whether there will be some in the future.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=723848

 data/org.gnome.shell.gschema.xml.in.in |   10 +++++
 js/ui/status/bluetooth.js              |   64 +++++++++++++++++++++++++------
 2 files changed, 61 insertions(+), 13 deletions(-)
---
diff --git a/data/org.gnome.shell.gschema.xml.in.in b/data/org.gnome.shell.gschema.xml.in.in
index 12b76c9..c42a9f7 100644
--- a/data/org.gnome.shell.gschema.xml.in.in
+++ b/data/org.gnome.shell.gschema.xml.in.in
@@ -72,6 +72,16 @@
         This key sets the default state of the checkbox.
       </_description>
     </key>
+    <key name="had-bluetooth-devices-setup" type="b">
+      <default>false</default>
+      <_summary>Whether the default Bluetooth adapter had set up devices associated to it</_summary>
+      <_description>
+        The shell will only show a Bluetooth menu item if a Bluetooth
+        adapter is powered, or if there were devices set up associated
+        with the default adapter. This will be reset if the default
+        adapter is ever seen not to have devices associated to it.
+      </_description>
+    </key>
     <child name="calendar" schema="org.gnome.shell.calendar"/>
     <child name="keybindings" schema="org.gnome.shell.keybindings"/>
     <child name="keyboard" schema="org.gnome.shell.keyboard"/>
diff --git a/js/ui/status/bluetooth.js b/js/ui/status/bluetooth.js
index 8c9afcf..d689e54 100644
--- a/js/ui/status/bluetooth.js
+++ b/js/ui/status/bluetooth.js
@@ -23,6 +23,8 @@ const RfkillManagerInterface = '<node> \
 
 const RfkillManagerProxy = Gio.DBusProxy.makeProxyWrapper(RfkillManagerInterface);
 
+const HAD_BLUETOOTH_DEVICES_SETUP = 'had-bluetooth-devices-setup';
+
 const Indicator = new Lang.Class({
     Name: 'BTIndicator',
     Extends: PanelMenu.SystemIndicator,
@@ -32,6 +34,7 @@ const Indicator = new Lang.Class({
 
         this._indicator = this._addIndicator();
         this._indicator.icon_name = 'bluetooth-active-symbolic';
+        this._hadSetupDevices = global.settings.get_boolean(HAD_BLUETOOTH_DEVICES_SETUP);
 
         this._proxy = new RfkillManagerProxy(Gio.DBus.session, BUS_NAME, OBJECT_PATH,
                                              Lang.bind(this, function(proxy, error) {
@@ -44,13 +47,15 @@ const Indicator = new Lang.Class({
                                              }));
         this._proxy.connect('g-properties-changed', Lang.bind(this, this._sync));
 
-        // The Bluetooth menu only appears when Bluetooth is in use,
-        // so just statically build it with a "Turn Off" menu item.
-        this._item = new PopupMenu.PopupSubMenuMenuItem('', true);
+        this._item = new PopupMenu.PopupSubMenuMenuItem(_("Bluetooth"), true);
         this._item.icon.icon_name = 'bluetooth-active-symbolic';
-        this._item.menu.addAction(_("Turn Off"), Lang.bind(this, function() {
-            this._proxy.BluetoothAirplaneMode = true;
+
+        this._toggleItem = new PopupMenu.PopupMenuItem('');
+        this._toggleItem.connect('activate', Lang.bind(this, function() {
+            this._proxy.BluetoothAirplaneMode = !this._proxy.BluetoothAirplaneMode;
         }));
+        this._item.menu.addMenuItem(this._toggleItem);
+
         this._item.menu.addSettingsAction(_("Bluetooth Settings"), 'gnome-bluetooth-panel.desktop');
         this.menu.addMenuItem(this._item);
 
@@ -68,42 +73,75 @@ const Indicator = new Lang.Class({
         while (ret) {
             let isDefault = this._model.get_value(iter,
                                                   GnomeBluetooth.Column.DEFAULT);
-            if (isDefault)
+            let isPowered = this._model.get_value(iter,
+                                                  GnomeBluetooth.Column.POWERED);
+            if (isDefault && isPowered)
                 return iter;
             ret = this._model.iter_next(iter);
         }
         return null;
     },
 
-    _getNConnectedDevices: function() {
+    // nDevices is the number of devices setup for the current default
+    // adapter if one exists and is powered. If unpowered or unavailable,
+    // nDevice is "1" if it had setup devices associated to it the last
+    // time it was seen, and "-1" if not.
+    //
+    // nConnectedDevices is the number of devices connected to the default
+    // adapter if one exists and is powered, or -1 if it's not available.
+    _getNDevices: function() {
         let adapter = this._getDefaultAdapter();
         if (!adapter)
-            return 0;
+            return [ this._hadSetupDevices ? 1 : -1, -1 ];
 
+        let nConnectedDevices = 0;
         let nDevices = 0;
         let [ret, iter] = this._model.iter_children(adapter);
         while (ret) {
             let isConnected = this._model.get_value(iter,
                                                     GnomeBluetooth.Column.CONNECTED);
             if (isConnected)
+                nConnectedDevices++;
+
+            let isPaired = this._model.get_value(iter,
+                                                 GnomeBluetooth.Column.PAIRED);
+            let isTrusted = this._model.get_value(iter,
+                                                  GnomeBluetooth.Column.TRUSTED);
+            if (isPaired || isTrusted)
                 nDevices++;
             ret = this._model.iter_next(iter);
         }
-        return nDevices;
+
+        if (this._hadSetupDevices != (nDevices > 0)) {
+            this._hadSetupDevices = !this._hadSetupDevices;
+            global.settings.set_boolean(HAD_BLUETOOTH_DEVICES_SETUP, this._hadSetupDevices);
+        }
+
+        return [ nDevices, nConnectedDevices];
     },
 
     _sync: function() {
-        let nDevices = this._getNConnectedDevices();
+        let [ nDevices, nConnectedDevices ] = this._getNDevices();
         let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
 
         this.menu.setSensitive(sensitive);
-        this._indicator.visible = nDevices > 0;
-        this._item.actor.visible = this._proxy.BluetoothHasAirplaneMode && 
!this._proxy.BluetoothAirplaneMode;
+        this._indicator.visible = nConnectedDevices > 0;
 
+        // Remember if there were setup devices and show the menu
+        // if we've seen setup devices and we're not hard blocked
         if (nDevices > 0)
+            this._item.actor.visible = !this._proxy.BluetoothHardwareAirplaneMode;
+        else
+            this._item.actor.visible = this._proxy.BluetoothHasAirplaneMode && 
!this._proxy.BluetoothAirplaneMode;
+
+        if (nConnectedDevices > 0)
             /* Translators: this is the number of connected bluetooth devices */
-            this._item.label.text = ngettext("%d Connected", "%d Connected", nDevices).format(nDevices);
+            this._item.label.text = ngettext("%d Connected", "%d Connected", 
nConnectedDevices).format(nConnectedDevices);
+        else if (nConnectedDevices == -1)
+            this._item.label.text = _("Off");
         else
             this._item.label.text = _("Not In Use");
+
+        this._toggleItem.label.text = this._proxy.BluetoothAirplaneMode ? _("Turn On") : _("Turn Off");
     },
 });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]