network
NetworkManager: connectivity, Wi-Fi and wired state, scanned access points and join progress.
text {
content = mantle.network:map(function(network)
if network == nil then
return ""
elseif not network.connected then
return "offline"
elseif network.ssid == "Ethernet" then
return "wired"
end
return string.format("%s %d%%", network.ssid or "", network.strength)
end),
}
State
mantle.network:get() returns NetworkState, nil before the first push. A field marked ? may be absent.
mantle.network’s payload.
| Field | Type | Description |
|---|---|---|
available_networks | AccessPointInfo[] | NetworkManager’s visible networks, re-read on every change: one per SSID, at most 20, ordered associated, then saved, then strongest. {} without Wi-Fi hardware. |
connect_error? | JoinError | The last failed connect, or nil before any or after a success. Kept until the next connect, cancel_connect or abort_connect; check its ssid before showing it. |
connected | boolean | A connection carries the default route; false means offline. |
connecting_ssid? | string | The SSID connect is joining, or nil; clears on a verdict or abort_connect. |
ethernet_enabled | boolean | A wired device is activated; set_ethernet_enabled’s read-back, unlike carrier. |
ethernet_ip? | string | The first activated wired device’s IPv4 address without prefix, or nil. |
ethernet_present | boolean | At least one wired device exists, cable or not. |
ethernet_speed | integer | That wired device’s link speed in Mb/s; 0 when unknown or none is activated. |
networking_enabled | boolean | NetworkManager networking is on (NetworkingEnabled). |
password_ssid? | string | The SSID whose connect waits for a password from a network/connect secure field, or nil. Also set after a rejected key; cleared when a join starts or by cancel_connect. |
scanning | boolean | A scan is in flight, from the moment scan is accepted. |
ssid? | string | "Ethernet" when the default route is wired, else the associated SSID, else nil. An association still getting an address has an ssid while connected is false. |
strength | integer | The associated network’s strength, 0 to 100; 0 without a Wi-Fi association. |
wifi_enabled | boolean | Wi-Fi radio power (WirelessEnabled); can be true with no Wi-Fi hardware, see wifi_present. |
wifi_ip? | string | The Wi-Fi device’s IPv4 address without prefix, or nil. |
wifi_present | boolean | A Wi-Fi device exists. |
AccessPointInfo
One scanned network in available_networks.
| Field | Type | Description |
|---|---|---|
active | boolean | The Wi-Fi device is associated with this SSID. |
band | string | "2.4 GHz", "5 GHz", "6 GHz", or empty for a frequency outside those bands. |
saved | boolean | A saved NetworkManager profile names this SSID, so connect asks for no password. |
secure | boolean | Needs a key: WEP, WPA or RSN. |
ssid | string | Network name, "" for hidden networks; one entry per SSID, from its strongest access point. |
strength | integer | Signal strength, 0 to 100. |
JoinError
A failed join, as connect_error.
| Field | Type | Description |
|---|---|---|
message | string | Display text, such as "wrong password" or "network not found". |
ssid | string | The network the join was for. |
Actions
Call each as mantle.network:<action>(arguments...); ? marks an argument you may omit.
| Action | Arguments | Description |
|---|---|---|
set_networking_enabled | enabled: boolean | Turns NetworkManager networking on or off. |
set_wifi_enabled | enabled: boolean | Powers the Wi-Fi radio. |
set_ethernet_enabled | enabled: boolean | false disconnects every wired device; true activates each one’s autoconnect profile, and a device without one stays down. |
scan | Requests a Wi-Fi scan; a no-op without Wi-Fi hardware. | |
connect | ssid: string, hidden: boolean | Joins a network. Without a saved profile, a secured, hidden or out-of-range one sets password_ssid and waits for a key. |
cancel_connect | Drops the password request password_ssid names; a join already running continues. | |
abort_connect | Stops the join connecting_ssid names, deleting a profile the join created. | |
forget | ssid: string | Deletes every saved profile for this SSID. |
disconnect_wifi | Disconnects Wi-Fi; NetworkManager does not autoconnect it again until the next join. |
Backend
| Contract | Behavior |
|---|---|
| Updates | Every manager, device-list, device-state, access-point, association and saved-profile change re-reads the whole state from NetworkManager. A hotplugged adapter rescans the device set |
| Devices | Only the first Wi-Fi device is tracked. Wired fields describe the first activated wired device |
| Toggles | Networking through Enable, Wi-Fi through WirelessEnabled |
| Scan | RequestScan. scanning turns true on the call and false when LastScan moves or NetworkManager refuses |
| Access points | The associated one’s strength is live. The others’ are read when they appear and after each scan, when NetworkManager updates them |
| Connect | A saved profile or an open network in range joins at once. Anything else sets password_ssid and waits for the key from a secure_submit = { capability = "network", action = "connect" } field (secure fields); the key never reaches Lua |
| Join verdict | Watched for up to 45 s. A rejected key sets password_ssid again. A new network’s profile, key included, is saved when the join starts and stays after a rejection; a key retyped for a saved profile reaches disk only once NetworkManager accepts it |
| Abort | abort_connect deletes a profile the join created, else deactivates the join |
| Missing | Stays nil. The next generation’s first read retries |
How do I…
Ask for a Wi-Fi password
Show the field while password_ssid is set. Escape clears a secure field and keeps it armed, then
calls its on_cancel, the place to call cancel_connect:
local asking = mantle.network:map(function(network)
return network ~= nil and network.password_ssid ~= nil
end)
return column {
visible = asking,
spacing = 6,
children = {
text {
content = mantle.network:map(function(network)
return network and network.password_ssid and ("Password for " .. network.password_ssid) or ""
end),
},
textfield {
width = 240,
height = 24,
placeholder = "Password",
secure_submit = { capability = "network", action = "connect" },
on_cancel = function() mantle.network:cancel_connect() end,
},
},
}
Know whether a join worked
A failed connect lands in connect_error:
text {
foreground = "#F38BA8",
content = mantle.network:map(function(network)
local failure = network and network.connect_error
return failure and (failure.ssid .. ": " .. failure.message) or ""
end),
}
Gotchas
| Trap | Fix |
|---|---|
available_networks has a row with ssid == "" | Hidden networks broadcast no name; they merge into one nameless row. Skip it and join hidden networks with connect(ssid, true) |
| A hidden network asks for a password even when open | Its security is unknown until it answers. Enter on the empty field joins it as open |