Pulling the USB Bluetooth dongle made BleakScanner raise from inside the main
loop; the exception propagated out of daemon_main, the bg thread died, and the
tray froze on its last state with no recovery (reported: "daemon crashed and
doesn't come back").
Two layers of hardening:
1. main() loop now wraps scan+connect in try/except — adapter-gone errors are
logged, the tray shows Scanning, and it backs off and retries, so replugging
the adapter recovers automatically. CancelledError is re-raised.
2. The tray supervises the asyncio loop: an unexpected crash is logged and the
loop is RESTARTED after a backoff, gated by a quit_evt so Quit still stops
cleanly (and call_soon_threadsafe is guarded against a closed loop).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>