From a86b95dd585416a9ae62b232b02c0d62531aecbe Mon Sep 17 00:00:00 2001 From: nevaforget Date: Mon, 30 Mar 2026 19:14:10 +0200 Subject: [PATCH] Add WireGuard support to VPN manager, use nm-applet for auth nm-applet replaces the foot terminal workaround for VPN authentication, providing a proper NetworkManager secret agent. moonarch-vpn now handles both VPN and WireGuard connection types. Waybar indicator switched from tun0 interface check to nmcli active connection query with signal-based instant refresh. --- DECISIONS.md | 6 ++ defaults/bin/moonarch-vpn | 128 ++++++++++++++++++----------------- defaults/xdg/niri/config.kdl | 1 + defaults/xdg/waybar/config | 5 +- 4 files changed, 75 insertions(+), 65 deletions(-) diff --git a/DECISIONS.md b/DECISIONS.md index 8483d18..a0ffcfa 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -24,6 +24,12 @@ - **Tradeoffs**: Walker is newer/less battle-tested than Rofi. Requires separate Elephant daemon with per-provider packages. Dmenu mode lacks Rofi's `-a`/`-u` (active/urgent) and `-mesg` flags. Settings menu (moonarch-setmen) dropped entirely — apps are findable via Walker's app search. - **How**: Walker + Elephant as systemd user services. Native providers replace 5 rofi scripts (launcher, clipboard, bluetooth, volume, sink-switcher). 3 scripts ported to walker dmenu (vpn, cpugov, sink-switcher). Walker theme inherits GTK4 system theme colors (gtk-inherit). Old rofi configs preserved in `legacy/rofi/`. +## 2026-03-30 – Use nm-applet as VPN secret agent, add WireGuard support +- **Who**: Dominik, Ragnar +- **Why**: VPN auth previously spawned a foot terminal for `nmcli --ask`, which was fragile and ugly. WireGuard connections were invisible to the VPN script and Waybar indicator because both only checked for OpenVPN (`tun0` / `vpn` type). +- **Tradeoffs**: nm-applet adds a tray indicator (mitigated with `--indicator` mode which is minimal). Requires nm-applet running at session start. Alternative was gnome-keyring or a custom secret agent — nm-applet is simpler and handles all NM secret types. +- **How**: nm-applet started via niri spawn-at-startup. moonarch-vpn rewritten to support both vpn and wireguard types, uses nm-applet for auth instead of foot terminal, sends notify-send for connect/disconnect results. Waybar VPN module uses `nmcli` active connection check instead of `/proc/sys/net/ipv4/conf/tun0`, plus RTMIN+9 signal for instant updates after toggle. + ## 2026-03-30 – Standardize GTK theme to Colloid-Grey-Dark-Catppuccin - **Who**: Dominik, Ragnar - **Why**: gsettings had `Colloid-Dark-Catppuccin` while config files had `Colloid-Catppuccin` — inconsistent. Grey accent matches the icon theme (Colloid-Grey-Catppuccin-Dark). Explicit `-Dark` variant is more reliable than depending on `prefer-dark` color-scheme setting. diff --git a/defaults/bin/moonarch-vpn b/defaults/bin/moonarch-vpn index c5c89d4..5167966 100755 --- a/defaults/bin/moonarch-vpn +++ b/defaults/bin/moonarch-vpn @@ -1,100 +1,102 @@ #!/usr/bin/env bash # ABOUTME: Walker-dmenu VPN connection manager using NetworkManager (nmcli). -# ABOUTME: Lists VPN connections and toggles them on/off. +# ABOUTME: Lists VPN/WireGuard connections and toggles them on/off with notifications. -# Copyright (C) 2021 Damien Cassou +# Based on rofi-vpn by Damien Cassou +# https://gitlab.com/DamienCassou/rofi-vpn +# Licensed under GPL-3.0-or-later -# Author: Damien Cassou -# Url: https://gitlab.com/DamienCassou/rofi-vpn -# Version: 0.2.0 - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Commentary: - -# This program uses rofi and nmcli to let the user enable/disable VPN -# connections. - -# Code: - -# What to show in front of an active VPN connection: +# Prefixes for active/inactive VPN connections (Nerd Font icons): ACTIVE_PREFIX="󰌘 " - -# What to show in front of an inactive VPN connection: INACTIVE_PREFIX="󰌙 " -# Display on standard output all VPN connections, one per line. An -# active VPN connection is prefixed with `ACTIVE_PREFIX` and an inactive -# one is prefixed with `INACTIVE_PREFIX`. +for cmd in nmcli walker notify-send; do + command -v "$cmd" >/dev/null 2>&1 || { + echo "Error: '$cmd' not found" >&2 + exit 1 + } +done + +# List all VPN and WireGuard connections with active/inactive prefix. function list_vpn_connections() { nmcli --get-values ACTIVE,NAME,TYPE connection show \ - | grep ':vpn$' \ + | grep -E ':(vpn|wireguard)$' \ | sed \ -e "s/^no:/${INACTIVE_PREFIX}/" \ -e "s/^yes:/${ACTIVE_PREFIX}/" \ - -e 's/:vpn$//' + -e 's/:\(vpn\|wireguard\)$//' } -# Take a line as displayed by `list_vpn_connections()` as argument and -# use nmcli to toggle the corresponding connection. +# Remove the known prefix to extract the bare connection name. +function extract_connection_name() { + local result="$1" + result="${result#"$ACTIVE_PREFIX"}" + result="${result#"$INACTIVE_PREFIX"}" + echo "$result" +} + +# Connect a VPN and notify the result. +# Requires nm-applet (or another NM secret agent) for interactive auth. +function connect_vpn() { + local connection="$1" + local feedback + + if feedback=$(nmcli connection up "$connection" 2>&1); then + notify-send "VPN" "Connected to '$connection'" + else + notify-send -u critical "VPN" "Connection failed: $feedback" + fi +} + +# Disconnect a VPN and notify the result. +function disconnect_vpn() { + local connection="$1" + local feedback + + if feedback=$(nmcli connection down "$connection" 2>&1); then + notify-send "VPN" "Disconnected from '$connection'" + else + notify-send -u critical "VPN" "Disconnect failed: $feedback" + fi +} + +# Toggle the VPN connection based on its current state. function toggle_vpn_connection() { local result="$1" local connection - connection=$(extract_connection_name_from_result "${result}") + connection=$(extract_connection_name "$result") - if [[ $result = ${ACTIVE_PREFIX}* ]]; then - feedback=$(nmcli connection down "$connection") - notify-send "VPN Status '$connection'" "$feedback" + if [[ $result = "${ACTIVE_PREFIX}"* ]]; then + disconnect_vpn "$connection" else - foot -a="vpn-prompt" -T="VPN Connection" nmcli connection --ask up "$connection" - #feedback=$(nmcli connection up "$connection") - notify-send "VPN Status '$connection'" "Trying to connect" + connect_vpn "$connection" fi + + pkill -RTMIN+9 waybar 2>/dev/null } -# Take a line as displayed by `list_vpn_connections()` as argument and -# remove `ACTIVE_PREFIX` or `INACTIVE_PREFIX` to only display the -# connection name. -function extract_connection_name_from_result() { - local result="$1" - - # I don't know how to use plain bash to remove the prefix so I'm - # using sed: - # shellcheck disable=SC2001 - sed -e 's/^.* \([^ ]\+\)$/\1/' <<< "$result" -} - -# Execute the `rofi` command. The first argument of the function is -# used as lines to select from. -function start_rofi() { +# Show the VPN picker using Walker. +function pick_connection() { local content="$1" echo -e "$content" | walker -d -p "󰖂 VPN" } -# List the VPN connections and let the user toggle one using rofi. function main() { local connections local result connections=$(list_vpn_connections) - result=$(start_rofi "$connections") - if [ -n "$result" ]; then + if [[ -z "$connections" ]]; then + notify-send "VPN" "No VPN connections configured" + exit 0 + fi + + result=$(pick_connection "$connections") + + if [[ -n "$result" ]]; then toggle_vpn_connection "$result" - else - exit 1 fi } diff --git a/defaults/xdg/niri/config.kdl b/defaults/xdg/niri/config.kdl index c337439..073386b 100644 --- a/defaults/xdg/niri/config.kdl +++ b/defaults/xdg/niri/config.kdl @@ -81,6 +81,7 @@ layout { spawn-at-startup "waybar" spawn-at-startup "dunst" "-conf" "/etc/xdg/dunst/dunstrc" spawn-at-startup "/usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1" +spawn-at-startup "nm-applet" "--indicator" spawn-sh-at-startup "waypaper --restore" // spawn-sh-at-startup "nemo . &> /dev/null &" spawn-sh-at-startup "foot --server" diff --git a/defaults/xdg/waybar/config b/defaults/xdg/waybar/config index f7101c7..1ee0689 100644 --- a/defaults/xdg/waybar/config +++ b/defaults/xdg/waybar/config @@ -367,9 +367,10 @@ "custom/vpn": { "format": "󰖂", "exec": "echo '{\"class\": \"connected\", \"tooltip\": \"VPN Connected\"}'", - "exec-if": "test -d /proc/sys/net/ipv4/conf/tun0", + "exec-if": "nmcli -t -f TYPE,STATE connection show --active | grep -qE '^(vpn|wireguard):'", "return-type": "json", - "interval": 5 + "interval": 5, + "signal": 9 }, "power-profiles-daemon": { "format": "{icon}",