Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Stage 8d — Network Settings and Hotspot

Why this stage exists

NetworkManager, not Phosh or a compositor, owns Linux connection profiles, radio state, and shared-hotspot routing. Patin already displayed its state but could not change it. This milestone adds a phone-oriented frontend without moving system networking into Patin or 0xin.

Toolkit and Linux mechanisms

Wayland advertises keyboard capability per seat, like pointer and touch. The regular platform now creates those keyboards dynamically and translates xkb press/repeat events into toolkit-owned KeyInput. Adaptive touch-key geometry, drawing, shift, and symbol state initially moved from the lock to patin::keyboard. Stage 8e later corrected that boundary: the special lock keyboard returned to the lock, while normal settings fields use the session OSK.

patin-service-network now distinguishes hardware availability, radio enablement, active signal, and hotspot state. D-Bus supplies live state; NetworkManager’s nmcli frontend handles scans and profile mutations, keeping profile serialization and secrets inside NetworkManager. Errors, including PolicyKit denials, are returned to the UI.

Composition

patin-network-settings was initially a separate overlay process. Its Wi-Fi page provides radio control and scan/connect/disconnect/forget. Cellular has a separate page for the NetworkManager mobile-data toggle and registration state. Hotspot also has its own page for one persistent Patin Hotspot profile using AP mode and IPv4 sharing; SSID, password, open or WPA-personal security, and automatic/2.4/5 GHz band are editable. Stage 8e later changed the process into a managed XDG toplevel without coupling it to 0xin.

The demo bar retains dim Wi-Fi and cellular slots when the relevant runtime capability exists. Tapping a slot launches --page=wifi or --page=cellular, with at most one child per bar. PATIN_NETWORK_SETTINGS_PROGRAM can replace the executable; --page=hotspot is available to other launchers and all three pages remain reachable through tabs. No 0xin-specific code is involved.

Window construction does not perform NetworkManager or nmcli discovery. The first regular shell update loads the status snapshot, hotspot profile, and the existing NetworkManager Wi-Fi cache after the compositor has had a chance to configure and draw the XDG window. The cache is filtered to the connected network and saved profiles that are currently visible; saved profiles that are out of range and unknown nearby networks are not presented as available.

The Wi-Fi page’s explicit Scan for new networks action schedules nmcli --rescan yes for the next shell update. Its label changes to a scanning state before the synchronous operation starts, and successful results replace the filtered list with every discovered network. Thus a radio scan occurs only after user intent and never forms part of perceived launch time.

When connected, Disconnect shares the Wi-Fi radio row on its right. Duplicate access points with the same SSID are collapsed without losing active state: an active BSSID always wins over a stronger inactive BSSID, so the connected label does not depend on scan ordering or signal strength.

Selecting a saved network activates its NetworkManager profile by UUID instead of treating its displayed SSID as a new network. This reuses stored secrets and avoids both unnecessary password prompts and SSID-text lookup ambiguity. After a successful connect, disconnect, or forget operation, the UI updates its active markers or rows immediately; periodic polling still confirms the authoritative NetworkManager state.

Enterprise enrollment, IP/DNS/routes, APN/roaming/SIM editing, multiple hotspots, and a PolicyKit agent are later work.

Verification

Verified locally on 10 August 2026:

$ cargo fmt --all -- --check
(no output, exit 0)

$ cargo test --workspace --all-targets
34 passed, 0 failed

$ cargo clippy --workspace --all-targets --all-features -- -D warnings
Finished, no warnings

$ mdbook build
INFO HTML book written to `/home/vdzee/proj/patin/book`

$ git diff --check
(no output, exit 0)

Unit coverage verifies unavailable-service degradation, escaped scan parsing, credential validation, page selection, keyboard behavior, and bar page routing without changing host network state.

FP5 acceptance

The NetworkManager-backed release targets were built natively and installed on the postmarketOS FP5. The demo installer was corrected to build demo_bar from the root patin package and patin-network-settings from its own package. Before replacement, both previously installed binaries were copied to ~/.local/share/patin/backups/pre-networkmanager-rollback/.

$ cargo build --release --locked --example demo_bar -p patin
Finished `release` profile [optimized]

$ cargo build --release --locked -p patin-network-settings
Finished `release` profile [optimized]

$ timeout 5 patin-network-settings --page=wifi
patin: connected; waiting for the compositor to configure the surface
Terminated (expected smoke-test SIGTERM)

$ systemctl is-enabled NetworkManager && systemctl is-active NetworkManager
enabled
active

$ nmcli -t -f NAME,TYPE connection show --active
Corner:802-11-wireless
Business:gsm
lo:loopback
wt0:wireguard

The activated bar connected to 0xin and reported Wi-Fi at 66%, cellular at 57%, both radios available and enabled, and no active hotspot. Deployment did not alter either active connection. Mobile-data toggling, hotspot activation, joining the hotspot from another device, and reboot persistence remain deliberately pending because those tests disrupt the phone’s live connectivity.