From d4db8756b5fa714e3b15b56fd6f231ae3db98b01 Mon Sep 17 00:00:00 2001 From: impressionyang Date: Thu, 11 Jun 2026 14:32:07 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=9D=BE=E5=BC=80=20CapsLock=20?= =?UTF-8?q?=E5=90=8E=201s=20=E5=86=B7=E5=8D=B4=E6=9C=9F=E5=86=8D=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=E4=B8=8B=E6=AC=A1=E6=8C=89=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 cooldownTimer_ 和 cooldownActive_ 标志, 松开后启动 1s 冷却定时器,期间忽略所有 Activated 信号, 防止快速连续操作导致的重复触发。 Co-Authored-By: Claude Opus 4.7 --- src/core/voice_input_service.cpp | 21 +++++++++++++++++++++ src/core/voice_input_service.h | 3 +++ 2 files changed, 24 insertions(+) diff --git a/src/core/voice_input_service.cpp b/src/core/voice_input_service.cpp index 7796847..12b9dab 100644 --- a/src/core/voice_input_service.cpp +++ b/src/core/voice_input_service.cpp @@ -51,6 +51,14 @@ VoiceInputService::VoiceInputService(ConfigManager* configManager, emit statusChanged("正在录音..."); } }); + + // 松开后的冷却定时器 + cooldownTimer_ = new QTimer(this); + cooldownTimer_->setSingleShot(true); + connect(cooldownTimer_, &QTimer::timeout, this, [this]() { + cooldownActive_ = false; + LOG_DEBUG(kTag, "冷却期结束,恢复 CapsLock 检测"); + }); } VoiceInputService::~VoiceInputService() { @@ -103,6 +111,7 @@ void VoiceInputService::stop() { if (!running_) return; longPressTimer_->stop(); + cooldownTimer_->stop(); if (impl_->audioCapture) { impl_->audioCapture->stop(); @@ -115,6 +124,7 @@ void VoiceInputService::stop() { recording_ = false; longPressDetected_ = false; capsResetDone_ = false; + cooldownActive_ = false; audioBuffer_.clear(); LOG_INFO(kTag, "语音输入服务已停止"); @@ -127,6 +137,12 @@ void VoiceInputService::onHotkeyActivated() { return; } + // 冷却期内 → 忽略 + if (cooldownActive_) { + LOG_DEBUG(kTag, "忽略 Activated(冷却期内)"); + return; + } + LOG_DEBUG(kTag, "快捷键激活(按下)"); recording_ = true; longPressDetected_ = false; @@ -166,6 +182,11 @@ void VoiceInputService::onHotkeyDeactivated() { longPressDetected_ = false; capsResetDone_ = false; + + // 启动冷却期,1s 内忽略新的 Activated + cooldownActive_ = true; + cooldownTimer_->start(releaseCooldownMs_); + LOG_DEBUG(kTag, QString("冷却期启动 (%1ms)").arg(releaseCooldownMs_)); } void VoiceInputService::onAudioData(const std::vector& samples, int sampleRate) { diff --git a/src/core/voice_input_service.h b/src/core/voice_input_service.h index cb4880f..15ca6c3 100644 --- a/src/core/voice_input_service.h +++ b/src/core/voice_input_service.h @@ -68,12 +68,15 @@ private: bool recording_ = false; bool longPressDetected_ = false; bool capsResetDone_ = false; // CapsLock 复位后忽略重复 Activated + bool cooldownActive_ = false; // 松开后的冷却期,防止立即重新触发 int longPressThreshold_ = 1000; + int releaseCooldownMs_ = 1000; // 松开后冷却时间 std::vector audioBuffer_; int audioSampleRate_ = 16000; QTimer* longPressTimer_ = nullptr; + QTimer* cooldownTimer_ = nullptr; void startRecording(); void stopRecordingAndTranscribe();