From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pigeon.gentoo.org ([208.92.234.80] helo=lists.gentoo.org) by finch.gentoo.org with esmtp (Exim 4.60) (envelope-from ) id 1PsFtS-0006KA-PB for garchives@archives.gentoo.org; Wed, 23 Feb 2011 14:40:45 +0000 Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 81E50E0630; Wed, 23 Feb 2011 14:40:20 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) by pigeon.gentoo.org (Postfix) with ESMTP id DDEFCE0616 for ; Wed, 23 Feb 2011 14:40:19 +0000 (UTC) Received: from pelican.gentoo.org (unknown [66.219.59.40]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id B9E131B41CA for ; Wed, 23 Feb 2011 14:40:18 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by pelican.gentoo.org (Postfix) with ESMTP id 252988006E for ; Wed, 23 Feb 2011 14:40:18 +0000 (UTC) From: "Nirbheek Chauhan" To: gentoo-commits@lists.gentoo.org Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Nirbheek Chauhan" Message-ID: Subject: [gentoo-commits] proj/gnome:master commit in: gnome-base/gnome-shell/, net-misc/networkmanager/, ... X-VCS-Repository: proj/gnome X-VCS-Files: gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet-1.0.patch gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet.patch gnome-base/gnome-shell/gnome-shell-9999.ebuild net-misc/networkmanager/files/networkmanager-more-gi-annotations.patch net-misc/networkmanager/networkmanager-9999.ebuild X-VCS-Directories: gnome-base/gnome-shell/ net-misc/networkmanager/ net-misc/networkmanager/files/ gnome-base/gnome-shell/files/ X-VCS-Committer: nirbheek X-VCS-Committer-Name: Nirbheek Chauhan X-VCS-Revision: c4b935e51b5eb23600ff21c9407feb07f5ed06b1 Date: Wed, 23 Feb 2011 14:40:18 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: quoted-printable X-Archives-Salt: X-Archives-Hash: ebd3e6d67e614f9ee1b1aef25e2cf968 commit: c4b935e51b5eb23600ff21c9407feb07f5ed06b1 Author: Nirbheek Chauhan gentoo org> AuthorDate: Wed Feb 23 13:48:27 2011 +0000 Commit: Nirbheek Chauhan gentoo org> CommitDate: Wed Feb 23 14:09:12 2011 +0000 URL: http://git.overlays.gentoo.org/gitweb/?p=3Dproj/gnome.git;a=3D= commit;h=3Dc4b935e5 gnome-base/gnome-shell: update nm-applet patch, update networkmanager-999= 9 * New patch added to NM, needed for gnome-shell now --- ...> gnome-shell-experimental-nm-applet-1.0.patch} | 1121 +++++++++++---= ------ gnome-base/gnome-shell/gnome-shell-9999.ebuild | 2 +- .../files/networkmanager-more-gi-annotations.patch | 43 + net-misc/networkmanager/networkmanager-9999.ebuild | 3 + 4 files changed, 663 insertions(+), 506 deletions(-) diff --git a/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-app= let.patch b/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-appl= et-1.0.patch similarity index 63% rename from gnome-base/gnome-shell/files/gnome-shell-experimental-nm-appl= et.patch rename to gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet= -1.0.patch index 64aa99c..15a560b 100644 --- a/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet.pat= ch +++ b/gnome-base/gnome-shell/files/gnome-shell-experimental-nm-applet-1.0= .patch @@ -1,4 +1,4 @@ -From 11400d81fd9775bac7db3e49e620004bb9d6fab5 Mon Sep 17 00:00:00 2001 +From f8a4fa0646aa4ab620331c0bbcae4334173b614d Mon Sep 17 00:00:00 2001 From: Giovanni Campagna Date: Tue, 25 Jan 2011 22:08:12 +0100 Subject: [PATCH] Status area: add NetworkManager indicator @@ -10,15 +10,35 @@ dialogs. =20 https://bugzilla.gnome.org/show_bug.cgi?id=3D621707 --- + data/theme/gnome-shell.css | 8 + js/Makefile.am | 2 + - js/misc/modemManager.js | 93 +++ + js/misc/modemManager.js | 103 +++ js/ui/panel.js | 3 +- - js/ui/status/network.js | 1656 ++++++++++++++++++++++++++++++++= +++++++ - tools/build/gnome-shell.modules | 19 + - 5 files changed, 1772 insertions(+), 1 deletions(-) + js/ui/status/network.js | 1754 ++++++++++++++++++++++++++++++++= +++++++ + tools/build/gnome-shell.modules | 17 + + 6 files changed, 1886 insertions(+), 1 deletions(-) create mode 100644 js/misc/modemManager.js create mode 100644 js/ui/status/network.js =20 +diff --git a/data/theme/gnome-shell.css b/data/theme/gnome-shell.css +index 1da6619..8f0fb52 100644 +--- a/data/theme/gnome-shell.css ++++ b/data/theme/gnome-shell.css +@@ -154,6 +154,14 @@ StTooltip StLabel { + spacing: .5em; + } +=20 ++.popup-inactive-menu-item { ++ font-style: italic; ++} ++ ++.popup-subtitle-menu-item { ++ font-weight: bold; ++} ++ + .popup-menu-icon { + icon-size: 1.14em; + } diff --git a/js/Makefile.am b/js/Makefile.am index e4a4145..53f80d4 100644 --- a/js/Makefile.am @@ -41,10 +61,10 @@ index e4a4145..53f80d4 100644 ui/status/bluetooth.js \ diff --git a/js/misc/modemManager.js b/js/misc/modemManager.js new file mode 100644 -index 0000000..104262b +index 0000000..b368511 --- /dev/null +++ b/js/misc/modemManager.js -@@ -0,0 +1,93 @@ +@@ -0,0 +1,103 @@ +// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- +const DBus =3D imports.dbus; +const Lang =3D imports.lang; @@ -56,15 +76,15 @@ index 0000000..104262b +const ModemGsmNetworkInterface =3D { + name: 'org.freedesktop.ModemManager.Modem.Gsm.Network', + methods: [ -+ { name: 'GetRegistrationInfo', inSignature: '', outSignature: 'uss' }, -+ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' }, ++ { name: 'GetRegistrationInfo', inSignature: '', outSignature: '= uss' }, ++ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' = }, + ], + properties: [ -+ { name: 'AccessTechnology', signature: 'u', access: 'read' } ++ { name: 'AccessTechnology', signature: 'u', access: 'read' } + ], + signals: [ -+ { name: 'SignalQuality', inSignature: 'u' }, -+ { name: 'RegistrationInfo', inSignature: 'uss' } ++ { name: 'SignalQuality', inSignature: 'u' }, ++ { name: 'RegistrationInfo', inSignature: 'uss' } + ] +}; +const ModemGsmNetworkProxy =3D DBus.makeProxyClass(ModemGsmNetworkInter= face); @@ -72,11 +92,11 @@ index 0000000..104262b +const ModemCdmaInterface =3D { + name: 'org.freedesktop.ModemManager.Modem.Cdma', + methods: [ -+ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' }, -+ { name: 'GetServingSystem', inSignature: '', outSignature: 'usu' }, ++ { name: 'GetSignalQuality', inSignature: '', outSignature: 'u' = }, ++ { name: 'GetServingSystem', inSignature: '', outSignature: 'usu= ' }, + ], + signals: [ -+ { name: 'SignalQuality', inSignature: 'u' } ++ { name: 'SignalQuality', inSignature: 'u' } + ] +}; +const ModemCdmaProxy =3D DBus.makeProxyClass(ModemCdmaInterface); @@ -88,29 +108,37 @@ index 0000000..104262b + +ModemGsm.prototype =3D { + _init: function(path) { -+ this._proxy =3D new ModemGsmNetworkProxy(DBus.system, 'org.freedesktop= .ModemManager', path); -+ -+ this.signal_quality =3D 0; -+ this.operator_name =3D null; -+ this._proxy.connect('SignalQuality', Lang.bind(this, this._qualityChan= ged)); -+ this._proxy.connect('RegistrationInfo', Lang.bind(this, this._registra= tionInfoChanged)); -+ this._proxy.GetRegistrationInfoRemote(Lang.bind(this, this._registrati= onInfoChanged)); -+ this._proxy.GetSignalQualityRemote(Lang.bind(this, this._qualityChange= d)); -+ }, ++ this._proxy =3D new ModemGsmNetworkProxy(DBus.system, 'org.free= desktop.ModemManager', path); + -+ _registrationInfoChanged: function(status, code, name) { -+ if (name.length > 0) -+ this.operator_name =3D name; -+ else -+ this.operator_name =3D null; -+ this.emit('notify::operator-name'); -+ }, ++ this.signal_quality =3D 0; ++ this.operator_name =3D null; + -+ _qualityChanged: function(quality) { -+ this.signal_quality =3D quality; -+ this.emit('notify::signal-quality'); ++ // Code is duplicated because the function have different signa= tures ++ this._proxy.connect('SignalQuality', Lang.bind(this, function(p= roxy, quality) { ++ this.signal_quality =3D quality; ++ this.emit('notify::signal-quality'); ++ })); ++ this._proxy.connect('RegistrationInfo', Lang.bind(this, functio= n(proxy, status, code, name) { ++ if (name.length > 0) ++ this.operator_name =3D name; ++ else ++ this.operator_name =3D null; ++ this.emit('notify::operator-name'); ++ })); ++ this._proxy.GetRegistrationInfoRemote(Lang.bind(this, function(= status, code, name) { ++ if (name.length > 0) ++ this.operator_name =3D name; ++ else ++ this.operator_name =3D null; ++ this.emit('notify::operator-name'); ++ })); ++ this._proxy.GetSignalQualityRemote(Lang.bind(this, function(qua= lity) { ++ this.signal_quality =3D quality; ++ this.emit('notify::signal-quality'); ++ })); + } +} ++Signals.addSignalMethods(ModemGsm.prototype); + +function ModemCdma() { + this._init.apply(this, arguments); @@ -122,28 +150,29 @@ index 0000000..104262b + + this.signal_quality =3D 0; + this.operator_name =3D null; -+ this._proxy.connect('SignalQuality', Lang.bind(this, this._qual= ityChanged)); -+ this._proxy.GetSignalQualityRemote(Lang.bind(this, this._qualit= yChanged)); -+ this._proxy.GetServingSystemRemote(Lang.bind(this, function(sta= tus, name, code) { ++ this._proxy.connect('SignalQuality', Lang.bind(this, function(q= uality) { ++ this.signal_quality =3D quality; ++ this.emit('notify::signal-quality'); ++ })); ++ this._proxy.GetSignalQualityRemote(Lang.bind(this, function(pro= xy, quality) { ++ this.signal_quality =3D quality; ++ this.emit('notify::signal-quality'); ++ })); ++ this._proxy.GetServingSystemRemote(Lang.bind(this, function(pro= xy, status, name, code) { + if (name.length > 0) + this.operator_name =3D name; + else + this.operator_name =3D null; + this.emit('notify::operator-name'); + })); -+ }, -+ -+ _qualityChanged: function(quality) { -+ this.signal_quality =3D quality; -+ this.emit('notify::signal-quality'); + } +}; -\ No newline at end of file ++Signals.addSignalMethods(ModemCdma.prototype); diff --git a/js/ui/panel.js b/js/ui/panel.js -index f1a5e90..46355c4 100644 +index 1c23ae8..ab7a656 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js -@@ -37,7 +37,8 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION =3D { +@@ -38,7 +38,8 @@ const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION =3D { 'a11y': imports.ui.status.accessibility.ATIndicator, 'volume': imports.ui.status.volume.Indicator, 'battery': imports.ui.status.power.Indicator, @@ -155,10 +184,10 @@ index f1a5e90..46355c4 100644 if (Config.HAVE_BLUETOOTH) diff --git a/js/ui/status/network.js b/js/ui/status/network.js new file mode 100644 -index 0000000..a0cd576 +index 0000000..04e9c87 --- /dev/null +++ b/js/ui/status/network.js -@@ -0,0 +1,1656 @@ +@@ -0,0 +1,1754 @@ +// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- +const ByteArray =3D imports.byteArray; +const DBus =3D imports.dbus; @@ -181,6 +210,13 @@ index 0000000..a0cd576 +const Gettext =3D imports.gettext.domain('gnome-shell'); +const _ =3D Gettext.gettext; + ++const NMConnectionCategory =3D { ++ WIRED: 'wired', ++ WIRELESS: 'wireless', ++ WWAN: 'wwan', ++ VPN: 'vpn' ++}; ++ +const NMAppletIface =3D { + name: 'org.freedesktop.NetworkManager.Applet', + methods: [ @@ -191,16 +227,9 @@ index 0000000..a0cd576 +const NMAppletProxy =3D DBus.makeProxyClass(NMAppletIface); + +function macToArray(string) { -+ const regexp =3D /([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2}= ):([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2}):([A-Fa-f0-9]{2})/; -+ let match =3D regexp.exec(string); -+ if (match) { -+ // remove the global match -+ match.splice(0, 1); -+ return match.map(function(el) { -+ return parseInt(el, 16); -+ }); -+ } else -+ return new Array(6); ++ return string.split(':').map(function(el) { ++ return parseInt(el, 16); ++ }); +} + +function macCompare(one, two) { @@ -211,75 +240,101 @@ index 0000000..a0cd576 + return true; +} + -+/** -+ * makeClassKey: -+ * @object: any Object -+ * -+ * Returns a string which can be used to identify @object's [[Class]] -+ */ -+function makeClassKey(object) { -+ return Object.prototype.toString.call(object); -+} -+ -+function addChipersFromFlags(settings, flags) { -+ // helper copied from nm-applet -+ -+ if (flags & NetworkManager['802_11_AP_SEC_PAIR_TKIP']) -+ settings.add_pairwise('tkip'); -+ if (flags & NetworkManager['802_11_AP_SEC_PAIR_CCMP']) -+ settings.add_pairwise('ccmp'); -+ -+ if (flags & NetworkManager['802_11_AP_SEC_GROUP_WEP40']) -+ settings.add_group('wep40'); -+ if (flags & NetworkManager['802_11_AP_SEC_GROUP_WEP104']) -+ settings.add_group('wep104'); -+ if (flags & NetworkManager['802_11_AP_SEC_GROUP_TKIP']) -+ settings.add_group('tkip'); -+ if (flags & NetworkManager['802_11_AP_SEC_GROUP_CCMP']) -+ settings.add_group('ccmp'); ++function ssidCompare(one, two) { ++ if (one.length !=3D two.length) ++ return false; ++ for (let i =3D 0; i < one.length; i++) { ++ if (one[i] !=3D two[i]) ++ return false; ++ } ++ return true; +} + -+// shared between NMAccessPointMenuItem and NMDeviceWWAN ++// shared between NMNetworkMenuItem and NMDeviceWWAN +function signalToIcon(value) { -+ if(value > 80) ++ if (value > 80) + return 'excellent'; -+ if(value > 55) ++ if (value > 55) + return 'good'; -+ if(value > 30) ++ if (value > 30) + return 'ok'; -+ if(value > 5) ++ if (value > 5) + return 'weak'; + return 'none'; +} + -+function NMAccessPointMenuItem() { ++// shared between NMNetworkMenuItem and NMDeviceWireless ++function sortAccessPoints(accessPoints) { ++ return accessPoints.sort(function (one, two) { ++ return two.strength - one.strength; ++ }); ++} ++ ++function NMNetworkMenuItem() { + this._init.apply(this, arguments); +} + -+NMAccessPointMenuItem.prototype =3D { ++NMNetworkMenuItem.prototype =3D { + __proto__: PopupMenu.PopupImageMenuItem.prototype, + -+ _init: function(accessPoint, title, params) { -+ this._accessPoint =3D accessPoint; -+ this._title =3D title || String(accessPoint.get_ssid()); ++ _init: function(accessPoints, title, params) { ++ accessPoints =3D sortAccessPoints(accessPoints); ++ this.bestAP =3D accessPoints[0]; ++ ++ let ssid =3D this.bestAP.get_ssid(); ++ title =3D title || NetworkManager.utils_ssid_to_utf8(ssid, ssid= .length) || _(""); ++ ++ PopupMenu.PopupImageMenuItem.prototype._init.call(this, title, = this._getIcon(), params); ++ ++ this._accessPoints =3D [ ]; ++ for (let i =3D 0; i < accessPoints.length; i++) { ++ let ap =3D accessPoints[i]; ++ // need a wrapper object here, because the access points ca= n be shared ++ // between many NMNetworkMenuItems ++ let apObj =3D { ++ ap: ap, ++ updateId: ap.connect('notify::strength', Lang.bind(this= , this._updated)) ++ }; ++ this._accessPoints.push(apObj); ++ } ++ }, + -+ PopupMenu.PopupImageMenuItem.prototype._init.call(this, this._t= itle, this._get_icon(), params); ++ _updated: function(ap, strength) { ++ if (strength > this._bestAP.strength) ++ this.bestAP =3D ap; + -+ this._updateId =3D this._accessPoint.connect('notify::strength'= , Lang.bind(this, this._updated)); ++ this.setIcon(this._getIcon()); + }, + -+ _updated: function() { -+ this.setIcon(this._get_icon()); ++ _getIcon: function() { ++ return 'network-wireless-signal-' + signalToIcon(this.bestAP.st= rength); + }, + -+ _get_icon: function() { -+ return 'network-wireless-signal-' + signalToIcon(this._accessPo= int.strength); ++ updateAccessPoints: function(accessPoints) { ++ for (let i =3D 0; i < this._accessPoints.length; i++) { ++ let apObj =3D this._accessPoints[i]; ++ apObj.ap.disconnect(apObj.updateId); ++ apObj.updateId =3D 0; ++ } ++ ++ accessPoints =3D sortAccessPoints(accessPoints); ++ this.bestAP =3D accessPoints[0]; ++ this._accessPoints =3D [ ]; ++ for (let i =3D 0; i < accessPoints; i++) { ++ let ap =3D accessPoints[i]; ++ let apObj =3D { ++ ap: ap, ++ updateId: ap.connect('notify::strength', Lang.bind(this= , this._updated)) ++ }; ++ this._accessPoints.push(apObj); ++ } + }, + + destroy: function() { -+ if (this._updateId) { -+ this._accessPoint.disconnect(this._updateId); -+ this._updateId =3D 0; ++ for (let i =3D 0; i < this._accessPoints.length; i++) { ++ let apObj =3D this._accessPoints[i]; ++ apObj.ap.disconnect(apObj.updateId); ++ apObj.updateId =3D 0; + } + + PopupMenu.PopupImageMenuItem.prototype.destroy.call(this); @@ -287,20 +342,20 @@ index 0000000..a0cd576 +}; + +function NMDevice() { -+ throw TypeError('Instantanting abstract class NMDevice'); ++ throw new TypeError('Instantanting abstract class NMDevice'); +} + +NMDevice.prototype =3D { + _init: function(client, device, connections, activeConnectionPositi= on) { -+ /* */ -+ this.client =3D client; + this.device =3D device; + if (device) { + this.device._delegate =3D this; + this.device.connect('state-changed', Lang.bind(this, this.d= eviceStateChanged)); + } + -+ this.connections =3D [ ]; ++ // protected ++ this._client =3D client; ++ this._connections =3D [ ]; + for (let i =3D 0; i < connections.length; i++) { + if (!connections[i]._uuid) + continue; @@ -312,42 +367,42 @@ index 0000000..a0cd576 + name: connections[i]._name, + uuid: connections[i]._uuid, + }; -+ this.connections.push(obj); ++ this._connections.push(obj); + } -+ this.activeConnection =3D null; -+ this.activeConnectionItem =3D null; -+ this.disconnectItem =3D null; -+ this.autoConnectionItem =3D null; -+ this.statusItem =3D null; ++ this._activeConnection =3D null; ++ this._activeConnectionItem =3D null; ++ this._disconnectItem =3D null; ++ this._autoConnectionItem =3D null; ++ this._statusItem =3D null; + -+ /* */ ++ // private + this._activeConnectionPosition =3D activeConnectionPosition || = 0; + -+ /* */ -+ this.titleItem =3D new PopupMenu.PopupMenuItem(this.device._des= cription, { reactive: false, style_class: 'popup-subtitle-menu-item' }); ++ if (this.device) ++ this.titleItem =3D new PopupMenu.PopupMenuItem(this.device.= _description, { reactive: false, style_class: 'popup-subtitle-menu-item' = }); + this.section =3D new PopupMenu.PopupMenuSection(); + -+ this.createSection(); ++ this._createSection(); + }, + + setActiveConnection: function(activeConnection) { -+ if (this.activeConnection && activeConnection =3D=3D this.activ= eConnection) ++ if (activeConnection =3D=3D this._activeConnection) + // nothing to do + return; + + // remove any UI -+ if (this.activeConnectionItem) { -+ this.activeConnectionItem.destroy(); -+ this.activeConnectionItem =3D null; ++ if (this._activeConnectionItem) { ++ this._activeConnectionItem.destroy(); ++ this._activeConnectionItem =3D null; + } + -+ if (this.disconnectItem) { -+ this.disconnectItem.destroy(); -+ this.disconnectItem =3D null; ++ if (this._disconnectItem) { ++ this._disconnectItem.destroy(); ++ this._disconnectItem =3D null; + } + -+ let previousActive =3D this.activeConnection; -+ this.activeConnection =3D=3D null; ++ let previousActive =3D this._activeConnection; ++ this._activeConnection =3D=3D null; + + if (previousActive && previousActive._connection) { + // add the connection back as a normal one, by removing and= adding it @@ -358,25 +413,25 @@ index 0000000..a0cd576 + if (activeConnection) { + if (activeConnection._connection) { + // remove the connection if it was already seen -+ let pos =3D this.findConnection(activeConnection._conne= ction._uuid); ++ let pos =3D this._findConnection(activeConnection._conn= ection._uuid); + if (pos !=3D -1) { -+ let obj =3D this.connections[pos]; ++ let obj =3D this._connections[pos]; + if (obj.item) + obj.item.destroy(); + obj.item =3D null; + } + } + -+ this.activeConnection =3D activeConnection; -+ this.createActiveConnectionItems(); -+ if (this.disconnectItem) -+ this.section.addMenuItem(this.disconnectItem, this._act= iveConnectionPosition); -+ this.section.addMenuItem(this.activeConnectionItem, this._a= ctiveConnectionPosition); ++ this._activeConnection =3D activeConnection; ++ this._createActiveConnectionItems(); ++ if (this._disconnectItem) ++ this.section.addMenuItem(this._disconnectItem, this._ac= tiveConnectionPosition); ++ this.section.addMenuItem(this._activeConnectionItem, this._= activeConnectionPosition); + } + }, + + addConnection: function(connection) { -+ if (this.findConnection(connection._uuid) !=3D -1) { ++ if (this._findConnection(connection._uuid) !=3D -1) { + log('Connection already added to menu, not adding again'); + return; + } @@ -387,157 +442,139 @@ index 0000000..a0cd576 + name: connection._name, + uuid: connection._uuid, + }; -+ this.connections.push(obj); ++ this._connections.push(obj); + + if (!this.device || + (this.device.state =3D=3D NetworkManager.DeviceState.DISCON= NECTED || + this.device.state =3D=3D NetworkManager.DeviceState.ACTIVA= TED)) { -+ // we need to show this connection -+ if (!this.hasAuto) { -+ // already showing the connection list -+ obj.item =3D this.createConnectionItem(obj); ++ // we're showing a connection list, so we need to append th= is one ++ if (this._connections.length > 1) { ++ // already showing real connections ++ obj.item =3D this._createConnectionItem(obj); + this.section.addMenuItem(obj.item); + } else { -+ // First connection in the list -+ this.clearSection(); -+ this.createSection(); ++ // first connection in the list, destroy the automatic = one ++ this._clearSection(); ++ this._createSection(); + } + } + }, + + removeConnection: function(connection, skipCreateAuto) { -+ if (!connection._uuid) ++ if (!connection._uuid) { ++ log('Cannot remove a connection without an UUID'); + return; -+ let pos =3D this.findConnection(connection._uuid); -+ if (pos =3D=3D -1) ++ } ++ let pos =3D this._findConnection(connection._uuid); ++ if (pos =3D=3D -1) { ++ log('Connection was never added, cannot remove'); + return; ++ } + -+ let obj =3D this.connections[pos]; ++ let obj =3D this._connections[pos]; + if (obj.item) + obj.item.destroy(); -+ this.connections.splice(pos, 1); ++ this._connections.splice(pos, 1); + -+ if (this.connections.length =3D=3D 0 && !skipCreateAuto) { ++ if (this._connections.length =3D=3D 0 && !skipCreateAuto) { + // We need to show the automatic connection again -+ this.clearSection(); -+ this.createSection(); ++ this._clearSection(); ++ this._createSection(); + } + }, + + connectionValid: function(connection) { -+ throw TypeError('Invoking pure virtual function NMDevice.connec= tionValid'); ++ throw new TypeError('Invoking pure virtual function NMDevice.co= nnectionValid'); + }, + -+ /* */ -+ createAutomaticConnection: function() { -+ throw TypeError('Invoking pure virtual function NMDevice.create= AutomaticConnection'); ++ // protected ++ _createAutomaticConnection: function() { ++ throw new TypeError('Invoking pure virtual function NMDevice.cr= eateAutomaticConnection'); + }, + -+ findConnection: function(uuid) { -+ for (let i =3D 0; i < this.connections.length; i++) { -+ let obj =3D this.connections[i]; ++ _findConnection: function(uuid) { ++ for (let i =3D 0; i < this._connections.length; i++) { ++ let obj =3D this._connections[i]; + if (obj.uuid =3D=3D uuid) + return i; + } + return -1; + }, + -+ clearSection: function() { ++ _clearSection: function() { + // Clear everything + this.section.removeAll(); -+ this.autoConnectionItem =3D null; -+ this.activeConnectionItem =3D null; -+ this.disconnectItem =3D null; -+ this.statusItem =3D null; -+ for (let i =3D 0; i < this.connections.length; i++) { -+ this.connections[i].item =3D null; ++ this._autoConnectionItem =3D null; ++ this._activeConnectionItem =3D null; ++ this._disconnectItem =3D null; ++ this._statusItem =3D null; ++ for (let i =3D 0; i < this._connections.length; i++) { ++ this._connections[i].item =3D null; + } + }, + -+ createSection: function() { ++ _createSection: function() { + let status; + if (!this.device || + (this.device.state =3D=3D NetworkManager.DeviceState.DISCON= NECTED || + this.device.state =3D=3D NetworkManager.DeviceState.ACTIVA= TED)) -+ this.createConnectionList(); ++ this._createConnectionList(); + else if (this.device.state !=3D NetworkManager.DeviceState.UNMA= NAGED) { -+ let title =3D this.getStatusLabel(); -+ this.statusItem =3D new PopupMenu.PopupMenuItem(title, { re= active: false, style_class: 'popup-inactive-menu-item' }); -+ this.section.addMenuItem(this.statusItem); ++ let title =3D this._getStatusLabel(); ++ this._statusItem =3D new PopupMenu.PopupMenuItem(title, ++ { reactive: = false, ++ style_clas= s: 'popup-inactive-menu-item' ++ }); ++ this.section.addMenuItem(this._statusItem); + } + // else do nothing, the menu should remain empty + }, + -+ getStatusLabel: function() { -+ switch(this.device.state) { -+ case NetworkManager.DeviceState.DISCONNECTED: -+ case NetworkManager.DeviceState.ACTIVATED: -+ log('Attempt to show status for a disconnected / activate d= evice, should be showing connection list instead'); -+ return 'invalid'; -+ case NetworkManager.DeviceState.PREPARE: -+ case NetworkManager.DeviceState.CONFIG: -+ case NetworkManager.DeviceState.IP_CONFIG: -+ return _("connecting..."); -+ case NetworkManager.DeviceState.NEED_AUTH: -+ return _("authentication required"); -+ case NetworkManager.DeviceState.UNAVAILABLE: -+ if ((this.device.capabilities & NetworkManager.DeviceCapabi= lities.CARRIER_DETECT) && -+ !this.device.carrier) -+ return _("network cable unplugged"); -+ else -+ return _("network unavailable"); -+ case NetworkManager.DeviceState.FAILED: -+ return _("connection failed"); -+ default: -+ log('Device state invalid, is %d'.format(this.device.state)= ); -+ return 'invalid'; -+ } -+ }, -+ -+ createConnectionList: function() { -+ if (this.activeConnection) { -+ this.createActiveConnectionItems(); -+ this.section.addMenuItem(this.activeConnectionItem); -+ if (this.disconnectItem) -+ this.section.addMenuItem(this.disconnectItem); ++ _createConnectionList: function() { ++ if (this._activeConnection) { ++ this._createActiveConnectionItems(); ++ this.section.addMenuItem(this._activeConnectionItem); ++ if (this._disconnectItem) ++ this.section.addMenuItem(this._disconnectItem); + } -+ if (this.connections.length > 0) { -+ for(let j =3D 0; j < this.connections.length; ++j) { -+ let obj =3D this.connections[j]; -+ if (this.activeConnection && obj.connection =3D=3D this= .activeConnection._connection) ++ if (this._connections.length > 0) { ++ for(let j =3D 0; j < this._connections.length; ++j) { ++ let obj =3D this._connections[j]; ++ if (this._activeConnection && ++ obj.connection =3D=3D this._activeConnection._conne= ction) + continue; -+ obj.item =3D this.createConnectionItem(obj); ++ obj.item =3D this._createConnectionItem(obj); + this.section.addMenuItem(obj.item); + } -+ } else if (this.autoConnectionName) { -+ this.autoConnectionItem =3D new PopupMenu.PopupMenuItem(thi= s.autoConnectionName); -+ this.autoConnectionItem.connect('activate', Lang.bind(this,= function() { -+ let connection =3D this.createAutomaticConnection(); -+ this.client.add_and_activate_connection(connection, thi= s.device, null, function() { }); ++ } else if (this._autoConnectionName) { ++ this._autoConnectionItem =3D new PopupMenu.PopupMenuItem(th= is._autoConnectionName); ++ this._autoConnectionItem.connect('activate', Lang.bind(this= , function() { ++ let connection =3D this._createAutomaticConnection(); ++ this._client.add_and_activate_connection(connection, th= is.device, null, null); + })); -+ this.section.addMenuItem(this.autoConnectionItem); ++ this.section.addMenuItem(this._autoConnectionItem); + } + }, + -+ createConnectionItem: function(obj) { ++ _createConnectionItem: function(obj) { + let path =3D obj.connection.path; + let item =3D new PopupMenu.PopupMenuItem(obj.name); + item.connect('activate', Lang.bind(this, function() { -+ this.client.activate_connection(path, this.device, null, fu= nction() { }); ++ this._client.activate_connection(path, this.device, null, n= ull); + })); + return item; + }, + -+ createActiveConnectionItems: function() { ++ _createActiveConnectionItems: function() { + let title; -+ let active =3D this.activeConnection._connection; -+ this.disconnectItem =3D null; ++ let active =3D this._activeConnection._connection; ++ this._disconnectItem =3D null; + if (active) { + title =3D active._name; -+ this.disconnectItem =3D new PopupMenu.PopupMenuItem(_("Disc= onnect")); -+ this.disconnectItem.connect('activate', Lang.bind(this, fun= ction() { ++ this._disconnectItem =3D new PopupMenu.PopupMenuItem(_("Dis= connect")); ++ this._disconnectItem.connect('activate', Lang.bind(this, fu= nction() { + /* The correct approach would be -+ this.client.deactivate_connection(this.activeConnect= ion); ++ this.client.deactivate_connection(this._activeConnec= tion); + but with this, NM insists in restarting the connecti= on immediately + */ + this.device.disconnect(function() { }); @@ -547,8 +584,35 @@ index 0000000..a0cd576 + and we cannot access its settings (including the name) *= / + title =3D _("Connected (private)"); + } -+ this.activeConnectionItem =3D new PopupMenu.PopupMenuItem(title= , { reactive: false }); -+ this.activeConnectionItem.setShowDot(true); ++ this._activeConnectionItem =3D new PopupMenu.PopupMenuItem(titl= e, { reactive: false }); ++ this._activeConnectionItem.setShowDot(true); ++ }, ++ ++ // private ++ _getStatusLabel: function() { ++ switch(this.device.state) { ++ case NetworkManager.DeviceState.DISCONNECTED: ++ case NetworkManager.DeviceState.ACTIVATED: ++ log('Attempt to show status for a disconnected / activate d= evice, should be showing connection list instead'); ++ return 'invalid'; ++ case NetworkManager.DeviceState.PREPARE: ++ case NetworkManager.DeviceState.CONFIG: ++ case NetworkManager.DeviceState.IP_CONFIG: ++ return _("connecting..."); ++ case NetworkManager.DeviceState.NEED_AUTH: ++ return _("authentication required"); ++ case NetworkManager.DeviceState.UNAVAILABLE: ++ if ((this.device.capabilities & NetworkManager.DeviceCapabi= lities.CARRIER_DETECT) && ++ !this.device.carrier) ++ return _("network cable unplugged"); ++ else ++ return _("network unavailable"); ++ case NetworkManager.DeviceState.FAILED: ++ return _("connection failed"); ++ default: ++ log('Device state invalid, is %d'.format(this.device.state)= ); ++ return 'invalid'; ++ } + }, + + deviceStateChanged: function(device, newstate, oldstate, reason) { @@ -564,10 +628,11 @@ index 0000000..a0cd576 + switch(newstate) { + case NetworkManager.DeviceState.UNMANAGED: + // clear everything and be quiet -+ this.clearSection(); ++ this._clearSection(); + return; + case NetworkManager.DeviceState.NEED_AUTH: + // FIXME: make this have a real effect ++ // (currently we rely on a running nm-applet) + this.emit('need-auth'); + break; + case NetworkManager.DeviceState.FAILED: @@ -581,13 +646,13 @@ index 0000000..a0cd576 + oldstate !=3D NetworkManager.DeviceState.ACTIVATED && + oldstate !=3D NetworkManager.DeviceState.UNMANAGED) { + // a transition between states that show the status label -+ this.statusItem.label.text =3D this.getStatusLabel(); ++ this._statusItem.label.text =3D this._getStatusLabel(); + return; + } + + // just refresh everything -+ this.clearSection(); -+ this.createSection(); ++ this._clearSection(); ++ this._createSection(); + } +}; +Signals.addSignalMethods(NMDevice.prototype); @@ -601,31 +666,31 @@ index 0000000..a0cd576 + __proto__: NMDevice.prototype, + + _init: function(client, device, connections) { -+ this.autoConnectionName =3D _("Auto Ethernet"); -+ this.category =3D 'wired'; ++ this._autoConnectionName =3D _("Auto Ethernet"); ++ this.category =3D NMConnectionCategory.WIRED; + + NMDevice.prototype._init.call(this, client, device, connections= ); + }, + + connectionValid: function(connection) { -+ if (connection._type !=3D '802-3-ethernet') ++ if (connection._type !=3D NetworkManager.SETTING_WIRED_SETTING_= NAME) + return false; + -+ let ethernetSettings =3D connection.get_setting_by_name('802-3-= ethernet'); ++ let ethernetSettings =3D connection.get_setting_by_name(Network= Manager.SETTING_WIRED_SETTING_NAME); + let fixedMac =3D ethernetSettings.get_mac_address(); + if (fixedMac) + return macCompare(fixedMac, macToArray(this.device.perm_hw_= address)); + return true; + }, + -+ createAutomaticConnection: function() { ++ _createAutomaticConnection: function() { + let connection =3D new NetworkManager.Connection(); + connection._uuid =3D NetworkManager.utils_uuid_generate(); + connection.add_setting(new NetworkManager.SettingWired()); + connection.add_setting(new NetworkManager.SettingConnection({ + uuid: connection._uuid, -+ id: this.autoConnectionName, -+ type: '802-3-ethernet', ++ id: this._autoConnectionName, ++ type: NetworkManager.SETTING_WIRED_SETTING_NAME, + autoconnect: true + })); + return connection; @@ -640,15 +705,15 @@ index 0000000..a0cd576 + __proto__: NMDevice.prototype, + + _init: function(client, device, connections) { -+ this.autoConnectionName =3D _("New Mobile Broadband connection.= .."); -+ this.category =3D 'wwan'; ++ this._autoConnectionName =3D _("New Mobile Broadband connection= ..."); ++ this.category =3D NMConnectionCategory.WWAN; + + if (device instanceof NMClient.GsmDevice) { + this.mobileDevice =3D new ModemManager.ModemGsm(device.udi)= ; -+ this._connectionType =3D 'gsm'; ++ this._connectionType =3D NetworkManager.SETTING_GSM_SETTING= _NAME; + } else if (device instanceof NMClient.CdmaDevice) { + this.mobileDevice =3D new ModemManager.ModemCdma(device.udi= ); -+ this._connectionType =3D 'cdma'; ++ this._connectionType =3D NetworkManager.SETTING_CDMA_SETTIN= G_NAME; + } + + this.mobileDevice.connect('notify::operator-name', Lang.bind(th= is, function() { @@ -663,43 +728,46 @@ index 0000000..a0cd576 + })); + this.mobileDevice.connect('notify::signal-quality', Lang.bind(t= his, function() { + if (this._operatorItem) { -+ this._operatorItem.setIcon(this._get_signal_icon()); ++ this._operatorItem.setIcon(this._getSignalIcon()); + } + })); + + NMDevice.prototype._init.call(this, client, device, connections= , 1); + }, + -+ _get_signal_icon: function() { ++ _getSignalIcon: function() { + return 'network-cellular-signal-' + signalToIcon(this.mobileDev= ice.signal_quality); + }, + -+ createSection: function() { -+ NMDevice.prototype.createSection.call(this); ++ _createSection: function() { ++ NMDevice.prototype._createSection.call(this); + -+ this._operatorItem =3D new PopupMenu.PopupImageMenuItem(this.mo= bileDevice.operator_name || '', this._get_signal_icon(), { reactive: fals= e }); ++ this._operatorItem =3D new PopupMenu.PopupImageMenuItem(this.mo= bileDevice.operator_name || '', ++ this._get= SignalIcon(), ++ { reactiv= e: false }); + this.section.addMenuItem(this._operatorItem, 0); + }, + + clearSection: function() { + this._operatorItem =3D null; + -+ NMDevice.prototype.clearSection.call(this); ++ NMDevice.prototype._clearSection.call(this); + }, + + connectionValid: function(connection) { + return connection._type =3D=3D this._connectionType; + }, + -+ createAutomaticConnection: function() { ++ _createAutomaticConnection: function() { + // FIXME: we need to summon the mobile wizard here + // or NM will not have the necessary parameters to complete the= connection ++ // (the same FIXME is currently in nm-applet, actually) + + let connection =3D new NetworkManager.Connection; + connection._uuid =3D NetworkManager.utils_uuid_generate(); + connection.add_setting(new NetworkManager.SettingConnection({ + uuid: connection._uuid, -+ id: this.autoConnectionName, ++ id: this._autoConnectionName, + type: this._connectionType, + autoconnect: false + })); @@ -715,17 +783,17 @@ index 0000000..a0cd576 + __proto__: NMDevice.prototype, + + _init: function(client, device, connections) { -+ this.autoConnectionName =3D _("New Mobile Broadband connection.= .."); -+ this.category =3D 'wwan'; ++ this._autoConnectionName =3D _("New Mobile Broadband connection= ..."); ++ this.category =3D NMConnectionCategory.WWAN; + + NMDevice.prototype._init.call(this, client, device, connections= ); + }, + + connectionValid: function(connection) { -+ if (connection._type !=3D 'bluetooth') ++ if (connection._type !=3D NetworkManager.SETTING_BLUETOOTH_SETT= ING_NAME) + return false; + -+ let bluetoothSettings =3D connection.get_setting_by_name('bluet= ooth'); ++ let bluetoothSettings =3D connection.get_setting_by_name(Networ= kManager.SETTING_BLUETOOTH_SETTING_NAME); + let fixedBdaddr =3D bluetoothSettings.get_bdaddr(); + if (fixedBdaddr) + return macCompare(fixedBdaddr, macToArray(this.device.hw_ad= dress)); @@ -733,15 +801,16 @@ index 0000000..a0cd576 + return true; + }, + -+ createAutomaticConnection: function() { ++ _createAutomaticConnection: function() { + // XXX: is this enough? or do we need other stuff from bluetoot= hd? + + let connection =3D new NetworkManager.Connection; + connection._uuid =3D NetworkManager.utils_uuid_generate(); ++ connection.add_setting(new NetworkManager.SettingBluetooth); + connection.add_setting(new NetworkManager.SettingConnection({ + uuid: connection._uuid, -+ id: this.autoConnectionName, -+ type: 'gsm', ++ id: this._autoConnectionName, ++ type: NetworkManager.SETTING_BLUETOOTH_SETTING_NAME, + autoconnect: false + })); + return connection; @@ -759,14 +828,18 @@ index 0000000..a0cd576 + + _init: function(client) { + // Disable autoconnections -+ this.autoConnectionName =3D null; -+ this.category =3D 'vpn'; ++ this._autoConnectionName =3D null; ++ this.category =3D NMConnectionCategory.VPN; + + NMDevice.prototype._init.call(this, client, null, [ ]); + }, + + connectionValid: function(connection) { -+ return connection._type =3D=3D 'vpn'; ++ return connection._type =3D=3D NetworkManager.SETTING_VPN_SETTI= NG_NAME; ++ }, ++ ++ get empty() { ++ return this._connections.length =3D=3D 0; + } +}; + @@ -778,10 +851,10 @@ index 0000000..a0cd576 + __proto__: NMDevice.prototype, + + _init: function(client, device, connections) { -+ this.category =3D 'wireless'; ++ this.category =3D NMConnectionCategory.WIRELESS; + + this._overflowItem =3D null; -+ this._accessPoints =3D [ ]; ++ this._networks =3D [ ]; + + // XXX: breaking the layers with this, but cannot call + // this.connectionValid until I have a device @@ -794,22 +867,19 @@ index 0000000..a0cd576 + for (let i =3D 0; i < accessPoints.length; i++) { + // Access points are grouped by network name + let ap =3D accessPoints[i]; -+ let name =3D String(ap.get_ssid()); -+ let pos =3D this._findAccessPoint(name); ++ let ssid =3D ap.get_ssid(); ++ let pos =3D this._findNetwork(ssid); + let obj; + if (pos !=3D -1) { -+ obj =3D this._accessPoints[pos]; ++ obj =3D this._networks[pos]; + obj.accessPoints.push(ap); -+ obj.accessPoints.sort(function(one, two) { -+ return two.strength - one.strength; -+ }); + } else { -+ obj =3D { name: name, ++ obj =3D { ssid: ssid, + connections: [ ], + item: null, + accessPoints: [ ap ] + }; -+ this._accessPoints.push(obj); ++ this._networks.push(obj); + } + + // Check if some connection is valid for this AP @@ -827,32 +897,28 @@ index 0000000..a0cd576 + NMDevice.prototype._init.call(this, client, device, validConnec= tions); + }, + -+ _findAccessPoint: function(name) { -+ for (let i =3D 0; i < this._accessPoints.length; i++) { -+ if (this._accessPoints[i].name =3D=3D name) ++ _findNetwork: function(ssid) { ++ for (let i =3D 0; i < this._networks.length; i++) { ++ if (ssidCompare(this._networks[i].ssid, ssid)) + return i; + } + return -1; + }, + + _accessPointAdded: function(device, accessPoint) { -+ let name =3D String(accessPoint.get_ssid()); -+ let pos =3D this._findAccessPoint(name); ++ let ssid =3D accessPoint.get_ssid(); ++ let pos =3D this._findNetwork(ssid); + let apObj; + if (pos !=3D -1) { -+ apObj =3D this._accessPoints[pos]; ++ apObj =3D this._network[pos]; + if (apObj.accessPoints.indexOf(accessPoint) !=3D -1) { -+ // already seen this AP ++ log('Access point was already seen, not adding again'); + return; + } + + apObj.accessPoints.push(accessPoint); -+ apObj.accessPoints.sort(function(one, two) { -+ return two.strength - one.strength; -+ }); -+ + } else { -+ apObj =3D { name: name, ++ apObj =3D { ssid: ssid, + connections: [ ], + item: null, + accessPoints: [ accessPoint ] @@ -861,8 +927,8 @@ index 0000000..a0cd576 + } + + // check if this enables new connections for this group -+ for (let i =3D 0; i < this.connections.length; i++) { -+ let connection =3D this.connections[i].connection; ++ for (let i =3D 0; i < this._connections.length; i++) { ++ let connection =3D this._connections[i].connection; + if (this._connectionValidForAP(connection, accessPoint) && + apObj.connections.indexOf(connection) =3D=3D -1) { + apObj.connections.push(connection); @@ -872,21 +938,21 @@ index 0000000..a0cd576 + if (this.device.state =3D=3D NetworkManager.DeviceState.DISCONN= ECTED || + this.device.state =3D=3D NetworkManager.DeviceState.ACTIVAT= ED) { + // update everything (it would be too complicated to update= just what has changed) -+ this.clearSection(); -+ this.createConnectionList(); ++ this._clearSection(); ++ this._createConnectionList(); + } + }, + + _accessPointRemoved: function(device, accessPoint) { -+ let name =3D String(accessPoint.get_ssid()); -+ let pos =3D this._findAccessPoint(name); ++ let ssid =3D accessPoint.get_ssid(); ++ let pos =3D this._findNetwork(ssid); + + if (pos =3D=3D -1) { + log('Removing an access point that was never added'); + return; + } + -+ let apObj =3D this._accessPoints[pos]; ++ let apObj =3D this._networks[pos]; + let i =3D apObj.accessPoints.indexOf(accessPoint); + + if (i =3D=3D -1) { @@ -899,25 +965,19 @@ index 0000000..a0cd576 + if (apObj.accessPoints.length =3D=3D 0) { + if (apObj.item) + apObj.item.destroy(); -+ this._accessPoints.splice(pos, 1); -+ } ++ this._networks.splice(pos, 1); ++ } else if (apObj.item) ++ apObj.item.updateAccessPoints(apObj.accessPoints); + }, + + _createAPItem: function(connection, accessPointObj, useConnectionNa= me) { -+ accessPointObj.accessPoints.sort(function(one, two) { -+ return two.strength - one.strength; -+ }); -+ let item =3D new NMAccessPointMenuItem(accessPointObj.accessPoi= nts[0], useConnectionName ? connection._name : undefined); ++ let item =3D new NMNetworkMenuItem(accessPointObj.accessPoints,= useConnectionName ? connection._name : undefined); + item._connection =3D connection; + item.connect('activate', Lang.bind(this, function() { -+ // always connect to the strongest access point in a group -+ let apList =3D accessPointObj.accessPoints; -+ apList.sort(function(one, two) { -+ return two.strength - one.strength; -+ }); -+ for (let i =3D 0; i < apList.length; i++) { -+ if (this._connectionValidForAP(connection, apList[i])) = { -+ this.client.activate_connection(connection.path, th= is.device, apList[i].dbus_path, function() { }); ++ let accessPoints =3D sortAccessPoints(accessPointObj.access= Points); ++ for (let i =3D 0; i < accessPoints.length; i++) { ++ if (this._connectionValidForAP(connection, accessPoints= [i])) { ++ this._client.activate_connection(connection.path, t= his.device, accessPoints[i].dbus_path, null); + break; + } + } @@ -926,11 +986,11 @@ index 0000000..a0cd576 + }, + + connectionValid: function(connection) { -+ if (connection._type !=3D '802-11-wireless') ++ if (connection._type !=3D NetworkManager.SETTING_WIRELESS_SETTI= NG_NAME) + return false; + -+ let wirelessSettings =3D connection.get_setting_by_name('802-11= -wireless'); -+ let wirelessSecuritySettings =3D connection.get_setting_by_name= ('802-11-wireless-security'); ++ let wirelessSettings =3D connection.get_setting_by_name(Network= Manager.SETTING_WIRELESS_SETTING_NAME); ++ let wirelessSecuritySettings =3D connection.get_setting_by_name= (NetworkManager.SETTING_WIRELESS_SECURITY_SETTING_NAME); + + let fixedMac =3D wirelessSettings.get_mac_address(); + if (fixedMac && !macCompare(fixedMac, macToArray(this.device.pe= rm_hw_address))) @@ -959,27 +1019,29 @@ index 0000000..a0cd576 + return true; + }, + -+ clearSection: function() { -+ NMDevice.prototype.clearSection.call(this); ++ _clearSection: function() { ++ NMDevice.prototype._clearSection.call(this); + -+ for (let i =3D 0; i < this._accessPoints.length; i++) -+ this._accessPoints[i].item =3D null; ++ for (let i =3D 0; i < this._networks.length; i++) ++ this._networks[i].item =3D null; + this._overflowItem =3D null; + }, + + removeConnection: function(connection, skipCreateAuto) { + if (!connection._uuid) + return; -+ let pos =3D this.findConnection(connection._uuid); -+ if (pos =3D=3D -1) ++ let pos =3D this._findConnection(connection._uuid); ++ if (pos =3D=3D -1) { ++ log('Removing connection that was never added'); + return; ++ } + -+ let obj =3D this.connections[pos]; -+ this.connections.splice(pos, 1); ++ let obj =3D this._connections[pos]; ++ this._connections.splice(pos, 1); + + let anyauto =3D false, forceupdate =3D false; -+ for (let i =3D 0; i < this._accessPoints.length; i++) { -+ let apObj =3D this._accessPoints[i]; ++ for (let i =3D 0; i < this._networks.length; i++) { ++ let apObj =3D this._networks[i]; + let connections =3D apObj.connections; + for (let k =3D 0; k < connections.length; k++) { + if (connections[k]._uuid =3D=3D connection._uuid) { @@ -1010,13 +1072,13 @@ index 0000000..a0cd576 + } + + if (forceupdate || (anyauto && !skipCreateAuto)) { -+ this.clearSection(); -+ this.createConnectionList(); ++ this._clearSection(); ++ this._createConnectionList(); + } + }, + + addConnection: function(connection) { -+ if (this.findConnection(connection._uuid) !=3D -1) { ++ if (this._findConnection(connection._uuid) !=3D -1) { + log('Connection already added to menu, not adding again'); + return; + } @@ -1027,12 +1089,12 @@ index 0000000..a0cd576 + name: connection._name, + uuid: connection._uuid, + }; -+ this.connections.push(obj); ++ this._connections.push(obj); + + // find an appropriate access point -+ let any =3D false; -+ for (let i =3D 0; i < this._accessPoints.length; i++) { -+ let apObj =3D this._accessPoints[i]; ++ let any =3D false, forceupdate =3D false; ++ for (let i =3D 0; i < this._networks.length; i++) { ++ let apObj =3D this._networks[i]; + + // Check if connection is valid for any of these access poi= nts + let any =3D false; @@ -1049,7 +1111,7 @@ index 0000000..a0cd576 + (this.device.state =3D=3D NetworkManager.DeviceState.DI= SCONNECTED || + this.device.state =3D=3D NetworkManager.DeviceState.AC= TIVATED)) { + // we need to show this connection -+ if (apObj.item && apObj.connections.length > 2) { ++ if (apObj.item && apObj.item.menu) { + // We're already showing the submenu for this acces= s point + apObj.item.menu.addMenuItem(this._createAPItem(conn= ection, apObj, true)); + } else { @@ -1057,23 +1119,29 @@ index 0000000..a0cd576 + apObj.item.destroy(); + if (apObj.connections.length =3D=3D 1) { + apObj.item =3D this._createAPItem(connection, a= pObj, false); ++ this.section.addMenuItem(apObj.item); + } else { -+ apObj.item =3D new PopupMenu.PopupSubMenuMenuIt= em(apObj.name); -+ apObj.item.menu.addMenuItem(this._createAPItem(= connection, apObj, true)); ++ apObj.item =3D null; ++ // we need to force an update to create the sub= menu ++ forceupdate =3D true; + } -+ this.section.addMenuItem(apObj.item); + } + } + } ++ ++ if (forceupdate) { ++ this._clearSection(); ++ this._createSection(); ++ } + }, + + _connectionValidForAP: function(connection, ap) { + // copied and adapted from nm-applet -+ let wirelessSettings =3D connection.get_setting_by_name('802-11= -wireless'); -+ if (wirelessSettings.get_ssid() !=3D String(ap.get_ssid())) ++ let wirelessSettings =3D connection.get_setting_by_name(Network= Manager.SETTING_WIRELESS_SETTING_NAME); ++ if (!ssidCompare(wirelessSettings.get_ssid(), ap.get_ssid())) + return false; + -+ let wirelessSecuritySettings =3D connection.get_setting_by_name= ('802-11-wireless-security'); ++ let wirelessSecuritySettings =3D connection.get_setting_by_name= (NetworkManager.SETTING_WIRELESS_SECURITY_SETTING_NAME); + + let fixedBssid =3D wirelessSettings.get_bssid(); + if (fixedBssid && !macCompare(fixedBssid, macToArray(ap.hw_addr= ess))) @@ -1097,44 +1165,52 @@ index 0000000..a0cd576 + return true; + }, + -+ createActiveConnectionItems: function() { ++ _createActiveConnectionItems: function() { + let activeAp =3D this.device.active_access_point; + let icon, title; -+ if (this.activeConnection._connection) { -+ let connection =3D this.activeConnection._connection; ++ if (this._activeConnection._connection) { ++ let connection =3D this._activeConnection._connection; + if (activeAp) -+ this.activeConnectionItem =3D new NMAccessPointMenuItem= (activeAp, undefined, { reactive: false }); ++ this._activeConnectionItem =3D new NMNetworkMenuItem([ = activeAp ], undefined, ++ = { reactive: false }); + else -+ this.activeConnectionItem =3D new PopupMenu.PopupImageM= enuItem(connection._name, 'network-wireless-connected', { reactive: false= }); -+ this.disconnectItem =3D new PopupMenu.PopupMenuItem(_("Disc= onnect")); -+ this.disconnectItem.connect('activate', Lang.bind(this, fun= ction() { ++ this._activeConnectionItem =3D new PopupMenu.PopupImage= MenuItem(connection._name, ++ = 'network-wireless-connected', ++ = { reactive: false }); ++ this._disconnectItem =3D new PopupMenu.PopupMenuItem(_("Dis= connect")); ++ this._disconnectItem.connect('activate', Lang.bind(this, fu= nction() { + this.device.disconnect(function() { }); + })); + } else { -+ // We cannot read the connection (due to ACL, most likely),= but we still show signal if we have it ++ // We cannot read the connection (due to ACL, or API incomp= atibility), but we still show signal if we have it + let menuItem; + if (activeAp) -+ this.activeConnectionItem =3D new NMAccessPointMenuItem= (activeAp, undefined, { reactive: false }); ++ this._activeConnectionItem =3D new NMNetworkMenuItem([ = activeAp ], undefined, ++ = { reactive: false }); + else -+ this.activeConnectionItem =3D new PopupMenu.PopupImageM= enuItem(_("Connected (private)"), 'network-wireless-connected', { reactiv= e: false }); ++ this._activeConnectionItem =3D new PopupMenu.PopupImage= MenuItem(_("Connected (private)"), ++ = 'network-wireless-connected', ++ = { reactive: false }); + } -+ this.activeConnectionItem.setShowDot(true); ++ this._activeConnectionItem.setShowDot(true); + }, + -+ createConnectionList: function() { -+ if(this.activeConnection) { -+ this.createActiveConnectionItems(); -+ this.section.addMenuItem(this.activeConnectionItem); -+ if (this.disconnectItem) -+ this.section.addMenuItem(this.disconnectItem); ++ _createConnectionList: function() { ++ if(this._activeConnection) { ++ this._createActiveConnectionItems(); ++ this.section.addMenuItem(this._activeConnectionItem); ++ if (this._disconnectItem) ++ this.section.addMenuItem(this._disconnectItem); + } + + let activeAp =3D this.device.active_access_point; -+ let activeApName =3D activeAp ? String(activeAp.get_ssid()) : n= ull; ++ // Use undefined instead of null, so we're sure not to match an= ything ++ // that comes from NetworkManager ++ let activeApSsid =3D activeAp ? activeAp.get_ssid() : null; + -+ for(let j =3D 0; j < this._accessPoints.length; j++) { -+ let apObj =3D this._accessPoints[j]; -+ if(apObj.name =3D=3D activeApName) ++ for(let j =3D 0; j < this._networks.length; j++) { ++ let apObj =3D this._networks[j]; ++ if(activeAp && ssidCompare(apObj.ssid, activeApSsid)) + continue; + + let menuItem; @@ -1142,26 +1218,35 @@ index 0000000..a0cd576 + if (apObj.connections.length =3D=3D 1) + apObj.item =3D this._createAPItem(apObj.connections= [0], apObj, false); + else { -+ apObj.item =3D new PopupMenu.PopupSubMenuMenuItem(a= pObj.name); ++ let title =3D NetworkManager.utils_ssid_to_utf8(apO= bj.ssid, apObj.ssid.length) || _(""); ++ apObj.item =3D new PopupMenu.PopupSubMenuMenuItem(t= itle); + apObj.item._apObj =3D apObj; + for (let i =3D 0; i < apObj.connections.length; i++= ) -+ menuItem.menu.addMenuItem(this._createAPItem(ap= Obj.connections[i], apObj, true)); ++ apObj.item.menu.addMenuItem(this._createAPItem(= apObj.connections[i], apObj, true)); + } + } else { -+ apObj.item =3D new NMAccessPointMenuItem(apObj.accessPo= ints[0]); ++ apObj.item =3D new NMNetworkMenuItem(apObj.accessPoints= ); + apObj.item._apObj =3D apObj; + apObj.item.connect('activate', Lang.bind(this, function= () { ++ let name; ++ let ssid =3D NetworkManager.utils_ssid_to_utf8(apOb= j.ssid, apObj.ssid.length); ++ if (ssid) { ++ /* TRANSLATORS: this the automatic wireless con= nection name (including the network name) */ ++ name =3D _("Auto %s").format(ssid); ++ } else ++ name =3D _("Auto wireless"); ++ + let connection =3D new NetworkManager.Connection(); + connection.add_setting(new NetworkManager.SettingWi= reless()); + connection.add_setting(new NetworkManager.SettingCo= nnection({ -+ /* TRANSLATORS: this the automatic wireless con= nection name (including the network name) */ -+ id: _("Auto %s").format(apObj.name), ++ id: name, + autoconnect: true, // NetworkManager will know = to ignore this if appropriate + uuid: NetworkManager.utils_uuid_generate(), -+ type: '802-11-wireless' ++ type: NetworkManager.SETTING_WIRELESS_SETTING_N= AME + })); + -+ this.client.add_and_activate_connection(connection,= this.device, apObj.accessPoints[0].dbus_path, function() { }) ++ accessPoints =3D sortAccessPoints(apObj.accessPoint= s); ++ this._client.add_and_activate_connection(connection= , this.device, accessPoints[0].dbus_path, null) + })); + } + @@ -1170,6 +1255,7 @@ index 0000000..a0cd576 + else { + if (!this._overflowItem) { + this._overflowItem =3D new PopupMenu.PopupSubMenuMe= nuItem(_("More...")); ++ this.section.addMenuItem(this._overflowItem); + } + this._overflowItem.menu.addMenuItem(menuItem); + } @@ -1198,16 +1284,17 @@ index 0000000..a0cd576 + this._statusSection.addMenuItem(new PopupMenu.PopupSeparatorMen= uItem()); + this.menu.addMenuItem(this._statusSection); + -+ this._allSections =3D [ ]; ++ this._deviceSections =3D [ ]; + + this._wiredSection =3D new PopupMenu.PopupMenuSection(); -+ this._wiredItem =3D new PopupMenu.PopupMenuItem(_("Wired networ= ks"), { style_class: 'popup-subtitle-menu-item', reactive: false }); ++ this._wiredItem =3D new PopupMenu.PopupMenuItem(_("Wired networ= ks"), ++ { style_class: 'p= opup-subtitle-menu-item', reactive: false }); + this._wiredDevices =3D [ ]; + + this._wiredSection.addMenuItem(this._wiredItem); + this._wiredSection.addMenuItem(new PopupMenu.PopupSeparatorMenu= Item()); + this._wiredSection.actor.hide(); -+ this._allSections.push(this._wiredSection); ++ this._deviceSections.push(this._wiredSection); + this.menu.addMenuItem(this._wiredSection); + + this._wirelessSection =3D new PopupMenu.PopupMenuSection(); @@ -1221,7 +1308,7 @@ index 0000000..a0cd576 + })); + this._wirelessSection.addMenuItem(newAdhocWireless); + -+ let newHiddenWireless =3D new PopupMenu.PopupMenuItem(_("Connec= t to hidden wireless network...")); ++ let newHiddenWireless =3D new PopupMenu.PopupMenuItem(_("Other = networks...")); + newHiddenWireless.connect('activate', Lang.bind(this, function(= ) { + this._nmApplet.ConnectToHiddenNetworkRemote(); + })); @@ -1229,7 +1316,7 @@ index 0000000..a0cd576 + + this._wirelessSection.addMenuItem(new PopupMenu.PopupSeparatorM= enuItem()); + this._wirelessSection.actor.hide(); -+ this._allSections.push(this._wirelessSection); ++ this._deviceSections.push(this._wirelessSection); + this.menu.addMenuItem(this._wirelessSection); + + this._wwanSection =3D new PopupMenu.PopupMenuSection(); @@ -1239,13 +1326,18 @@ index 0000000..a0cd576 + this._wwanSection.addMenuItem(new PopupMenu.PopupSeparatorMenuI= tem()); + + this._wwanSection.actor.hide(); -+ this._allSections.push(this._wwanSection); ++ this._deviceSections.push(this._wwanSection); + this.menu.addMenuItem(this._wwanSection); + -+ // this._vpnDevice =3D new NMDeviceVPN(); -+ // this._vpnSection =3D this._vpnDevice.section -+ // this._allSections.push(this._vpnSection) -+ // this.menu.addMenuItem(this._vpnSection); ++ this._vpnDevice =3D new NMDeviceVPN(); ++ this._vpnItem =3D new PopupMenu.PopupMenuItem(_("VPN Connection= s"), ++ { style_class: 'pop= up-subtitle-menu-item', reactive: false }); ++ this._vpnSection =3D new PopupMenu.PopupMenuSection(); ++ this._vpnSection.addMenuItem(this._vpnItem); ++ this._vpnSection.addMenuItem(this._vpnDevice.section); ++ this._vpnSection.addMenuItem(new PopupMenu.PopupSeparatorMenuIt= em()); ++ this._deviceSections.push(this._vpnSection); ++ this.menu.addMenuItem(this._vpnSection); + + this.menu.addAction(_("Network Settings"), function() { + Util.spawnDesktop('gnome-network-panel'); @@ -1262,48 +1354,45 @@ index 0000000..a0cd576 + + // Device types + this._dtypes =3D { }; -+ this._dtypes[makeClassKey(NMClient.DeviceEthernet.prototype)] =3D= NMDeviceWired; -+ this._dtypes[makeClassKey(NMClient.DeviceWifi.prototype)] =3D N= MDeviceWireless; -+ this._dtypes[makeClassKey(NMClient.GsmDevice.prototype)] =3D NM= DeviceWWAN; -+ this._dtypes[makeClassKey(NMClient.CdmaDevice.prototype)] =3D N= MDeviceWWAN; -+ this._dtypes[makeClassKey(NMClient.DeviceBt.prototype)] =3D NMD= eviceBluetooth; ++ this._dtypes[NetworkManager.DeviceType.ETHERNET] =3D NMDeviceWi= red; ++ this._dtypes[NetworkManager.DeviceType.WIFI] =3D NMDeviceWirele= ss; ++ this._dtypes[NetworkManager.DeviceType.GSM] =3D NMDeviceWWAN; ++ this._dtypes[NetworkManager.DeviceType.CDMA] =3D NMDeviceWWAN; ++ this._dtypes[NetworkManager.DeviceType.BT] =3D NMDeviceBluetoot= h; + // FIXME: WWAN support (if enabled) + + // Connection types + this._ctypes =3D { }; -+ this._ctypes['802-11-wireless'] =3D 'wireless'; -+ this._ctypes['802-3-ethernet'] =3D this._ctypes['pppoe'] =3D 'w= ired'; -+ this._ctypes['bluetooth'] =3D this._ctypes['cdma'] =3D this._ct= ypes['gsm'] =3D 'wwan'; -+ this._ctypes['vpn'] =3D 'vpn'; ++ this._ctypes[NetworkManager.SETTING_WIRELESS_SETTING_NAME] =3D = NMConnectionCategory.WIRELESS; ++ this._ctypes[NetworkManager.SETTING_WIRED_SETTING_NAME] =3D NMC= onnectionCategory.WIRED; ++ this._ctypes[NetworkManager.SETTING_PPPOE_SETTING_NAME] =3D NMC= onnectionCategory.WIRED; ++ this._ctypes[NetworkManager.SETTING_BLUETOOTH_SETTING_NAME] =3D= NMConnectionCategory.WWAN; ++ this._ctypes[NetworkManager.SETTING_CDMA_SETTING_NAME] =3D NMCo= nnectionCategory.WWAN; ++ this._ctypes[NetworkManager.SETTING_GSM_SETTING_NAME] =3D NMCon= nectionCategory.WWAN; ++ this._ctypes[NetworkManager.SETTING_VPN_SETTING_NAME] =3D NMCon= nectionCategory.VPN; + + this._settings =3D NMClient.RemoteSettings.new(null); + this._settings.connect('connections-read', Lang.bind(this, func= tion() { -+ this._read_connections(); -+ this._read_devices(); -+ this._sync_nm_state(); ++ this._readConnections(); ++ this._readDevices(); ++ this._syncNMState(); + + // Connect to signals late so that early signals don't find= in inconsistent state -+ this._client.connect('notify::manager-running', Lang.bind(t= his, this._sync_nm_state)); -+ this._client.connect('notify::networking-enabled', Lang.bin= d(this, this._sync_nm_state)); -+ this._client.connect('notify::state', Lang.bind(this, this.= _sync_nm_state)); -+ this._client.connect('notify::active-connections', Lang.bin= d(this, this._update_icon)); -+ this._client.connect('device-added', Lang.bind(this, this._= device_added)); -+ this._client.connect('device-removed', Lang.bind(this, this= ._device_removed)); -+ this._settings.connect('new-connection', Lang.bind(this, th= is._new_connection)); ++ this._client.connect('notify::manager-running', Lang.bind(t= his, this._syncNMState)); ++ this._client.connect('notify::networking-enabled', Lang.bin= d(this, this._syncNMState)); ++ this._client.connect('notify::state', Lang.bind(this, this.= _syncNMState)); ++ this._client.connect('notify::active-connections', Lang.bin= d(this, this._updateIcon)); ++ this._client.connect('device-added', Lang.bind(this, this._= deviceAdded)); ++ this._client.connect('device-removed', Lang.bind(this, this= ._deviceRemoved)); ++ this._settings.connect('new-connection', Lang.bind(this, th= is._newConnection)); + })); -+ //this._sync_nm_state(); + }, + + _ensureSource: function() { + if (!this._source) { -+ this._source =3D new MessageTray.Source(_("Network Manager"= )); -+ let icon =3D new St.Icon({ icon_name: 'network-transmit-rec= eive', -+ icon_type: St.IconType.SYMBOLIC, -+ icon_size: this._source.ICON_SIZE -+ }); -+ this._source._setSummaryIcon(icon); ++ this._source =3D new NMMessageTraySource(); + this._source._destroyId =3D this._source.connect('destroy',= Lang.bind(this, function() { -+ this._source.disconnect(this._source._destroyId); ++ this._source._destroyId =3D 0; + this._source =3D null; + })); + Main.messageTray.add(this._source); @@ -1346,21 +1435,20 @@ index 0000000..a0cd576 + }); + + this._client.connect('notify::' + type + '-enabled', handler); -+ this._client.connect('notify::' + type + 'hardware-enabled', ha= ndler); ++ this._client.connect('notify::' + type + '-hardware-enabled', h= andler); + this['_' + type + 'Item'] =3D item; + handler(); + }, + -+ _read_devices: function() { ++ _readDevices: function() { + let devices =3D this._client.get_devices(); + for (let i =3D 0; i < devices.length; ++i) { -+ this._device_added(this._client, devices[i]); ++ this._deviceAdded(this._client, devices[i]); + } + }, + -+ _device_added: function(client, device) { -+ let objKey =3D makeClassKey(device); -+ let wrapperClass =3D this._dtypes[objKey]; ++ _deviceAdded: function(client, device) { ++ let wrapperClass =3D this._dtypes[device.get_device_type()]; + if (wrapperClass) { + // XXX: check what nm-applet does here + device._description =3D device.get_product(); @@ -1393,6 +1481,10 @@ index 0000000..a0cd576 + { icon:= icon }); + this._source.notify(notification); + })); ++ wrapper._destroyId =3D wrapper.connect('destroy', function(= wrapper) { ++ wrapper.disconnect(wrapper._networkLostId); ++ wrapper.disconnect(wrapper._activationFailedId); ++ }); + let section =3D this['_' + wrapper.category + 'Section']; + let devices =3D this['_' + wrapper.category + 'Devices']; + @@ -1408,10 +1500,10 @@ index 0000000..a0cd576 + devices[i].titleItem.actor.hide(); + } + } else -+ log('Invalid network device class, is ' + objKey); ++ log('Invalid network device type, is ' + device.get_device_= type()); + }, + -+ _device_removed: function(client, device) { ++ _deviceRemoved: function(client, device) { + if (!device._delegate) { + log('Removing a network device that was not added (race con= dition?)'); + return; @@ -1436,7 +1528,7 @@ index 0000000..a0cd576 + } + }, + -+ _sync_active_connections: function() { ++ _syncActiveConnections: function() { + let closedConnections =3D [ ]; + let newActiveConnections =3D this._client.get_active_connection= s() || [ ]; + for (let i =3D 0; i < this._activeConnections.length; i++) { @@ -1469,10 +1561,16 @@ index 0000000..a0cd576 + let a =3D this._activeConnections[i]; + + if (!a._inited) { -+ a._notifyDefaultId =3D a.connect('notify::default', Lan= g.bind(this, this._update_icon)); -+ a._notifyDefault6Id =3D a.connect('notify::default6', L= ang.bind(this, this._update_icon)); ++ a._notifyDefaultId =3D a.connect('notify::default', Lan= g.bind(this, this._updateIcon)); ++ a._notifyDefault6Id =3D a.connect('notify::default6', L= ang.bind(this, this._updateIcon)); + if (a.state =3D=3D NetworkManager.ActiveConnectionState= .ACTIVATING) // prepare to notify to the user -+ a._notifyStateId =3D a.connect('notify::state', Lan= g.bind(this, this._notify_active_connection)); ++ a._notifyStateId =3D a.connect('notify::state', Lan= g.bind(this, this._notifyActiveConnection)); ++ else { ++ // notify immediately ++ Mainloop.idle_add(Lang.bind(this, function() { ++ this._notifyActiveConnection(a); ++ })); ++ } + + a._inited =3D true; + } @@ -1486,6 +1584,7 @@ index 0000000..a0cd576 + } else { + a._connection =3D null; + a._type =3D null; ++ a._section =3D null; + log('Cannot find connection for active (or connecti= on cannot be read)'); + } + } @@ -1507,7 +1606,7 @@ index 0000000..a0cd576 + } + + if (!a._primaryDevice) { -+ if (a._type !=3D 'vpn') { ++ if (a._type !=3D NetworkManager.SETTING_VPN_SETTING_NAM= E) { + // find a good device to be considered primary + // XXX: check what nm-applet does here + a._primaryDevice =3D null; @@ -1527,36 +1626,32 @@ index 0000000..a0cd576 + } + } + -+ if (activating) -+ this._mainConnection =3D activating; -+ else if (default_ip4) -+ this._mainConnection =3D default_ip4; -+ else -+ this._mainConnection =3D default_ip6; ++ this._mainConnection =3D activating || default_ip4 || default_i= p6 || this._activeConnections[0] || null; + }, + -+ _notify_active_connection: function(active) { -+ if (active.state =3D=3D NetworkManager.ActiveConnectionState.AC= TIVE) { ++ _notifyActiveConnection: function(active) { ++ if (active.state =3D=3D NetworkManager.ActiveConnectionState.AC= TIVATED) { + this._ensureSource(); + + let icon; + let banner; -+ switch (active._type) { -+ case 'gsm': -+ case 'cdma': -+ case 'bluetooth': ++ switch (active._section) { ++ case NMConnectionCategory.WWAN: + icon =3D 'network-cellular-signal-excellent'; + banner =3D _("You're now connected to mobile broadband = connection '%s'").format(active._connection._name); + break; -+ case '802-11-wireless': ++ case NMConnectionCategory.WIRELESS: + icon =3D 'network-wireless-signal-excellent'; + banner =3D _("You're now connected to wireless network = '%s'").format(active._connection._name); + break; -+ case '802-3-ethernet': -+ case 'pppoe': ++ case NMConnectionCategory.WIRED: + icon =3D 'network-wired'; + banner =3D _("You're now connected to wired network '%s= '").format(active._connection._name); + break; ++ case NMConnectionCategory.VPN: ++ icon =3D 'network-vpn'; ++ banner =3D _("You're now connected to VPN network '%s'"= ).format(active._connection._name); ++ break; + default: + // a fallback for a generic 'connected' icon + icon =3D 'network-transmit-receive'; @@ -1564,7 +1659,7 @@ index 0000000..a0cd576 + } + + let iconActor =3D new St.Icon({ icon_name: icon, -+ con_type: St.IconType.SYMBOLI= C, ++ icon_type: St.IconType.SYMBOL= IC, + icon_size: this._source.ICON_= SIZE + }); + let notification =3D new MessageTray.Notification(this._sou= rce, @@ -1573,14 +1668,16 @@ index 0000000..a0cd576 + { icon: ico= nActor }); + this._source.notify(notification); + -+ active.disconnect(active._stateChangeId); -+ active._stateChangeId =3D 0; ++ if (active._stateChangeId) { ++ active.disconnect(active._stateChangeId); ++ active._stateChangeId =3D 0; ++ } + } + -+ this._sync_nm_state(); ++ this._syncNMState(); + }, + -+ _read_connections: function() { ++ _readConnections: function() { + let connections =3D this._settings.list_connections(); + for (let i =3D 0; i < connections.length; i++) { + let connection =3D connections[i]; @@ -1588,75 +1685,77 @@ index 0000000..a0cd576 + log('Connection was already seen, when reading the conn= ections for the first time (race condition?)'); + continue; + } -+ connection.connect('removed', Lang.bind(this, this._connect= ion_removed)); -+ // we don't connect to 'updated' because GJS currently cann= ot deliver it -+ // (it needs to type overrides from GIR) -+ //connection.connect('updated', Lang.bind(this, this._updat= e_connection)); -+ -+ let connectionSettings =3D connection.get_setting_by_name('= connection'); -+ connection._type =3D connectionSettings.type; -+ connection._section =3D this._ctypes[connection._type]; -+ connection._name =3D connectionSettings.id; -+ connection._uuid =3D connectionSettings.uuid; ++ connection.connect('removed', Lang.bind(this, this._connect= ionRemoved)); ++ connection.connect('updated', Lang.bind(this, this._updateC= onnection)); ++ ++ this._updateConnection(connection); + this._connections.push(connection); + } + }, + -+ _new_connection: function(settings, connection) { ++ _newConnection: function(settings, connection) { + if (connection._uuid) { + log('Connection was already seen, not adding again...'); + return; + } + -+ connection.connect('removed', Lang.bind(this, this._connection_= removed)); -+ //connection.connect('updated', Lang.bind(this, this._update_co= nnection)); ++ connection.connect('removed', Lang.bind(this, this._connectionR= emoved)); ++ connection.connect('updated', Lang.bind(this, this._updateConne= ction)); + -+ let connectionSettings =3D connection.get_setting_by_name('conn= ection'); -+ connection._type =3D connectionSettings.type; -+ connection._section =3D this._ctypes[connection._type]; -+ connection._name =3D connectionSettings.id; -+ connection._uuid =3D connectionSettings.uuid; ++ this._updateConnection(connection); + this._connections.push(connection); + -+ this._update_icon(); ++ this._updateIcon(); + }, + -+ _connection_removed: function(connection) { ++ _connectionRemoved: function(connection) { + let pos =3D this._connections.indexOf(connection); + if (pos !=3D -1) + this._connections.splice(connection); + -+ if (!connection._ever_added) ++ if (!connection._everAdded) + return; + + let section =3D connection._section; -+ let devices =3D this['_' + section + 'Devices']; -+ for (let i =3D 0; i < devices.length; i++) -+ devices[i].removeConnection(connection); ++ if (section =3D=3D NMConnectionCategory.VPN) { ++ this._vpnDevice.removeConnection(connection); ++ if (this._vpnDevice.empty) ++ this._vpnSection.actor.hide(); ++ } else { ++ let devices =3D this['_' + section + 'Devices']; ++ for (let i =3D 0; i < devices.length; i++) ++ devices[i].removeConnection(connection); ++ } + }, + -+ _update_connection: function(connection) { -+ this._connection_removed(connection); ++ _updateConnection: function(connection) { ++ this._connectionRemoved(connection); + -+ let connectionSettings =3D connection.get_setting_by_name('conn= ection'); ++ let connectionSettings =3D connection.get_setting_by_name(Netwo= rkManager.SETTING_CONNECTION_SETTING_NAME); + connection._type =3D connectionSettings.type; + connection._section =3D this._ctypes[connection._type]; + connection._name =3D connectionSettings.id; + connection._uuid =3D connectionSettings.uuid; + + let section =3D connection._section; -+ let devices =3D this['_' + section + 'Devices']; -+ for (let i =3D 0; i < devices.length; i++) { -+ if (devices[i].connectionValid(connection)) { -+ devices[i].addConnection(connection); -+ connection._ever_added =3D true; ++ if (section =3D=3D NMConnectionCategory.VPN) { ++ this._vpnDevice.addConnection(connection); ++ this._vpnSection.actor.show(); ++ connection._everAdded =3D true; ++ } else { ++ let devices =3D this['_' + section + 'Devices']; ++ for (let i =3D 0; i < devices.length; i++) { ++ if (devices[i].connectionValid(connection)) { ++ devices[i].addConnection(connection); ++ connection._everAdded =3D true; ++ } + } + } + }, + -+ _hideAll: function() { -+ for (let i =3D 0; i < this._allSections.length; i++) { -+ let item =3D this._allSections[i]; ++ _hideDevices: function() { ++ for (let i =3D 0; i < this._deviceSections.length; i++) { ++ let item =3D this._deviceSections[i]; + item.actor.hide(); + } + }, @@ -1666,17 +1765,26 @@ index 0000000..a0cd576 + + if (this._wiredDevices.length > 0) + this._wiredSection.actor.show(); ++ else ++ this._wiredSection.actor.hide(); + + if (this._wirelessDevices.length > 0) + this._wirelessSection.actor.show(); ++ else ++ this._wirelessSection.actor.hide(); + + if (this._wwanDevices.length > 0) + this._wwanSection.actor.show(); ++ else ++ this._wwanSection.actor.hide(); + -+ // this._vpnSection.actor.show(); ++ if (!this._vpnDevice.empty) ++ this._vpnSection.actor.show(); ++ else ++ this._vpnSection.actor.hide(); + }, + -+ _sync_nm_state: function() { ++ _syncNMState: function() { + if (!this._client.manager_running) { + log('NetworkManager is not running, hiding...'); + this.menu.close(); @@ -1687,18 +1795,18 @@ index 0000000..a0cd576 + + if (!this._client.networking_enabled) { + this.setIcon('network-offline'); -+ this._hideAll(); ++ this._hideDevices(); + this._statusItem.label.text =3D _("Networking is disabled")= ; + this._statusSection.actor.show(); + return; + } + + this._showNormal(); -+ this._update_icon(); ++ this._updateIcon(); + }, + -+ _update_icon: function() { -+ this._sync_active_connections(); ++ _updateIcon: function() { ++ this._syncActiveConnections(); + let mc =3D this._mainConnection; + let hasApIcon =3D false; + let hasMobileIcon =3D false; @@ -1712,22 +1820,23 @@ index 0000000..a0cd576 + log('NetworkManager is connecting, but we have no Activ= eConnection activating'); + break; + } -+ switch (mc._type) { -+ case 'gsm': -+ case 'cdma': -+ case 'bluetooth': ++ switch (mc._section) { ++ case NMConnectionCategory.WWAN: + this.setIcon('network-cellular-acquiring'); + break; -+ case '802-11-wireless': ++ case NMConnectionCategory.WIRELESS: + this.setIcon('network-wireless-acquiring'); + break; -+ case '802-3-ethernet': -+ case 'pppoe': ++ case NMConnectionCategory.WIRED: + this.setIcon('network-wired-acquiring'); + break; ++ case NMConnectionCategory.VPN: ++ // XXX: there is no network-vpn-acquiring ++ this.setIcon('network-vpn'); ++ break; + default: + this.setIcon('network-error'); -+ log ('Invalid active connection type ' + mc._type); ++ log('Invalid active connection type ' + mc._section); + } + break; + case NetworkManager.State.CONNECTED_LOCAL: @@ -1738,18 +1847,19 @@ index 0000000..a0cd576 + break; + } + let dev; -+ switch (mc._type) { -+ case '802-11-wireless': ++ switch (mc._section) { ++ case NMConnectionCategory.WIRELESS: + dev =3D mc._primaryDevice; + if (dev) { + let ap =3D dev.device.active_access_point; + let mode =3D dev.device.mode; + if (!ap) { + if (mode !=3D NetworkManager['80211Mode'].ADHOC= ) { -+ log ('An active wireless connection, in inf= rastructure mode, involves no access point?'); ++ log('An active wireless connection, in infr= astructure mode, involves no access point?'); + break; + } -+ this.setIcon('network-wireless-connected'); ++ // XXX: there is no network-wireless-connected ++ this.setIcon('network-wireless-signal-excellent= '); + } else { + if (this._accessPointUpdateId && this._activeAc= cessPoint !=3D ap) { + this._activeAccessPoint.disconnect(this._ac= cessPointUpdateId); @@ -1763,20 +1873,19 @@ index 0000000..a0cd576 + } + break; + } else { -+ log ('Active connection with no primary device?'); ++ log('Active connection with no primary device?'); + break; + } -+ case '802-3-ethernet': -+ case 'pppoe': -+ case 'serial': ++ case NMConnectionCategory.WIRED: + this.setIcon('network-wired-symbolic'); + break; -+ case 'bluetooth': -+ // XXX: NetworkManager does not give us signal for blue= tooth -+ this.setIcon('network-cellular-signal-excellent'); -+ break; -+ case 'cdma': -+ case 'gsm': ++ case NMConnectionCategory.WWAN: ++ if (mc._type =3D=3D NetworkManager.SETTING_BLUETOOTH_SE= TTING_NAME) { ++ // XXX: NetworkManager does not give us signal for = bluetooth ++ this.setIcon('network-cellular-signal-excellent'); ++ break; ++ } ++ + dev =3D mc._primaryDevice; + if (this._mobileUpdateId && this._mobileUpdateDevice !=3D= dev) { + this._mobileUpdateDevice.disconnect(this._mobileUpd= ateId); @@ -1788,11 +1897,11 @@ index 0000000..a0cd576 + this.setIcon('network-cellular-signal-' + signalToIcon(= dev.mobileDevice.signal_quality)); + hasMobileIcon =3D true; + break; -+ case 'vpn': ++ case NMConnectionCategory.VPN: + this.setIcon('network-vpn'); + break; + default: -+ log('Invalid active connection type ' + mc._type); ++ log('Invalid active connection type ' + mc._section); + this.setIcon('network-error'); + break; + } @@ -1815,8 +1924,26 @@ index 0000000..a0cd576 + } + } +}; ++ ++function NMMessageTraySource() { ++ this._init(); ++} ++ ++NMMessageTraySource.prototype =3D { ++ __proto__: MessageTray.Source.prototype, ++ ++ _init: function() { ++ MessageTray.Source.prototype._init.call(this, _("Network Manage= r")); ++ ++ let icon =3D new St.Icon({ icon_name: 'network-transmit-receive= ', ++ icon_type: St.IconType.SYMBOLIC, ++ icon_size: this.ICON_SIZE ++ }); ++ this._setSummaryIcon(icon); ++ } ++}; diff --git a/tools/build/gnome-shell.modules b/tools/build/gnome-shell.m= odules -index e8b5493..b14fd53 100644 +index e8b5493..2f44c5d 100644 --- a/tools/build/gnome-shell.modules +++ b/tools/build/gnome-shell.modules @@ -9,6 +9,8 @@ @@ -1828,23 +1955,7 @@ index e8b5493..b14fd53 100644 - - -+ - - -=20 -@@ -255,6 +258,7 @@ - - - -+ - - -=20 -@@ -315,4 +319,19 @@ +@@ -315,4 +317,19 @@ =20 diff --git a/gnome-base/gnome-shell/gnome-shell-9999.ebuild b/gnome-base/= gnome-shell/gnome-shell-9999.ebuild index ef3cd5a..f3a6869 100644 --- a/gnome-base/gnome-shell/gnome-shell-9999.ebuild +++ b/gnome-base/gnome-shell/gnome-shell-9999.ebuild @@ -91,7 +91,7 @@ src_prepare() { ewarn "Adding support for the experimental NetworkManager applet." ewarn "This needs the latest NetworkManager & nm-applet trunk." ewarn "Report bugs about this to 'nirbheek' on #gentoo-desktop @ FreeN= ode." - epatch "${FILESDIR}/${PN}-experimental-nm-applet.patch" + epatch "${FILESDIR}/${PN}-experimental-nm-applet-1.0.patch" fi =20 gnome2_src_prepare diff --git a/net-misc/networkmanager/files/networkmanager-more-gi-annotat= ions.patch b/net-misc/networkmanager/files/networkmanager-more-gi-annotat= ions.patch new file mode 100644 index 0000000..e6bac7d --- /dev/null +++ b/net-misc/networkmanager/files/networkmanager-more-gi-annotations.pa= tch @@ -0,0 +1,43 @@ +From a420d59ea24a1eb82a7c1dc96e3cf5b38b0fd757 Mon Sep 17 00:00:00 2001 +From: Giovanni Campagna +Date: Tue, 22 Feb 2011 23:34:41 +0100 +Subject: [PATCH] libnm-util: another introspection annotation + +nm_utils_ssid_to_utf8 has gchar* in the signature, but it accepts +an array of bytes, not a string. Fix with the appropriate +annotation. + +https://bugzilla.gnome.org/show_bug.cgi?id=3D643011 +--- + libnm-util/nm-utils.c | 9 +++++---- + 1 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c +index 87c5d5f..c2134db 100644 +--- a/libnm-util/nm-utils.c ++++ b/libnm-util/nm-utils.c +@@ -304,7 +304,8 @@ nm_utils_deinit (void) +=20 + /** + * nm_utils_ssid_to_utf8: +- * @ssid: pointer to a buffer containing the SSID data ++ * @ssid: (array length=3Dlen) (element-type guint8): pointer to a buff= er ++ * containing the SSID data + * @len: length of the SSID data in @ssid + * + * WiFi SSIDs are byte arrays, they are _not_ strings. Thus, an SSID m= ay +@@ -330,9 +331,9 @@ nm_utils_deinit (void) + * Again, this function should be used for debugging and display purpos= es + * _only_. + * +- * Returns: an allocated string containing a UTF-8 representation of th= e +- * SSID, which must be freed by the caller using g_free(). Returns NUL= L +- * on errors. ++ * Returns: (transfer full): an allocated string containing a UTF-8 rep= resentation ++ * of the SSID, which must be freed by the caller using g_free(). Re= turns ++ * NULL on errors. + **/ + char * + nm_utils_ssid_to_utf8 (const char *ssid, guint32 len) +--=20 +1.7.4 \ No newline at end of file diff --git a/net-misc/networkmanager/networkmanager-9999.ebuild b/net-mis= c/networkmanager/networkmanager-9999.ebuild index d4bbdd6..686bad1 100644 --- a/net-misc/networkmanager/networkmanager-9999.ebuild +++ b/net-misc/networkmanager/networkmanager-9999.ebuild @@ -133,6 +133,9 @@ src_prepare() { # FIXME: does not apply #epatch "${FILESDIR}/${PN}-0.8.2-shared-connection.patch" =20 + # https://bugzilla.gnome.org/show_bug.cgi?id=3D643011 + epatch "${FILESDIR}/${PN}-more-gi-annotations.patch" + gnome2_src_prepare } =20