Both services fire one status poll when the shell starts, but after a fresh
boot that lands before tailscaled has connected or dropboxd has finished its
respawn dance, leaving the bar icons stale for a full 30s/60s refresh
interval. Re-poll every 2s until the service shows up (or ~30s pass), then
hand off to the normal periodic refresh.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Each panel's hero on/off toggle (Tailscale, Dropbox Wi-Fi, Bluetooth,
network, audio mute) now has a reachable "header" cursor section, a focus
ring around the hero icon, Enter/Space activation, a letter shortcut, and
hover parity. The hero is inset by heroRingPad so the ring stays inside
the Flickable/ScrollView clip box instead of being cut off.
Bluetooth and audio get a virtual "header" section above their device
sections, so the adapter/mute can be toggled by keyboard even when no
device rows exist. Network repurposes its previously dead header section.
For the PanelHero-based panels (Tailscale, Dropbox), route panel state
through the wrapper's `header` id: inside a PanelHero iconComponent `root`
resolves to PanelHero, not the Panel, so `root.headerHasCursor` and
`root.setHeaderCursor()` silently referenced the wrong object.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Click the Dropbox hero icon to pause or resume the daemon (dropbox-cli
stop/start), with a tooltip on hover. When paused, both the hero and the
bar icon grey out and the phrase reads "Syncing paused". The greying is
optimistic so it reacts the instant you click, then reconciles with the
real daemon state once it settles (reverting if the command failed).
Also fix status.py's running detection, which was stuck reporting true:
this dropbox-cli inverts the `running` exit code and reports "isn't
running" (not "not running") when stopped, so the paused state never
showed. Detection now keys off the status text alone.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>