diff --git a/src/core/voice_input_service.cpp b/src/core/voice_input_service.cpp index 12b9dab..b2943ef 100644 --- a/src/core/voice_input_service.cpp +++ b/src/core/voice_input_service.cpp @@ -39,19 +39,29 @@ VoiceInputService::VoiceInputService(ConfigManager* configManager, , impl_(std::make_unique()) { impl_->sttEngine = sttEngine; + + // 1s 定时器:启动录音 longPressTimer_ = new QTimer(this); longPressTimer_->setSingleShot(true); connect(longPressTimer_, &QTimer::timeout, this, [this]() { - // 长按超时仍未松开 → 确认为长按录音 if (!longPressDetected_) { longPressDetected_ = true; - capsResetDone_ = true; - // 立即复位 CapsLock,不等用户松开 - simulateCapsLock(); emit statusChanged("正在录音..."); } }); + // 3s 定时器:复位 CapsLock 灯(防抖:只在未按下状态下执行) + capsResetTimer_ = new QTimer(this); + capsResetTimer_->setSingleShot(true); + connect(capsResetTimer_, &QTimer::timeout, this, [this]() { + // 如果已经松开(recording_ = false),不执行 + if (recording_) { + capsResetDone_ = true; + simulateCapsLock(); + LOG_DEBUG(kTag, "CapsLock 灯已复位(防抖保护中)"); + } + }); + // 松开后的冷却定时器 cooldownTimer_ = new QTimer(this); cooldownTimer_->setSingleShot(true); @@ -111,6 +121,7 @@ void VoiceInputService::stop() { if (!running_) return; longPressTimer_->stop(); + capsResetTimer_->stop(); cooldownTimer_->stop(); if (impl_->audioCapture) { @@ -146,10 +157,12 @@ void VoiceInputService::onHotkeyActivated() { LOG_DEBUG(kTag, "快捷键激活(按下)"); recording_ = true; longPressDetected_ = false; + capsResetDone_ = false; audioBuffer_.clear(); - // 启动长按定时器 + // 启动 1s 录音确认定时器 + 3s CapsLock 灯复位定时器 longPressTimer_->start(longPressThreshold_); + capsResetTimer_->start(capsResetDelayMs_); // 开始音频采集(后台预采集) int deviceIndex = configManager_->get("audio.input_device").toInt(); @@ -164,6 +177,7 @@ void VoiceInputService::onHotkeyDeactivated() { LOG_DEBUG(kTag, "快捷键停用(松开)"); recording_ = false; longPressTimer_->stop(); + capsResetTimer_->stop(); // 停止音频采集 if (impl_->audioCapture && impl_->audioCapture->isRunning()) { @@ -176,7 +190,7 @@ void VoiceInputService::onHotkeyDeactivated() { simulateCapsLock(); emit statusChanged("短按:切换 CapsLock"); } else { - // 长按 → CapsLock 已在长按阈值时复位,松开后直接开始识别 + // 长按 → CapsLock 已在 3s 定时器时复位,松开后直接开始识别 stopRecordingAndTranscribe(); } diff --git a/src/core/voice_input_service.h b/src/core/voice_input_service.h index 15ca6c3..696b09a 100644 --- a/src/core/voice_input_service.h +++ b/src/core/voice_input_service.h @@ -69,14 +69,16 @@ private: bool longPressDetected_ = false; bool capsResetDone_ = false; // CapsLock 复位后忽略重复 Activated bool cooldownActive_ = false; // 松开后的冷却期,防止立即重新触发 - int longPressThreshold_ = 1000; - int releaseCooldownMs_ = 1000; // 松开后冷却时间 + int longPressThreshold_ = 1000; // 1s 启动录音 + int capsResetDelayMs_ = 3000; // 3s 后复位 CapsLock 灯 + int releaseCooldownMs_ = 1000; // 松开后冷却时间 std::vector audioBuffer_; int audioSampleRate_ = 16000; - QTimer* longPressTimer_ = nullptr; - QTimer* cooldownTimer_ = nullptr; + QTimer* longPressTimer_ = nullptr; // 1s 启动录音 + QTimer* capsResetTimer_ = nullptr; // 3s 复位 CapsLock 灯 + QTimer* cooldownTimer_ = nullptr; // 松开后冷却 void startRecording(); void stopRecordingAndTranscribe();