Release v1.3.2 - June 2, 2026
πͺΆ NetSpeedTray v1.3.2: Smaller, Lighter, Better Multi-Monitor
A focused release that cuts the installer 24% smaller (106 β 81 MB) and drops idle RAM from ~135 MB to ~40β75 MB β the biggest weight-loss release since launch. The portable zip shrinks even more: 127 β 91 MB (-28%). Also adds a new Preferred Monitor setting, a one-click Support Bundle export for cleaner bug reports, live dark/light mode detection, a Windows 11 stylesheet fix, and hardened the log obfuscator against six previously-leaking PII categories.
β¨ New Features
Preferred Monitor (#72): A new dropdown in Settings β General lets users pin the widget to a specific monitor in multi-monitor setups instead of always landing on the primary taskbar. The setting stores the screen's stable Windows identifier (e.g. \\.\DISPLAY1) and gracefully falls back to primary if the saved monitor is no longer connected.
Export Support Bundle: Replaces the "Export Error Log" button in Settings β Troubleshooting. Bundles your log files, sanitized config, and a system info report (NetSpeedTray version, Windows version, monitor count + resolutions β no display names, no hostname) into a single timestamped zip ready to attach to a GitHub issue. Log content is run through the PII obfuscator one extra time before zipping. App Activity per-process / per-connection data is never included.
GitHub Issue Templates: Bug-report and feature-request templates now require the right context up front (version, Windows build, monitor layout, attached Support Bundle) so triage doesn't stall waiting on follow-up questions.
π Performance
Lower RAM at Idle (β45 to β70%): Moved matplotlib + numpy out of the startup import chain β they now load lazily the first time you open the graph window. Users who never open the graph see idle RAM drop from ~135 MB to ~40β75 MB depending on hardware. Opening the graph still loads matplotlib once-per-session (Python can't unload modules), but most users open the graph rarely.
Smaller Installer (106 β 81 MB, β24%) & Portable Zip (127 β 91 MB, β28%): Trimmed the PyInstaller bundle by excluding Qt subsystems we never import (QtNetwork, QtPdf, Quick/QML, Multimedia, WebEngine, Sql, Designer, Charts, Test, OpenGL, etc.), Pythonwin's MFC runtime (~5 MB), and unused PIL image-format codecs (AVIF, HEIF, etc.). Added UPX compression β the build script auto-downloads UPX if not present.
π¨ UI Improvements
Live Theme Detection (#62): The widget now updates its text color the moment Windows switches between Light and Dark mode, instead of waiting for an app restart. Only affects users with "Automatic" text color enabled (the default). Promised in January β finally shipped.
Better Log Breadcrumbs for Bug Reports: Four state-transition logs in StatsMonitorThread and StatsController now log at INFO level instead of DEBUG, so support-bundle logs include polling interval changes, hardware monitor connections, and primary interface changes without users having to enable verbose logging.
π Bug Fixes
Free-Move Widget Reverts to Primary Screen After Reboot (#133): Dragging the widget to a secondary monitor with Free Move enabled, then restarting, would snap it back to the primary screen. The saved coordinates were validated against the primary screen's geometry (where they're "off-screen") instead of the screen they actually belong to. Now uses QApplication.screenAt() for multi-monitor-aware validation. Disconnected-monitor fallback gracefully repositions to the calculated tray position instead of leaving the widget off-screen.
Settings Dialog Rendering on Windows 10 (#149): Group-box titles ("Font Settings", "Arrow Styling", etc.) were getting clipped at the top, and labels appeared washed-out on dark mode. Root cause: the stylesheet referenced Segoe UI Variable (a Windows 11-exclusive font) without a fallback, so on Windows 10 Qt picked an unrelated default font with different metrics. Added the standard fallback chain 'Segoe UI Variable', 'Segoe UI', sans-serif everywhere and bumped QGroupBox margin-top to fit the bold title.
π‘οΈ Security
PII Obfuscator Hardened (#141): Audited and strengthened the log redaction layer. Closed six previously-leaking categories: compressed IPv6 (the previous regex only matched the rarely-used full 8-group form, not ::1 or fe80::abcd:1234), forward-slash Windows paths (pathlib.Path repr leaks username), hostname, MAC addresses (both colon and dash forms), and Windows network interface GUIDs. Distinct sentinels (<REDACTED_IP>, <REDACTED_MAC>, <REDACTED_GUID>, <REDACTED_PATH>, <REDACTED_HOST>) make it clear what was scrubbed. The console handler now uses the same obfuscator. Dead helpers.setup_logging was removed to prevent accidental wiring of non-obfuscated logging in the future. Test coverage on the formatter: 0 β 31 unit tests, including idempotency and catastrophic-backtracking guards.
π Localization
Korean Translation Polish (#139, closes #122): Merged @VenusGirl's terminology updates (λΌλ²¨βλ μ΄λΈ, λΌμ΄λΈβμ€μκ°, 곡격μ βμ κ·Ήμ , νΌν¬βμ μ ), full Korean translations for the App Activity window and support menu strings, and fixed two bugs found during merge. New TRANSLATORS.md credits @VenusGirl (Korean), @CMTriX (Dutch), @ZeoNish (Russian), and Andrew PoΕΎenel (Slovenian). 100% locale key parity preserved across all 9 supported languages.
π§ͺ Quality Assurance
Test Suite Expanded: 146 β 191 passing unit tests (+45). New coverage includes the PII obfuscator (31 tests), Support Bundle generation (9 tests), multi-monitor position-restore regressions (5 tests), and live theme-change signal wiring.