fix: a cluster spot dragged the rig from SUB back to MAIN

Reported on an FTDX101 (F4NBZ): listening on the SUB VFO, clicking a spot moved
the radio to MAIN.

SetSimplexMode is the first thing SetFrequency tries, and it means "receive and
transmit here, simplex" — OmniRig applies that to the MAIN VFO by definition. It
is there because several Icoms ignore direct FreqA/FreqB writes, so it stays for
the main VFO; on SUB it is now skipped entirely and FreqB carries the change.

The generic "Freq" property is skipped on SUB too: on several rig files it IS the
main VFO, so writing it would move the VFO the operator is not using — or pull
them back to it, which is the bug being fixed.

An operator on SUB put themselves there deliberately. A spot click asks for a
frequency, not for a change of VFO — that distinction is the whole fix, and a
test pins which property each VFO state writes.
This commit is contained in:
2026-07-29 16:07:20 +02:00
parent ee1f9ccf35
commit c297f91ca8
3 changed files with 78 additions and 8 deletions
+42
View File
@@ -83,3 +83,45 @@ func TestResolveOmniRigVFOs(t *testing.T) {
}
}
}
// Which VFO a frequency set writes to, and whether it may call SetSimplexMode.
//
// Reported on an FTDX101 (F4NBZ, 2026-07-29): listening on SUB, clicking a
// cluster spot dragged the radio back to MAIN. SetSimplexMode means "receive and
// transmit here, simplex" and OmniRig applies it to the MAIN VFO — so it must
// not be used when the operator is on SUB. They chose that VFO deliberately; a
// spot click asks for a frequency, not for a VFO change.
func TestOmniRigWriteTarget(t *testing.T) {
// Mirrors the decision made in SetFrequency.
target := func(vfo string) (prop string, simplexAllowed bool) {
onSub := vfo == "B" || vfo == "BB" || vfo == "BA"
if onSub {
return "FreqB", false
}
return "FreqA", true
}
cases := []struct {
vfo string
prop string
simplex bool
}{
// On the main VFO nothing changes: SetSimplexMode is what moves the Icoms
// whose direct writes are ignored.
{"", "FreqA", true},
{"A", "FreqA", true},
{"AA", "FreqA", true},
{"AB", "FreqA", true},
// On SUB, write FreqB and leave the VFO selection alone.
{"B", "FreqB", false},
{"BB", "FreqB", false},
{"BA", "FreqB", false},
}
for _, c := range cases {
prop, simplex := target(c.vfo)
if prop != c.prop || simplex != c.simplex {
t.Errorf("VFO %q → write %s, simplex=%v; want %s, simplex=%v",
c.vfo, prop, simplex, c.prop, c.simplex)
}
}
}