SDRSync v2.2.9
Mute-on-TX rewritten to use native WebView-level muting instead of per-site JS calls, plus a cluster of real bugs found by two rounds of python-bug-hunter review — most notably a rigctld caching gap that could silently revert a reverse-sync push.
Fixed
- rigctld silent-revert bug (most severe, live-reproduced against real hamlib 4.5.5): rigctld caches the value of a SET for 500ms by default, so a reverse-sync verify poll landing in that window could report success for a rig push that was never actually applied — the WebSDR page showed the change, then it silently reverted up to 30s later with no warning.
connect()now sends\set_cache 0to disable the cache outright. - CW offset (Behaviour setting) going stale after connect — was only read once at driver construction, so changing it mid-session had no effect until a disconnect/reconnect. Now synced live every tick.
- A follow-up bug in that same fix: a blind per-tick CW-offset overwrite looked identical to a genuine WebSDR-page click of the same delta and got pushed to the rig, retuning it. Now only syncs on an actual change, with a forced re-baseline instead of letting the shift be misread as a page edit.
- WebSDR audio muting on teardown was a guaranteed no-op (fire-and-forget call racing a synchronous
close()) — briefly audible after disconnect. Now awaited end-to-end via a new native mute-before-teardown path. - KiwiSDR/OpenWebRX audio-unlock watcher could click the real mouse forever on receivers where clicking is a permanent no-op (measured ~44 real OS-level clicks/minute, indefinitely) — now gives up after 3 ineffective attempts and switches to watch-only.
- Simulated clicks never verified the target window was actually under the cursor — a minimized host frame or anything else covering that screen point still received a real OS-level click. Now confirmed via
wx.FindWindowAtPoint()first. - websdr.org's audio-unlock click wasn't platform-gated on Windows like the other drivers, moving the mouse for no reason on WebView2.
- flrig reverse-sync verify used
rig.get_vfo(a cache read, no live CAT query, and the wrong VFO) — switched torig.get_vfoA, confirmed to do a genuine live read. - "Mouse hijack to enable WebSDR audio" setting was also stale mid-session like CW offset — unchecking it didn't stop an already-running overlay watcher. Now re-checked every iteration.
- Transceiver panel auto-fold now only fires on the user's own Connect click, not any reconnection (idle auto-resume, attach flap, page-death recovery).
_tick()was fetching WebSDRget_status()twice per tick in the steady state; now fetched lazily once.
Changed
- Mute-on-TX: replaced per-site JS mute calls (up to ~1s lag, shared the page-write rate limiter with tuning) with a single native WebView-level mute —
webkit_web_view_set_is_muted()on Linux,ICoreWebView2_8.IsMutedvia raw COM on Windows. Instant, page-independent, identical across all four WebSDR families. - CW offset field relabeled "WebSDR CW offset (Hz)", narrowed to its actual -2000..2000 range, and gained an Apply button so a typed value takes effect without clicking elsewhere first.
Every fix has a regression test confirmed to fail against the pre-fix code before being restored. 487 tests pass (Windows: 480/487 — 7 pre-existing failures are a Linux-only audio-unlock-watcher test gap that doesn't mock sys.platform, not a regression; that watcher is intentionally disabled on Windows).
Windows build: SDRSync-v2.2.9-windows.zip is attached below. Extract and run SDRSync.exe — no installer needed.