Summary
Tracking the architectural follow-up to PR #3279 (merged via admin-merge with my fix-up commit c3ef6e3b). @NF0T's original Blocker 2 in his 2026-06-04 review was that KissTncServer lifetime is owned by Ax25HfPacketDecodeDialog, and the dialog should become a config/status view only with ownership moved to MainWindow. I took the minimum-viable fix in the merged PR (don't set WA_DeleteOnClose on this dialog so closing the window doesn't destroy the server) — transparently noted in the fix-up commit and coordination comment — but the deeper ownership refactor is still worth doing for the reasons @NF0T originally raised.
Why the deeper refactor still matters
The minimum-viable fix solves the user-visible bug (close → kill server) but leaves these architectural rough edges:
-
TX queue + counters + the modem TX path live in the dialog. A KISS frame coming in over TCP requires the dialog to exist to be transmitted on RF. With Start-on-Startup the dialog is constructed at launch, but the conceptual coupling between "TCP server lifecycle" and "modem TX path lifecycle" is inverted from what makes architectural sense — TX is a transport concern, not a UI concern.
-
Slice attachment plumbing is implicit. It works today because MainWindow::setActiveSlice happens to call setAttachedSlice on the dialog (MainWindow.cpp:11701), and that fires on the -1 → first-slice transition too. But this contract isn't documented and a future refactor of setActiveSlice could silently break it.
-
The dialog becoming hidden-but-alive to keep the server running is awkward. It's a config/status view that has to stay constructed for an unrelated transport reason.
Proposed direction
Per @NF0T's original prescription, paraphrased here for the tracking issue:
- Move `KissTncServer`, `m_kissTxQueue`, `m_kissRxCount`/`m_kissTxCount`, and the TX-from-KISS handler to `MainWindow`.
- `MainWindow` reads `TncSettings::startOnStartup()` and constructs/starts the server independently of the dialog.
- The dialog becomes a config/status view: it reads/writes `TncSettings` for its UI, calls `MainWindow::setKissTncEnabled(bool)` / `setKissTncPort(int)`, and subscribes to a `MainWindow::kissTncStatusChanged` signal for the status line.
- Slice add/remove wired at `MainWindow` level so the server (or whichever owns the modem TX path) gets slices directly.
- The trickiest piece is the modem TX path itself (currently `m_shim`, `m_txPaceTimer`, etc. in the dialog). Two reasonable approaches:
- (a) Extract the modem TX state machine into a separate model owned by `MainWindow`. Dialog observes it for UI display.
- (b) Keep modem TX in the dialog as a UI concern (matches current intent — the dialog also handles direct UI TX) but have `MainWindow` forward KISS-originated frames to it. Drop frames silently if dialog isn't constructed (with a log warning).
(a) is cleaner long-term, (b) is closer to the existing structure. @jensenpat's call on the right shape.
Out-of-scope until this is decided
PR #3290 (PMS / PBBS) is stacked on the KISS TNC code from #3279 and was waiting on that PR to clear. It can now rebase against current main and become reviewable independently of this architectural follow-up — the minimum-viable fix in #3279 is sufficient for the PMS PR's needs.
Tagging
@jensenpat — you're the author and have the deepest context. No urgency on this — the user-visible bug is fixed in main, and this is the kind of refactor that benefits from sitting with the design for a few days before committing. Feel free to bounce ideas in the issue or open a draft PR when you're ready.
Principle IX (Surface Only What Survives).
Summary
Tracking the architectural follow-up to PR #3279 (merged via admin-merge with my fix-up commit
c3ef6e3b). @NF0T's original Blocker 2 in his 2026-06-04 review was thatKissTncServerlifetime is owned byAx25HfPacketDecodeDialog, and the dialog should become a config/status view only with ownership moved toMainWindow. I took the minimum-viable fix in the merged PR (don't setWA_DeleteOnCloseon this dialog so closing the window doesn't destroy the server) — transparently noted in the fix-up commit and coordination comment — but the deeper ownership refactor is still worth doing for the reasons @NF0T originally raised.Why the deeper refactor still matters
The minimum-viable fix solves the user-visible bug (close → kill server) but leaves these architectural rough edges:
TX queue + counters + the modem TX path live in the dialog. A KISS frame coming in over TCP requires the dialog to exist to be transmitted on RF. With Start-on-Startup the dialog is constructed at launch, but the conceptual coupling between "TCP server lifecycle" and "modem TX path lifecycle" is inverted from what makes architectural sense — TX is a transport concern, not a UI concern.
Slice attachment plumbing is implicit. It works today because
MainWindow::setActiveSlicehappens to callsetAttachedSliceon the dialog (MainWindow.cpp:11701), and that fires on the -1 → first-slice transition too. But this contract isn't documented and a future refactor ofsetActiveSlicecould silently break it.The dialog becoming hidden-but-alive to keep the server running is awkward. It's a config/status view that has to stay constructed for an unrelated transport reason.
Proposed direction
Per @NF0T's original prescription, paraphrased here for the tracking issue:
(a) is cleaner long-term, (b) is closer to the existing structure. @jensenpat's call on the right shape.
Out-of-scope until this is decided
PR #3290 (PMS / PBBS) is stacked on the KISS TNC code from #3279 and was waiting on that PR to clear. It can now rebase against current main and become reviewable independently of this architectural follow-up — the minimum-viable fix in #3279 is sufficient for the PMS PR's needs.
Tagging
@jensenpat — you're the author and have the deepest context. No urgency on this — the user-visible bug is fixed in main, and this is the kind of refactor that benefits from sitting with the design for a few days before committing. Feel free to bounce ideas in the issue or open a draft PR when you're ready.
Principle IX (Surface Only What Survives).