Problem
Fast-follow from #3884 (PTT-hold rebindable key). The momentary keyboard-keying family — PTT (Hold) (m_pttHoldActive) and the CW straight key / paddles (m_cwStraightKeyActive, m_cwLeftPaddleActive, m_cwRightPaddleActive) — has two pre-existing stuck-TX windows where the key-release that should un-key never arrives or never matches:
-
Focus loss / window deactivation while held. If the window loses focus (alt-tab, click another app) while a momentary key is held, the KeyRelease goes elsewhere and the flag stays set → TX stays keyed. There's no auto-unkey on deactivation today; cancelTransmitFromIndicator() is only a manual stop.
-
Modifier-combo binding released modifier-first. shortcutSequenceFromKeyEvent() builds QKeySequence(modifiers | key), so a binding like Ctrl+T released Ctrl-first produces release events (Ctrl, then T) that don't match Ctrl+T → the un-key never fires → TX stuck. Default bindings are plain keys (Space etc.) and are immune.
Both are pre-existing and shared across the momentary-keying handlers (handlePttHoldShortcut / handleCwMomentaryShortcut) — surfaced, not introduced, by #3884.
Proposed fix (Principle VI — fail-safe)
Add a single deactivation safety net: on QEvent::WindowDeactivate / ApplicationStateChanged (and QEvent::FocusOut of the main window), if any momentary keying flag is set, clear it and call requestPttOff() / release the CW key — i.e. always fail to RX when keyboard focus leaves. This closes the focus-loss window for the whole family in one place.
For the modifier-combo case, the simplest robust option is to also un-key on the bound key's KeyRelease matched by key() alone (ignoring modifiers) when a momentary action is active, so releasing any part of the combo stops TX. Alternatively, discourage/validate against binding momentary TX actions to modifier combos in the shortcut editor.
Why
A held transmit key must never strand the transmitter when focus or the key-release is lost — fail-safe to RX is the Principle VI expectation.
Surfaced during review of #3884.
🤖 Generated with Claude Code
Problem
Fast-follow from #3884 (PTT-hold rebindable key). The momentary keyboard-keying family — PTT (Hold) (
m_pttHoldActive) and the CW straight key / paddles (m_cwStraightKeyActive,m_cwLeftPaddleActive,m_cwRightPaddleActive) — has two pre-existing stuck-TX windows where the key-release that should un-key never arrives or never matches:Focus loss / window deactivation while held. If the window loses focus (alt-tab, click another app) while a momentary key is held, the
KeyReleasegoes elsewhere and the flag stays set → TX stays keyed. There's no auto-unkey on deactivation today;cancelTransmitFromIndicator()is only a manual stop.Modifier-combo binding released modifier-first.
shortcutSequenceFromKeyEvent()buildsQKeySequence(modifiers | key), so a binding likeCtrl+Treleased Ctrl-first produces release events (Ctrl, thenT) that don't matchCtrl+T→ the un-key never fires → TX stuck. Default bindings are plain keys (Space etc.) and are immune.Both are pre-existing and shared across the momentary-keying handlers (
handlePttHoldShortcut/handleCwMomentaryShortcut) — surfaced, not introduced, by #3884.Proposed fix (Principle VI — fail-safe)
Add a single deactivation safety net: on
QEvent::WindowDeactivate/ApplicationStateChanged(andQEvent::FocusOutof the main window), if any momentary keying flag is set, clear it and callrequestPttOff()/ release the CW key — i.e. always fail to RX when keyboard focus leaves. This closes the focus-loss window for the whole family in one place.For the modifier-combo case, the simplest robust option is to also un-key on the bound key's
KeyReleasematched bykey()alone (ignoring modifiers) when a momentary action is active, so releasing any part of the combo stops TX. Alternatively, discourage/validate against binding momentary TX actions to modifier combos in the shortcut editor.Why
A held transmit key must never strand the transmitter when focus or the key-release is lost — fail-safe to RX is the Principle VI expectation.
Surfaced during review of #3884.
🤖 Generated with Claude Code