Skip to content

Latest commit

 

History

History
90 lines (74 loc) · 4.92 KB

File metadata and controls

90 lines (74 loc) · 4.92 KB

Architecture and maintenance baseline

CommTool is a desktop, event-driven communications workbench. main_window.py is still the composition root for the existing UI, but new behavior should live in the domain package that owns it and remain Qt-free whenever practical.

Area Package Boundary
transports transport/ serial, SEGGER J-Link RTT, TCP/UDP, BLE, Virtual; emits bytes/events
protocol protocol/ framing, parsing, checksums, reusable frame templates
automation automation/ replies, triggers, sequences, scripts, action safety
record record/ .ctrec, replay, PCAP export, local session catalog
project project/ .ctproj, presets, operator-panel and device resources
sessions sessions/ per-tab connection, buffers, engines, ownership
UI ui/ Qt widgets/dialogs and presentation adapters only

Rules for new work

  1. Put normalization, validation, indexing, serialization, and policy in a Qt-free module with direct unit tests.
  2. Keep payload ownership in its session. Window-level state is only for resources deliberately shared by a workspace/project.
  3. External actions are deny-by-default and must have bounded concurrency, timeout, import gates, and explicit unsafe overrides.
  4. Persist project resources explicitly; retain their old QSettings mapping until a format migration has shipped and been exercised.
  5. Do not add another large feature directly to main_window.py; add a thin adapter or mixin after the domain API is stable.

Runtime and CI baseline

  • Supported and tested source runtime: Python 3.11–3.13.
  • Compatibility CI: Python 3.11 and 3.13; primary Windows tests: Python 3.12.
  • Runtime dependencies are bounded in requirements.txt and reproduced in CI/release builds through constraints-runtime.txt.
  • RTT uses pylink-square; the Python package is bundled, while the vendor J-Link driver remains an explicit host prerequisite. DLL access is process-serialized.
  • Ruff, compileall, pure-logic tests, platform smoke suites, full Windows tests, and nightly soak/disconnect churn form the delivery gate.

Qt migration boundary

The current release line uses PyQt5/Qt5. New domain modules intentionally avoid Qt, which limits a future Qt6 migration to UI, signals, packaging, and compatibility tests. The migration should be a separate release track: introduce one qt_compat surface, move imports package-by-package, validate high-DPI/tray/network behavior on all three platforms, then switch packaging. Mixing that migration into protocol or transport feature work would make regression attribution unreliable.

Sidebar presentation state (v1.8.1)

ui/sidebar_dock.py owns pin/unpin, hover delay, flyout animation and dismissal. The flyout belongs to the terminal workspace row, and is explicitly hidden when that workspace hides. Its logical visibility is checked relative to the row so ancestor hiding cannot bypass cleanup. main_window.py persists the auto-hide preference and the two-widget splitter state captured before undocking.

Themed dialog policy (v1.8.2)

User-facing popups go through the themed dialog set only: InfoDialog (ui/dialogs.py) for info/error, CommTool._confirm_dlg for two-way confirmation, and CommTool._build_themed_text_input_dialog for single-line prompts. Native QMessageBox and QInputDialog are no longer called anywhere in src/. The pre-window "max sessions" notice in main.py builds an InfoDialog directly and reads language/theme from the profile ini because no main window exists yet. The send box sets setAcceptRichText(False) so paste and drag-drop insert plain text; all other editable text widgets are QPlainTextEdit / QLineEdit, which never accept rich text.

Startup path (v1.8.3)

CommTool.__init__ applies the global stylesheet once, using the theme saved in the profile ini (cb_theme is only restored later by _load_settings). apply_style remembers the last stylesheet it set and skips setStyleSheet plus the full polish_widget_tree pass when the stylesheet is unchanged, so the deferred _on_theme_changed after the event loop starts only refreshes the inline-styled pieces. A real runtime theme switch still re-polishes the tree.

The QApplication-wide eventFilter returns early unless the event type is in _ef_types (the types it actually dispatches on; mouse move/release only when Linux manual resizing is active). New event types handled there must be added to that set.

The J-Link RTT catalog (RttCatalog, thousands of DLL calls that hold the GIL) is held back while _rtt_catalog_hold is set: from construction until the main window's first paintEvent (plus one event-loop turn), with a 2 s fallback for a window that is never shown. Requests during the hold only set _rtt_catalog_wanted; _release_rtt_catalog_hold enumerates only if the connection type is still RTT. The device picker and driver-folder reload clear the hold and enumerate immediately.