[gnome-shell] NetworkMenu: keep wirelesss networks in predictable order
- From: Giovanni Campagna <gcampagna src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] NetworkMenu: keep wirelesss networks in predictable order
- Date: Tue, 26 Apr 2011 12:46:52 +0000 (UTC)
commit d0780d16224d7bb2ad183542337c48324fdd2185
Author: Giovanni Campagna <gcampagna src gnome org>
Date: Wed Apr 6 18:11:23 2011 +0200
NetworkMenu: keep wirelesss networks in predictable order
Adds a function that compares wireless networks and keeps them sorted
at all times. Order is: first already configured connections, then
first secure networks, then alphabtic. Also, the appearance of a new access
point no longer causes the whole menu to be rebuilt (but it still linear
searches for the position, I guess that could be skipped), which caused
the addition of more code for tracking the active access point.
https://bugzilla.gnome.org/show_bug.cgi?id=646580
js/ui/status/network.js | 207 ++++++++++++++++++++++++++++++++--------------
1 files changed, 144 insertions(+), 63 deletions(-)
---
diff --git a/js/ui/status/network.js b/js/ui/status/network.js
index 6fa5642..49cb3f0 100644
--- a/js/ui/status/network.js
+++ b/js/ui/status/network.js
@@ -42,6 +42,10 @@ const NM80211Mode = NetworkManager['80211Mode'];
const NM80211ApFlags = NetworkManager['80211ApFlags'];
const NM80211ApSecurityFlags = NetworkManager['80211ApSecurityFlags'];
+// number of wireless networks that should be visible
+// (the remaining are placed into More...)
+const NUM_VISIBLE_NETWORKS = 5;
+
function macToArray(string) {
return string.split(':').map(function(el) {
return parseInt(el, 16);
@@ -1036,6 +1040,7 @@ NMDeviceWireless.prototype = {
item: null,
accessPoints: [ ap ]
};
+ obj.ssidText = NetworkManager.utils_ssid_to_utf8(obj.ssid);
this._networks.push(obj);
}
@@ -1048,6 +1053,14 @@ NMDeviceWireless.prototype = {
}
}
}
+ if (this.device.active_access_point) {
+ this._activeNetwork = this._networks[this._findNetwork(this.device.active_access_point)];
+ } else {
+ this._activeNetwork = null;
+ }
+ this._networks.sort(this._networkSortFunction);
+
+ this._apChangedId = device.connect('notify::active-access-point', Lang.bind(this, this._activeApChanged));
this._apAddedId = device.connect('access-point-added', Lang.bind(this, this._accessPointAdded));
this._apRemovedId = device.connect('access-point-removed', Lang.bind(this, this._accessPointRemoved));
@@ -1055,8 +1068,13 @@ NMDeviceWireless.prototype = {
},
destroy: function() {
- if (this._apAddedId) {
+ if (this._apChangedId) {
// see above for this HACK
+ GObject.Object.prototype.disconnect.call(this.device, this._apChangedId);
+ this._apChangedId = 0;
+ }
+
+ if (this._apAddedId) {
GObject.Object.prototype.disconnect.call(this.device, this._apAddedId);
this._apAddedId = 0;
}
@@ -1122,6 +1140,19 @@ NMDeviceWireless.prototype = {
}
},
+ _activeApChanged: function() {
+ this._activeNetwork = null;
+
+ let activeAp = this.device.active_access_point;
+
+ if (activeAp) {
+ let pos = this._findNetwork(activeAp);
+ this._activeNetwork = this._networks[pos];
+ }
+
+ // we don't refresh the view here, setActiveConnection will
+ },
+
_getApSecurityType: function(accessPoint) {
if (accessPoint._secType)
return accessPoint._secType;
@@ -1151,6 +1182,32 @@ NMDeviceWireless.prototype = {
return type;
},
+ _networkSortFunction: function(one, two) {
+ let oneHasConnection = one.connections.length != 0;
+ let twoHasConnection = two.connections.length != 0;
+
+ // place known connections first
+ // (-1 = good order, 1 = wrong order)
+ if (oneHasConnection && !twoHasConnection)
+ return -1;
+ else if (!oneHasConnection && twoHasConnection)
+ return 1;
+
+ let oneHasSecurity = one.security != NMAccessPointSecurity.NONE;
+ let twoHasSecurity = two.security != NMAccessPointSecurity.NONE;
+
+ // place secure connections first
+ // (we treat WEP/WPA/WPA2 the same as there is no way to
+ // take them apart from the UI)
+ if (oneHasSecurity && !twoHasSecurity)
+ return -1;
+ else if (!oneHasSecurity && twoHasSecurity)
+ return 1;
+
+ // sort alphabetically
+ return GLib.utf8_collate(one.ssidText, two.ssidText);
+ },
+
_networkCompare: function(network, accessPoint) {
if (!ssidCompare(network.ssid, accessPoint.get_ssid()))
return false;
@@ -1173,6 +1230,8 @@ NMDeviceWireless.prototype = {
_accessPointAdded: function(device, accessPoint) {
let pos = this._findNetwork(accessPoint);
let apObj;
+ let needsupdate = false;
+
if (pos != -1) {
apObj = this._networks[pos];
if (apObj.accessPoints.indexOf(accessPoint) != -1) {
@@ -1181,6 +1240,8 @@ NMDeviceWireless.prototype = {
}
apObj.accessPoints.push(accessPoint);
+ if (apObj.item)
+ apObj.item.updateAccessPoints(apObj.accessPoints);
} else {
apObj = { ssid: accessPoint.get_ssid(),
mode: accessPoint.mode,
@@ -1189,7 +1250,8 @@ NMDeviceWireless.prototype = {
item: null,
accessPoints: [ accessPoint ]
};
- this._networks.push(apObj);
+ apObj.ssidText = NetworkManager.utils_ssid_to_utf8(apObj.ssid);
+ needsupdate = true;
}
// check if this enables new connections for this group
@@ -1198,12 +1260,44 @@ NMDeviceWireless.prototype = {
if (this._connectionValidForAP(connection, accessPoint) &&
apObj.connections.indexOf(connection) == -1) {
apObj.connections.push(connection);
+
+ // this potentially changes the order
+ needsupdate = true;
}
}
- // update everything
- this._clearSection();
- this._createSection();
+ if (needsupdate) {
+ if (apObj.item)
+ apObj.item.destroy();
+
+ if (pos != -1)
+ this._networks.splice(pos, 1);
+
+ if (this._networks.length == 0) {
+ // only network in the list
+ this._networks.push(apObj);
+ this._clearSection();
+ this._createSection();
+ return;
+ }
+
+ // skip networks that should appear earlier
+ let menuPos = 0;
+ for (pos = 0;
+ pos < this._networks.length &&
+ this._networkSortFunction(this._networks[i], apObj) < 0; ++pos) {
+ if (this._networks[pos] != this._activeNetwork)
+ menuPos++;
+ }
+
+ // (re-)add the network
+ this._networks.splice(pos, 0, apObj);
+
+ if (this._shouldShowConnectionList()) {
+ menuPos += (this._activeConnectionItem ? 1 : 0);
+ this._createNetworkItem(apObj, menuPos);
+ }
+ }
},
_accessPointRemoved: function(device, accessPoint) {
@@ -1315,6 +1409,12 @@ NMDeviceWireless.prototype = {
// remove the connection from the access point group
connections.splice(k);
anyauto = connections.length == 0;
+
+ if (anyauto) {
+ // this potentially changes the sorting order
+ forceupdate = true;
+ break;
+ }
if (apObj.item) {
if (apObj.item instanceof PopupMenu.PopupSubMenuMenuItem) {
let items = apObj.item.menu.getMenuItems();
@@ -1340,6 +1440,7 @@ NMDeviceWireless.prototype = {
}
if (forceupdate || anyauto) {
+ this._networks.sort(this._networkSortFunction);
this._clearSection();
this._createSection();
}
@@ -1355,42 +1456,24 @@ NMDeviceWireless.prototype = {
this._connections.push(obj);
// find an appropriate access point
- let any = false, forceupdate = false;
+ let forceupdate = false;
for (let i = 0; i < this._networks.length; i++) {
let apObj = this._networks[i];
// Check if connection is valid for any of these access points
- let any = false;
for (let k = 0; k < apObj.accessPoints.length; k++) {
let ap = apObj.accessPoints[k];
if (this._connectionValidForAP(connection, ap)) {
apObj.connections.push(connection);
- any = true;
+ // this potentially changes the sorting order
+ forceupdate = true;
break;
}
}
-
- if (any && this._shouldShowConnectionList()) {
- // we need to show this connection
- if (apObj.item && apObj.item.menu) {
- // We're already showing the submenu for this access point
- apObj.item.menu.addMenuItem(this._createAPItem(connection, apObj, true));
- } else {
- if (apObj.item)
- apObj.item.destroy();
- if (apObj.connections.length == 1) {
- apObj.item = this._createAPItem(connection, apObj, false);
- this.section.addMenuItem(apObj.item);
- } else {
- apObj.item = null;
- // we need to force an update to create the submenu
- forceupdate = true;
- }
- }
- }
}
if (forceupdate) {
+ this._networks.sort(this._networkSortFunction);
this._clearSection();
this._createSection();
}
@@ -1473,6 +1556,37 @@ NMDeviceWireless.prototype = {
return connection;
},
+ _createNetworkItem: function(apObj, position) {
+ if(apObj.connections.length > 0) {
+ if (apObj.connections.length == 1)
+ apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
+ else {
+ let title = apObj.ssidText;
+ apObj.item = new PopupMenu.PopupSubMenuMenuItem(title);
+ apObj.item._apObj = apObj;
+ for (let i = 0; i < apObj.connections.length; i++)
+ apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
+ }
+ } else {
+ apObj.item = new NMNetworkMenuItem(apObj.accessPoints);
+ apObj.item._apObj = apObj;
+ apObj.item.connect('activate', Lang.bind(this, function() {
+ let connection = this._createAutomaticConnection(apObj);
+ let accessPoints = sortAccessPoints(apObj.accessPoints);
+ this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null)
+ }));
+ }
+ if (position < NUM_VISIBLE_NETWORKS)
+ this.section.addMenuItem(apObj.item);
+ else {
+ if (!this._overflowItem) {
+ this._overflowItem = new PopupMenu.PopupSubMenuMenuItem(_("More..."));
+ this.section.addMenuItem(this._overflowItem);
+ }
+ this._overflowItem.menu.addMenuItem(apObj.item, position - NUM_VISIBLE_NETWORKS);
+ }
+ },
+
_createSection: function() {
if (!this._shouldShowConnectionList())
return;
@@ -1482,47 +1596,14 @@ NMDeviceWireless.prototype = {
this.section.addMenuItem(this._activeConnectionItem);
}
- let activeAp = this.device.active_access_point;
- let activeApSsid = activeAp ? activeAp.get_ssid() : null;
-
- // we want five access points in the menu, including the active one
- let numItems = this._activeConnection ? 4 : 5;
+ let activeOffset = this._activeConnectionItem ? 1 : 0;
for(let j = 0; j < this._networks.length; j++) {
let apObj = this._networks[j];
- if(activeAp && ssidCompare(apObj.ssid, activeApSsid))
+ if (apObj == this._activeNetwork)
continue;
- let menuItem;
- if(apObj.connections.length > 0) {
- if (apObj.connections.length == 1)
- apObj.item = this._createAPItem(apObj.connections[0], apObj, false);
- else {
- let title = NetworkManager.utils_ssid_to_utf8(apObj.ssid) || _("<unknown>");
- apObj.item = new PopupMenu.PopupSubMenuMenuItem(title);
- apObj.item._apObj = apObj;
- for (let i = 0; i < apObj.connections.length; i++)
- apObj.item.menu.addMenuItem(this._createAPItem(apObj.connections[i], apObj, true));
- }
- } else {
- apObj.item = new NMNetworkMenuItem(apObj.accessPoints);
- apObj.item._apObj = apObj;
- apObj.item.connect('activate', Lang.bind(this, function() {
- let connection = this._createAutomaticConnection(apObj);
- let accessPoints = sortAccessPoints(apObj.accessPoints);
- this._client.add_and_activate_connection(connection, this.device, accessPoints[0].dbus_path, null)
- }));
- }
-
- if (j < numItems)
- this.section.addMenuItem(apObj.item);
- else {
- if (!this._overflowItem) {
- this._overflowItem = new PopupMenu.PopupSubMenuMenuItem(_("More..."));
- this.section.addMenuItem(this._overflowItem);
- }
- this._overflowItem.menu.addMenuItem(apObj.item);
- }
+ this._createNetworkItem(apObj, j + activeOffset);
}
},
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]