You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Several widgets across the app use QApplication::doubleClickInterval() (typically 400 ms on Linux, configurable per-platform) to defer single-click actions long enough to detect a double-click. Most prominent example: the RX Controls 🔊 mute button (PR #3006), where single click mutes the current slice and double click mutes all owned slices. The single-click action waits the full interval before firing, so the user perceives ~400 ms of latency on every single click.
Power users who never double-click would prefer instant single-click response; users with slower motor input may want a longer window to reliably register their double-click intent. Right now it's bound to the platform default with no escape hatch.
Call sites today
Found via grep — every widget that uses the click-defer pattern:
All seven currently call QApplication::doubleClickInterval() directly. The values would diverge if a future widget uses a different source — making them all read the same project-wide value also closes that risk.
Range bounds worth picking: minimum ~150 ms (faster than human double-click capability), maximum ~800 ms (anything more starts to feel broken on single-click). 0 is reserved for "no double-click discrimination — fire single-click instantly" which intentionally disables any double-click affordance app-wide.
2. Helper accessor
Add a one-liner in a shared location (probably AppSettings.h or a small InteractionSettings.h):
inlineintclickDiscriminationIntervalMs()
{
auto& s = AppSettings::instance();
return s.value("ClickDiscriminationIntervalMs",
QApplication::doubleClickInterval()).toInt();
}
3. Migrate all seven call sites
Replace every QApplication::doubleClickInterval() call with the helper. Mechanical sweep, no behavior change for users who don't touch the setting.
4. UI surface
Radio Setup → "Behavior" tab (or equivalent) — a spinbox labeled "Single-click delay (ms)" with a hint like:
Time AetherSDR waits after a single click to decide whether you intended a double click. Default uses your OS setting (currently ms). Set 0 to disable double-click affordances entirely and fire single-click actions instantly.
5. Live propagation
Some widgets (e.g. WaveformWidget) cache the interval at construction via m_clickTimer.setInterval(...). Reading the value at click time (start-from-interval-helper-each-time) instead of caching at construction means changes via Settings apply on the next click without a restart. RxApplet's pattern (m_muteClickTimer->start(clickDiscriminationIntervalMs()) at click time) already does this — the others can follow.
Centralizing the value protects against future widget drift.
The double-click vs single-click discrimination pattern will probably keep expanding (e.g. spectrum widget click-to-tune vs double-click-to-edit-frequency); having one knob is the right shape.
Acceptance
AppSettings key added with proper default
Helper accessor in a shared header
All seven existing call sites migrated
UI surface in Radio Setup
Tooltip on the spinbox explaining what it does
Manual test: set to 100, verify mute button responds quickly; set to 0, verify single click is instant and double click no longer triggers all-mute (acceptable — the user opted in)
Background
Several widgets across the app use
QApplication::doubleClickInterval()(typically 400 ms on Linux, configurable per-platform) to defer single-click actions long enough to detect a double-click. Most prominent example: the RX Controls 🔊 mute button (PR #3006), where single click mutes the current slice and double click mutes all owned slices. The single-click action waits the full interval before firing, so the user perceives ~400 ms of latency on every single click.Power users who never double-click would prefer instant single-click response; users with slower motor input may want a longer window to reliably register their double-click intent. Right now it's bound to the platform default with no escape hatch.
Call sites today
Found via grep — every widget that uses the click-defer pattern:
src/gui/RxApplet.cpp— slice mute button (fix(rx): consolidate slice-mute UI — single-click this slice, double-click all #3006)src/gui/StripRxChainWidget.cpp:498src/gui/WaveformWidget.cpp:87src/gui/ClientRxChainWidget.cpp:432src/gui/ClientChainWidget.cpp:595src/gui/StripChainWidget.cpp:595src/gui/StripWaveform.cpp:90All seven currently call
QApplication::doubleClickInterval()directly. The values would diverge if a future widget uses a different source — making them all read the same project-wide value also closes that risk.Proposed shape
1. New AppSettings key
Range bounds worth picking: minimum ~150 ms (faster than human double-click capability), maximum ~800 ms (anything more starts to feel broken on single-click). 0 is reserved for "no double-click discrimination — fire single-click instantly" which intentionally disables any double-click affordance app-wide.
2. Helper accessor
Add a one-liner in a shared location (probably
AppSettings.hor a smallInteractionSettings.h):3. Migrate all seven call sites
Replace every
QApplication::doubleClickInterval()call with the helper. Mechanical sweep, no behavior change for users who don't touch the setting.4. UI surface
Radio Setup → "Behavior" tab (or equivalent) — a spinbox labeled "Single-click delay (ms)" with a hint like:
5. Live propagation
Some widgets (e.g. WaveformWidget) cache the interval at construction via
m_clickTimer.setInterval(...). Reading the value at click time (start-from-interval-helper-each-time) instead of caching at construction means changes via Settings apply on the next click without a restart. RxApplet's pattern (m_muteClickTimer->start(clickDiscriminationIntervalMs())at click time) already does this — the others can follow.Why this is worth doing
Acceptance
References