Skip to content

Fix ShackSwitch button stale visibility in top-right tray#2456

Merged
ten9876 merged 1 commit into
aethersdr:mainfrom
nigelfenton:fix/shackswitch-button-visibility
May 9, 2026
Merged

Fix ShackSwitch button stale visibility in top-right tray#2456
ten9876 merged 1 commit into
aethersdr:mainfrom
nigelfenton:fix/shackswitch-button-visibility

Conversation

@nigelfenton

Copy link
Copy Markdown
Contributor

Summary

The SS button in the AppletPanel top-right tray could remain visible in three scenarios where no ShackSwitch was actually present:

  1. Fresh install / no SS configuredm_ssBtn had no hide() after creation (unlike m_agBtn at the same site), so the button was always shown at startup regardless of whether a SS device existed or was configured.
  2. User cleared SS_ManualIp via the Peripherals tab — the row's Connect handler bailed early on empty input, so the saved IP could only be overwritten with another IP, never wiped.
  3. User edited the IP field and closed the dialog without clicking the row button — IP edits were only persisted via Connect/Disconnect, so a clear-and-close did nothing.

Changes

File Change
src/gui/AppletPanel.cpp Hide m_ssBtn on creation, mirroring m_agBtn. UDP discovery and the connected signal still re-show it when a real SS is detected.
src/gui/RadioSetupDialog.cpp Generalise the row Connect/Disconnect handler so an empty-IP click clears the persisted ipKey/portKey. Settings are wiped before disconnectFn() so downstream visibility handlers see the cleared state. Add a closeEvent saver list — each peripheral row registers a saver that treats "cleared previously-saved IP" as an implicit clear on dialog close. Non-empty edits still require an explicit Connect click.
src/gui/RadioSetupDialog.h Add m_peripheralRowSavers member + <QVector> include.
src/gui/MainWindow.cpp New disconnected-signal handler hides the SS button when the disconnecting device was a ShackSwitch and no SS_ManualIp remains. presenceChanged(false) is never emitted on a normal disconnect, so this bridges the gap.

The empty-IP-clear behaviour is generic across all four Peripherals rows (TGXL, PGXL, AG, SS), not just ShackSwitch.

Test plan

  • Fresh launch with no SS configured → SS button hidden
  • SS_ManualIp set → auto-connect on radio connect → SS button shows
  • UDP-discovered SS (real Uno Q hardware broadcasting name=ShackSwitch) → SS button appears within ~5s
  • Clear IP field, click Disconnect → settings wiped, button hidden, no auto-reconnect on next launch
  • Clear IP field, close dialog without clicking → settings still wiped (close-event saver path)
  • Edit IP to a new value, close dialog without clicking → no persist (still requires explicit Connect)
  • Build clean on Windows (Qt 6.10.3 + MSVC), Linux (Qt 6.2.4), macOS (Qt 6.11)

🤖 Generated with Claude Code

@ten9876

ten9876 commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Claude here — thanks for the careful work, Nigel. The ShackSwitch button visibility fix is solid: three legitimate failure modes identified, the empty-IP-wipe-before-disconnect ordering is exactly right, the closeEvent saver pattern is a nice touch, and the new MainWindow disconnected handler bridging the missing presenceChanged(false) is the kind of detail that's easy to miss. That part is mergeable as-is.

But the diff also includes a substantial undisclosed change: TciServer gains a QUdpSocket on UDP port 40002 that listens for AETHERPAD? broadcasts and replies with AETHERSDR ip=... tci=..., plus a CHANGELOG entry advertising it as a TCI LAN discovery responder for your aether_pad Arduino keypad project. The PR title and description don't mention this feature at all — a reviewer reading 'Fix ShackSwitch button stale visibility' has no reason to expect AetherSDR's network surface is being expanded.

Two issues with the bundle:

1. Hidden scope. Visibility fix and a network discovery responder are independent concerns. They should be reviewed and decided separately — particularly because the discovery protocol is specific to one external hardware project. Whether AetherSDR should host that protocol footprint in core is a real design question that deserves an explicit discussion, not silent merging.

2. CI didn't run. No checks reported on the branch — likely a fork-permissions setup. The TCI changes touch network code that benefits from build / check-windows / analyze coverage; we'd want all four gates green before merging anything that opens a new socket.

Could you split this into two PRs?

  • PR A: just the diff to AppletPanel.cpp, MainWindow.cpp, RadioSetupDialog.{h,cpp} (the button visibility fix). Drop the CHANGELOG addition — release notes land in the next release-prep PR, not in feature PRs. This one we can merge promptly once CI runs.

  • PR B: just the TciServer.cpp/h discovery responder, with title and description explicitly describing what it is, ideally referencing or filing an issue first to discuss whether AetherSDR should host external-project discovery protocols and what its security/firewall implications are (UDP port 40002 listener on every install).

Sorry for the friction — the ShackSwitch fix is good work and we want to land it cleanly without the bundled scope question slowing it down.

73, Jeremy KK7GWY & Claude (AI dev partner)

The SS button in the AppletPanel top-right tray could remain visible
in three scenarios where no ShackSwitch was actually present:

1. **Fresh install / no SS configured** — button always created visible
   because, unlike m_agBtn (hidden after creation), m_ssBtn had no
   matching hide() call. Hide it on creation; UDP discovery and
   connected-signal handlers re-show it when a real SS appears.

2. **Cleared SS_ManualIp via Peripherals tab** — the row's Connect
   button bailed early on empty input, so users could only overwrite
   the saved IP, never wipe it. Generalise the click handler so an
   empty IP at click time clears the persisted ipKey/portKey, and
   when also connected disconnects in the same step. Settings are
   now wiped *before* the disconnect signal so MainWindow's
   visibility handler reads the cleared state.

3. **Edited IP and closed dialog without clicking the row button** —
   add a closeEvent saver list. Each peripherals row registers a
   saver lambda that, on close, treats "user cleared a previously-
   saved IP" as an implicit clear. Non-empty edits still require an
   explicit Connect click so partially-typed IPs cannot leak in.

MainWindow gains a disconnected-signal handler that hides the SS
button when the device that disconnected was a ShackSwitch and no
SS_ManualIp remains saved. presenceChanged(false) is never emitted
on a normal disconnect, so this bridges the gap.

Generic across peripherals rows (TGXL, PGXL, AG, SS) — empty-IP
clear behaviour applies to all four. New in-class member
m_peripheralRowSavers in RadioSetupDialog.h.

Verified on Windows (Qt 6.10.3 + MSVC), Linux (Qt 6.2.4), macOS
(Qt 6.11). All three platforms build clean; UDP discovery still
auto-detects a real SS the moment its beacon arrives.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ten9876 ten9876 force-pushed the fix/shackswitch-button-visibility branch from ad797ae to 9cbb128 Compare May 8, 2026 23:37
@ten9876

ten9876 commented May 8, 2026

Copy link
Copy Markdown
Collaborator

Claude here — went ahead and split this myself rather than block on the original ask, Nigel. The branch is now rebased onto current main with just the ShackSwitch button visibility commit (9cbb1280) on top — the TCI LAN discovery responder commit and the CHANGELOG addition have been dropped from this PR.

The button visibility fix stands on its own merits and is clean to merge:

  • Fresh-install m_ssBtn->hide() mirroring m_agBtn at AppletPanel.cpp
  • Empty-IP-wipe-before-disconnect ordering at RadioSetupDialog.cpp
  • closeEvent saver pattern via m_peripheralRowSavers
  • New MainWindow disconnected handler bridging the missing presenceChanged(false)

Build clean locally. CI re-running — if check-windows still skips on your branch we may admin-merge once Linux + analyze + check-paths are green.

The TCI LAN discovery responder for aether_pad is a separate design question (whether AetherSDR should host an external-project-specific UDP discovery protocol on every install). When you're ready, please open it as a fresh PR with title and description matching its actual scope, and ideally an issue first to discuss the design implications. Happy to review when it lands.

Authorship of this PR's commit is preserved (you're still the author on 9cbb1280); the rebase only dropped the unrelated commit. Thanks for the careful work on the button fix.

73, Jeremy KK7GWY & Claude (AI dev partner)

@ten9876 ten9876 merged commit 4485af7 into aethersdr:main May 9, 2026
5 checks passed
@ten9876

ten9876 commented May 9, 2026

Copy link
Copy Markdown
Collaborator

Claude here — thanks for the patience while we worked through the scope split, Nigel. The four bits that landed are all genuinely useful: explicit defensive hide on creation, empty-IP-wipe ordering before synchronous disconnect, closeEvent saver pattern for the edit-without-Connect path, and the MainWindow disconnected handler bridging the missing presenceChanged(false) signal. Authorship preserved on the squash commit. Merged.

The TCI LAN discovery responder for aether_pad is welcome as a separate PR whenever you're ready — would appreciate an issue first to discuss whether AetherSDR should host external-project discovery protocols on every install (it's a real design question, not a hard no).

73, Jeremy KK7GWY & Claude (AI dev partner)

@nigelfenton

Copy link
Copy Markdown
Contributor Author

Thanks again for the merge. Opened #2502 to discuss the discovery design before any code — covers the concern you raised plus a proposal that I think threads the needle. No rush on a response.

@nigelfenton nigelfenton deleted the fix/shackswitch-button-visibility branch May 9, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants