Skip to content

Commit 722dd35

Browse files
IvanTheGeekclaude
andcommitted
network applet: support multiple simultaneous WireGuard connections
NMDeviceWIREGUARD kept a single _activeConnection slot, but every WireGuard connection is handed the same pseudo-device and _syncActiveConnections called setActiveConnection() once per connection - so each activation overwrote the previous one. With two tunnels up the menu showed one as connected and drew the other as if it were down, and the section switch tore down only one of them and then flipped straight back on. This mirrors what commit 'nm-applet: make visible multiple active vpn connection' (PR #12930) did for NMDeviceVPN: keep a list, assign it once after the sync loop instead of per connection, and deactivate all of them. Rows become a switch each rather than a pick-one list, since WireGuard connections are independent of one another - this is the behaviour requested in the issue. Closes #12178 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent 091fb70 commit 722dd35

1 file changed

Lines changed: 61 additions & 14 deletions

File tree

  • files/usr/share/cinnamon/applets/network@cinnamon.org

files/usr/share/cinnamon/applets/network@cinnamon.org/applet.js

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,8 @@ NMDeviceWIREGUARD.prototype = {
10731073
this.category = NMConnectionCategory.WIREGUARD;
10741074
this._type = NM.SETTING_WIREGUARD_SETTING_NAME;
10751075

1076+
this._activeConnections = [];
1077+
10761078
NMDevice.prototype._init.call(this, client, null, [ ]);
10771079

10781080
// Tests:
@@ -1089,25 +1091,63 @@ NMDeviceWIREGUARD.prototype = {
10891091
},
10901092

10911093
get connected() {
1092-
return !!this._activeConnection;
1094+
return this._activeConnections.length > 0;
10931095
},
10941096

1095-
setActiveConnection: function(activeConnection) {
1096-
if (activeConnection) {
1097-
activeConnection._type = NM.SETTING_WIREGUARD_SETTING_NAME;
1098-
}
1099-
NMDevice.prototype.setActiveConnection.call(this, activeConnection);
1097+
setActiveConnections: function(activeConnections) {
1098+
this._activeConnections = activeConnections || [];
11001099

1101-
this.emit('active-connection-changed');
1100+
this._createSection();
1101+
this.emit('active-connections-changed');
11021102
},
11031103

11041104
_shouldShowConnectionList: function() {
11051105
return true;
11061106
},
11071107

11081108
deactivate: function() {
1109-
if (this._activeConnection)
1110-
this._client.deactivate_connection(this._activeConnection, null);
1109+
for (let ac of this._activeConnections)
1110+
this._client.deactivate_connection(ac, null);
1111+
1112+
this._activeConnections = [];
1113+
},
1114+
1115+
_clearSection: function() {
1116+
if (this.section && this.section.removeAll)
1117+
this.section.removeAll();
1118+
1119+
this._autoConnectionItem = null;
1120+
this._overflowItem = null;
1121+
1122+
for (let i = 0; i < this._connections.length; i++) {
1123+
if (this._connections[i].item && this._connections[i].item.destroy)
1124+
this._connections[i].item.destroy();
1125+
1126+
this._connections[i].item = null;
1127+
}
1128+
},
1129+
1130+
/* A switch per tunnel: WireGuard connections are independent of one another,
1131+
so they are not a pick-one list. */
1132+
_createSection: function() {
1133+
for (let obj of this._connections) {
1134+
let active = this._activeConnections.some(ac => ac.connection == obj.connection);
1135+
1136+
if (!obj.item) {
1137+
obj.item = new PopupMenu.PopupSwitchMenuItem(obj.name, active);
1138+
obj.item.connect('toggled', (item, state) => {
1139+
let activeConnection = this._activeConnections.find(ac => ac.connection === obj.connection);
1140+
1141+
if (!state && activeConnection)
1142+
this._client.deactivate_connection(activeConnection, null);
1143+
else if (state && !activeConnection)
1144+
this._client.activate_connection_async(obj.connection, this.device, null, null, null);
1145+
});
1146+
this.section.addMenuItem(obj.item);
1147+
} else {
1148+
obj.item.setToggleState(active);
1149+
}
1150+
}
11111151
},
11121152

11131153
statusLabel: null,
@@ -1905,9 +1945,9 @@ CinnamonNetworkApplet.prototype = {
19051945
device: new NMDeviceWIREGUARD(this._client),
19061946
item: new NMWiredSectionTitleMenuItem(_("WIREGUARD Connections"))
19071947
};
1908-
this._devices.wireguard.device.connect('active-connection-changed', Lang.bind(this, function() {
1948+
this._devices.wireguard.device.connect('active-connections-changed', () => {
19091949
this._devices.wireguard.item.updateForDevice(this._devices.wireguard.device);
1910-
}));
1950+
});
19111951
this._devices.wireguard.item.updateForDevice(this._devices.wireguard.device);
19121952
this._devices.wireguard.section.addMenuItem(this._devices.wireguard.item);
19131953
this._devices.wireguard.section.addMenuItem(this._devices.wireguard.device.section);
@@ -2149,6 +2189,8 @@ CinnamonNetworkApplet.prototype = {
21492189
if (active._primaryDevice) {
21502190
if (active._type == NM.SETTING_VPN_SETTING_NAME)
21512191
this._devices.vpn.device.setActiveConnections([]);
2192+
else if (active._type == NM.SETTING_WIREGUARD_SETTING_NAME)
2193+
this._devices.wireguard.device.setActiveConnections([]);
21522194
else
21532195
active._primaryDevice.setActiveConnection(null);
21542196

@@ -2170,6 +2212,7 @@ CinnamonNetworkApplet.prototype = {
21702212
let default_ip6 = null;
21712213

21722214
let vpnConnections = [];
2215+
let wireguardConnections = [];
21732216

21742217
for (let a of this._activeConnections) {
21752218
if (!a._inited) {
@@ -2246,17 +2289,21 @@ CinnamonNetworkApplet.prototype = {
22462289
}
22472290

22482291
if (a._primaryDevice) {
2249-
if (a._type == NM.SETTING_VPN_SETTING_NAME) {
2292+
if (a._type == NM.SETTING_VPN_SETTING_NAME)
22502293
vpnConnections.push(a);
2251-
} else {
2294+
else if (a._type == NM.SETTING_WIREGUARD_SETTING_NAME)
2295+
wireguardConnections.push(a);
2296+
else
22522297
a._primaryDevice.setActiveConnection(a);
2253-
}
22542298
}
22552299
}
22562300

22572301
if (this._devices.vpn && this._devices.vpn.device)
22582302
this._devices.vpn.device.setActiveConnections(vpnConnections);
22592303

2304+
if (this._devices.wireguard && this._devices.wireguard.device)
2305+
this._devices.wireguard.device.setActiveConnections(wireguardConnections);
2306+
22602307
this._mainConnection = activated || activating || default_ip4 || default_ip6 || null;
22612308
},
22622309

0 commit comments

Comments
 (0)