It scanned on the way in and never again, so a radio plugged in ten seconds
late was invisible until MeshTerm was restarted. The worst version of that is
the first run: the screen says no companion devices detected and offers a
network address typed by hand, or quitting. Going to fetch the cable is the
obvious thing to do and it was the one thing that did not work.
The three transports want three different answers, and the reason is cost.
Enumerating serial ports is a SetupAPI walk -- not free, but cheap enough to
repeat every couple of seconds off the event loop without anyone noticing, and
it covers the case this is really about. Bluetooth is a bounded listen, so
"keep scanning" there means keeping the radio listening for as long as the
splash is open, on the handhelds this program exists for, on a battery, on the
screen somebody leaves up while they walk away. It gets a window every fifteen
seconds instead, eight of them, and the count is ignored while the list is
still empty -- an empty splash is precisely where somebody is waiting, and
another listen is the cost of being useful. TCP is not scanned at all, because
it never was: a network companion does not advertise, and its rows are read
from the registry and the profiles, which change only when the reader changes
them.
Only a change redraws. A poll that finds the same ports says nothing, which
matters for somebody part-way through arrowing down the list: a redraw they did
not ask for, on a list that has not moved, is the screen shifting under their
hands for no reason. When it does redraw, `replace_items` keeps their place by
value rather than by index, so a device appearing above the highlight does not
carry the selection with it.
`select_startup` grew a `live` argument to make this possible -- work to do
while the list is on screen, handed a `redraw(items)` rather than the screen
itself, since a caller holding a screen could not repaint it anyway. It is
cancelled when the screen resolves, so nothing outlives the list it was
redrawing and no repaint lands on the PIN prompt or the smoke test that opens
over it.
Fixes: #13
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>