Skip to content

Wait for device activation after connection switch - #176

Open
sergey-arkhipov wants to merge 3 commits into
firecat53:mainfrom
sergey-arkhipov:fix-secondary-connection-teardown
Open

sergey-arkhipov wants to merge 3 commits into
firecat53:mainfrom
sergey-arkhipov:fix-secondary-connection-teardown

Conversation

@sergey-arkhipov

Copy link
Copy Markdown

Problem:
When switching to a new Wi-Fi connection that has secondary connections
(VPN, WireGuard, etc.) configured, networkmanager_dmenu exits as soon
as activate_connection_async finishes. NetworkManager then does not
have enough time to properly tear down the previous secondary
connections, leaving them in an inconsistent state.

Solution:
After activate_connection_async completes and LOOP.run() returns,
block until the device actually reaches ACTIVATED state. This matches
the behavior of nmcli connection up. A 30-second safety timeout
prevents the script from hanging.

Changes:

  • process_ap(): call wait_for_device_activated(adapter) after
    LOOP.run() when activating a known connection.
  • New helper wait_for_device_activated(): connects to the device's
    state-changed signal and blocks on the main loop until
    NM.DeviceState.ACTIVATED is reached.

Testing:

  • Tested on [endeavouros / NetworkManager 2.6.3]
  • Confirmed that switching between networks with auto-connect VPN
    correctly triggers teardown and re-establishment of the VPN tunnel.

@firecat53

Copy link
Copy Markdown
Owner

I don't understand exactly what problem this PR is trying to solve? Can you
describe what issue you had and what symptoms you experienced? What does
'inconsistent state' mean?

It also fails to run with these errors and you left debug code in the PR.

✦ ❯ ./networkmanager_dmenu
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: ''
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: '
'
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: ''
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: '
'
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: ''
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: '
'
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: ''
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: '
'
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: ''
TypeError: wait_for_device_activated..on_state_changed() missing 1 required positional argument: '
'
^CTraceback (most recent call last):

Please provide a clear description and fix the errors or I will close.

@sergey-arkhipov
sergey-arkhipov force-pushed the fix-secondary-connection-teardown branch from b13b1f6 to 22c3225 Compare September 9, 2026 20:27
@sergey-arkhipov

Copy link
Copy Markdown
Author

You're right, sorry — leftover debug notify() calls and a bug in
on_state_changed's signature (5 positional params, but the
state-changed signal only passes 4: device, new_state, old_state,
reason). Fixed both, plus a timer leak (timeout source wasn't removed
after LOOP.run() returned).

Re: the actual issue — reliably reproducible:

  1. Connected to Wi-Fi A with a secondary VPN, working fine.
  2. Switch to Wi-Fi B via networkmanager_dmenu, which also has its
    own secondary VPN configured to auto-activate.
  3. Wi-Fi switches fine, but the VPN on B does NOT auto-activate.
    Only comes up if I start it manually afterwards.

This patch fixes it by blocking until the device reaches ACTIVATED
before the script exits, instead of exiting right after the
activation request is accepted. Might not be the "correct" fix at
the NM level, but it's a reliable workaround — open to a better
approach if you see one.

@firecat53

firecat53 commented Sep 10, 2026

Copy link
Copy Markdown
Owner

Can you post (redacted) output of

nmcli -f connection.secondaries connection show <wifi-B>
nmcli -f connection.type,connection.autoconnect connection show <wifi-B-VPN>

I don't easily have the ability to create secondary connections, so trying to make sure your config matches what I'd expect. Thanks

sergey-arkhipov and others added 2 commits September 9, 2026 18:43
Ensures NetworkManager has time to tear down secondary
connections (VPN, etc.) before the script exits.
@firecat53
firecat53 force-pushed the fix-secondary-connection-teardown branch from 22c3225 to 40d5cb0 Compare September 10, 2026 02:50
@firecat53

Copy link
Copy Markdown
Owner

Sorry, it was not as hard as I thought to test with a secondary connection. I was getting a crash message TypeError: argument cancellable: Expected Gio.Cancellable, but got int every time nmdm ran and changed connections. I re-worked the PR to fix that and to include a notification if the connection+secondary don't successfully activate.

I tested with openvpn secondaries attached to two different wifi networks and switched back and forth between the two. Seems to work now. I did see the issue you were describing without the fix. Thanks for reporting!

Please test the revised PR.

@sergey-arkhipov

Copy link
Copy Markdown
Author

Hi firecat53,

Tested your revised PR — the AP-switch case works now.

However, I'm seeing the same issue when switching via a saved
connection (not a new AP scan/selection) — the secondary VPN
doesn't auto-activate there either.

Looks like the same root cause in a different path: saved
connections go through process_vpngsm() (create_saved_actions →
_create_vpngsm_actions), which never calls
wait_for_device_activated() after activating. Might need the
device pulled from the resulting ActiveConnection there too, since
device isn't passed into activate_connection_async in that path.

@firecat53

Copy link
Copy Markdown
Owner

Ok, another fix pushed. Let me know if it works for you. Thanks!

@sergey-arkhipov

Copy link
Copy Markdown
Author

Thanks, firecat53! Tested both the AP-switch and saved-connection
cases — everything works as expected now. Appreciate you taking
the time to dig into this. Looking forward to the release 🙂

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.

2 participants