- Rust 64.9%
- QML 28%
- JavaScript 5.4%
- Just 1.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| config | ||
| omarchy-plugin | ||
| src | ||
| systemd | ||
| .gitignore | ||
| AGENTS.md | ||
| Cargo.lock | ||
| Cargo.toml | ||
| justfile | ||
| README.md | ||
banvik-wireguard-applet
Omarchy bar widget that lists NetworkManager WireGuard connections and
switches them on and off over D-Bus (via the
nmrs crate). No nmcli processes, no output parsing.
- Bar icon: bright while a tunnel is connected, dim otherwise; the tooltip names active tunnels and the current Wi-Fi or Ethernet connection.
- Left click: popup with the current network identity (SSID/BSSID or Ethernet LLDP switch and gateway MAC) and a switch per WireGuard connection (address, endpoint, and a shield icon when the peer takes all traffic).
- Rule editor: click the notepad button beside Current Network, or press
Ein the popup, to openrules.tomlinEDITOR. - Right click /
tin the popup / hero switch: quick toggle. It drops every active tunnel, or raises the most recently used one when none is up. - Keyboard:
↑/↓orj/kto move,Enterto toggle,Escto close.
Install
just install # binary, plugin, and enabled user rules service
omarchy plugin enable banvik.wireguard --before omarchy.network
Connections come from NetworkManager, e.g.
nmcli connection import type wireguard file wg0.conf.
Automatic network rules
Edit ~/.config/banvik-wireguard-applet/rules.toml (or
$XDG_CONFIG_HOME/banvik-wireguard-applet/rules.toml). just install creates
an empty file and enables a single systemd user service. For example:
[default]
connect = ["personal"]
disconnect = ["work"]
[ssid."Office"]
connect = ["personal"]
disconnect = ["work"]
[ssid."Office".bssid."AA:BB:CC:DD:EE:FF"]
connect = ["work"]
disconnect = ["personal"]
[ethernet.lldp."switch-chassis-id"]
connect = ["work"]
disconnect = ["personal"]
[ethernet.mac."11:22:33:44:55:66"]
connect = ["personal"]
disconnect = ["work"]
The service first tries the LLDP chassis ID of the connected switch, then the
router MAC. A matching wired rule takes priority over Wi-Fi. When wired
identity is not yet available, it uses the Wi-Fi rule if one is connected;
otherwise it waits. On Wi-Fi, a matching BSSID entry replaces its SSID entry.
default applies to an unmatched network or when no network is connected.
Names in connect and disconnect refer only to saved WireGuard connections;
UUIDs also work. Missing lists mean no action. Manual switches remain in effect
until the network changes or the rules service restarts.
LLDP must be enabled on the wired NetworkManager profile to receive switch announcements. For example:
nmcli connection modify "Wired connection 1" connection.lldp enable-rx
# Reconnect that profile, then inspect its neighbors:
nmcli device lldp list
Use the reported chassis ID for ethernet.lldp. The applet service never
changes network profile settings or runs nmcli.
After editing the file:
banvik-wireguard-applet --check-rules
systemctl --user restart banvik-wireguard-applet
journalctl --user -u banvik-wireguard-applet -f
Run banvik-wireguard-applet --network-json to see the current SSID, BSSID,
LLDP chassis IDs, and router MAC for writing rules. The router MAC is the
gateway's MAC, not the computer's Ethernet adapter MAC.
The service reads the rules at startup. If the file is invalid, it logs the
error and does not apply actions. just uninstall stops the service and
preserves the rule file.
CLI
banvik-wireguard-applet [--show|--toggle|--hide] popup control (default --show)
banvik-wireguard-applet --json | --watch snapshots (watch re-emits on NetworkManager D-Bus signals)
banvik-wireguard-applet --up|--down|--toggle-tunnel NAME|UUID
banvik-wireguard-applet --quick
banvik-wireguard-applet --check-rules | --rules-service | --network-json
banvik-wireguard-applet --edit-rules
The --watch JSON includes current network identity and is versioned: bump schema_version in src/main.rs
and SCHEMA in omarchy-plugin/Model.js together.
After editing QML, run omarchy restart shell. The plugin directory is a
symlink, and the shell's hot reload does not follow it into this repo.