Skip to content

network applet: six correctness fixes, incl. multiple active WireGuard connections - #13911

Open
IvanTheGeek wants to merge 6 commits into
linuxmint:masterfrom
IvanTheGeek:fix/network-applet-correctness
Open

network applet: six correctness fixes, incl. multiple active WireGuard connections#13911
IvanTheGeek wants to merge 6 commits into
linuxmint:masterfrom
IvanTheGeek:fix/network-applet-correctness

Conversation

@IvanTheGeek

@IvanTheGeek IvanTheGeek commented Jul 30, 2026

Copy link
Copy Markdown

Six independent correctness fixes in network@cinnamon.org, one per commit so they can be taken or dropped individually. No new UI.

The bugs

1. updateAccessPoints() never loopsfor (let i = 0; i < accessPoints; i++) compares the index to the array rather than its length, so the body never runs. _accessPoints is left empty and the notify::strength handlers are never reconnected, silently stopping signal-strength updates for that network.

2. splice(pos) truncates the connection listArray.splice(pos) with no delete count removes everything from pos to the end, so removing one connection dropped every connection after it from _connections.

3. The VPN-over-wireless icon never resolvesset_applet_icon_symbolic_name() passes the name through unchanged and sets St.IconType.SYMBOLIC; St appends -symbolic itself at lookup time. The name built here already carried the suffix, so it asked for xsi-network-wireless-signal-<level>-secure-symbolic-symbolic, which does not exist. The panel icon renders as nothing while a VPN is active over wireless. Verified against the shipped icon set:

FOUND    xsi-network-wireless-signal-good-secure-symbolic
MISSING  xsi-network-wireless-signal-good-secure-symbolic-symbolic

The same commit guards active_access_point, which is null on a wireless device that is still activating.

4. _correctStateForTunnel() returns undefined — it falls through without a return when no tun/wireguard connection is active. Only reached from the currently-disabled connectivity check, but wrong either way.

5. An already-connected VPN draws no dot when its row is first built_updateConnectionItemView() takes active as its third argument, but the first-build call omits it, so active is undefined. The row corrects itself on the next redraw, which is why it reads as intermittent. This is likely what #12550 is seeing.

6. Only one WireGuard connection can be active in the UI (#12178) — NMDeviceWIREGUARD kept a single _activeConnection slot, but every WireGuard connection is handed the same pseudo-device and _syncActiveConnections() calls setActiveConnection() once per connection, so each activation overwrites the previous one. With two tunnels up the menu shows one as connected and draws the other as if it were down; the section switch tears down only one and then flips straight back on.

This last one mirrors what #12930 did for NMDeviceVPN — keep a list, assign it once after the sync loop rather than per connection, and deactivate all of them. The VPN section got that treatment; the WireGuard section was left behind.

Rows become a switch each rather than a pick-one list, since WireGuard connections are independent of one another. That is the behaviour asked for in #12178 ("checkboxes instead of the radio items to toggle the Networks independently") and re-confirmed there in February.

Testing

Honest about what was and wasn't done:

  • Built and node --checked against master.
  • Smoke-tested by running this branch's applet.js on Cinnamon 6.6.9, which differs from master only by the four lines of network: Remove stale wireguard connections #13847. With two WireGuard tunnels up simultaneously the applet reported both, each with its own working switch:
    wg active list: [wg-devvps, wg-lab-inet]
    rows: wg-devvps=ON  wg-lab-inet=ON  wg-lab=off  wg-home=off
    
  • Not run on master itself — I don't have a master build here.
  • Bugs 1-5 are reasoned from the code and verified by inspection; 1, 2 and 4 are single-expression fixes.

Closes #12178


Disclosure: I worked on this with Claude (Anthropic's Claude Code). It did the bulk of the code reading, diagnosis and patch authoring, and drafted this write-up; I reviewed the changes and ran them on my own machine before filing. The commits carry a Co-Authored-By: Claude trailer to the same effect. Flagging it so you can weight the review accordingly.

IvanTheGeek and others added 5 commits July 30, 2026 15:07
The loop compared the index against the accessPoints ARRAY rather than its
length, so the body never executed. _accessPoints was left empty and the
notify::strength handlers were never connected, silently stopping signal
strength updates for that network.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Array.splice(pos) with no delete count removes everything from pos to the end
of the array, so removing one connection dropped every connection after it
from _connections.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…point

set_applet_icon_symbolic_name() passes the name through unchanged and sets
St.IconType.SYMBOLIC; St appends '-symbolic' itself during lookup. The name
built here already carried the suffix, so it resolved to
'...-secure-symbolic-symbolic', which does not exist, and the panel icon
rendered as nothing while a VPN was active over wireless.

Also guard active_access_point, which is null on a wireless device that is
still activating.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The function fell through without a return when no tun/wireguard connection
was active, yielding undefined instead of the state it was given.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… first built

_updateConnectionItemView() takes 'active' as its third argument, but the
first-build call omitted it, so a connection that was already up drew no dot
until some later refresh happened to redraw the row.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Best-practices scanner

This is a regex-based check for API usage that can pose security, performance or
maintainability issues, or that may already be provided by Cinnamon. Most findings
are advisory and do not automatically disqualify a pull request.

This check is not perfect and will not replace a normal review.


Found 2 potential issue(s):

⚠️ WARNING

⚠️ lang_bind

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

obj.item.connect('toggled', Lang.bind(this, function(item, state) {

Lang.bind() is deprecated. Use arrow functions (() => {}) or Function.prototype.bind() instead.

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

this._devices.wireguard.device.connect('active-connections-changed', Lang.bind(this, function() {

Lang.bind() is deprecated. Use arrow functions (() => {}) or Function.prototype.bind() instead.


Automated pattern check.

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 linuxmint#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 linuxmint#12178

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@IvanTheGeek
IvanTheGeek force-pushed the fix/network-applet-correctness branch from 77ed2d3 to 722dd35 Compare July 30, 2026 19:17
@IvanTheGeek

Copy link
Copy Markdown
Author

The best-practices scanner findings above are addressed — all of the flagged Lang.bind() uses were in code this PR adds, and they are now arrow functions (which capture this the same way). No new Lang.bind() is introduced; the count in this file actually goes down versus master.

The scanner comment is stale rather than wrong: the workflow re-run is sitting in action_required, since runs from a first-time contributor need maintainer approval. It should clear once someone approves the run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

network@cinnamon.org applet can only show a single active WireGuard connection

1 participant