Skip to content

Panadapter shows no split state when split is initiated externally (rigctld / CAT / TCI / front panel) #3726

Description

@K5PTB

Summary

The panadapter's split-pair visualization — red SPLIT on the RX VFO, SWAP on the TX VFO, and the spectrum split-pair — only appears when split is enabled from the GUI. When split is enabled by an external controller (rigctld, SmartCAT TS-2000/Flex, TCI), the panadapter doesn't reflect it, even though TX is correctly on the split slice.

Split via panadapter:

Image

Split via rigctld:

Image

Repro

  1. One radio, slice A (RX) + slice B.
  2. Enable split externally, e.g. over rigctld: set_split_vfo 1 VFOB. TX moves to slice B.
  3. Observe: slice B shows the red TX badge (correct), but both VFOs keep the default grey SPLIT badge and the spectrum doesn't pair them.
  4. Compare: enabling split via the GUI SPLIT button shows red SPLIT on the RX VFO and SWAP on the TX VFO, with the spectrum paired.

Root cause — src/gui/MainWindow.cpp:6146

updateSplitState() gates the split-pair styling on the private GUI flag m_splitActive:

bool isTxSlice = (m_splitActive && s->sliceId() == m_splitTxSliceId);
bool isRxSplit = (m_splitActive && s->sliceId() == m_splitRxSliceId);
w->updateSplitBadge(isTxSlice, isRxSplit);

m_splitActive is set true only by GUI-initiated split (MainWindow_Wiring.cpp:2857, MainWindow_Controllers.cpp:442, MainWindow_Shortcuts.cpp:777). An external split sets the model's TX slice (SliceModel::setTxSlice(true)) but never touches m_splitActive, so updateSplitState() sees no split. The TX badge is correct because it's derived from model state (isTxSlice()); only the SPLIT/SWAP pair badges and the spectrum pairing are flag-driven — so every externally-initiated split is invisible to the panadapter.

Fix direction

  1. Derive the pair from model truth in updateSplitState(): a slice is "TX-in-split" if isTxSlice() and a distinct RX slice exists on its pan; the other is "RX-in-split" — instead of the m_splitActive/m_splitTxSliceId/m_splitRxSliceId flags.
  2. Drive updateSplitState() from model changes — SliceModel::txSliceChanged (RadioModel re-emits at RadioModel.cpp:5126) plus RadioModel::sliceAdded/sliceRemoved — not only the GUI actions.

This makes the panadapter reflect split regardless of initiator and shrinks the GUI's private split state. (Badge logic: VfoWidget.cpp:3157 updateSplitBadge(isTxSlice, isRxSplit).) It's a concrete instance of the slice-lifecycle RFC #3715 — consumers should derive from model truth, not per-consumer state.

Refs #3715.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GUIUser interfacebugSomething isn't workingexternal devicesFlexControl, MIDI, serial port, USB peripheralsmaintainer-reviewRequires maintainer review before any action is takenpriority: lowLow priorityspectrumPanadapter and waterfall

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions