diff --git a/src/core/voice_input_service.cpp b/src/core/voice_input_service.cpp index f3fd1e0..b35eb18 100644 --- a/src/core/voice_input_service.cpp +++ b/src/core/voice_input_service.cpp @@ -40,18 +40,15 @@ VoiceInputService::VoiceInputService(ConfigManager* configManager, { impl_->sttEngine = sttEngine; - // 1s 定时器:灯灭 → 开始正式录音 + // 1s 定时器:确认长按 → 开始正式录音(CapsLock 灯保持 ON,识别后复位) longPressTimer_ = new QTimer(this); longPressTimer_->setSingleShot(true); connect(longPressTimer_, &QTimer::timeout, this, [this]() { if (state_ == PreRecording) { - // 复位 CapsLock 灯 - simulateCapsLock(); - // 进入正式录音 state_ = Recording; audioBuffer_.clear(); // 清除预录音期间的静音 emit statusChanged("正在录音..."); - LOG_DEBUG(kTag, "PreRecording → Recording (灯灭,开始录音)"); + LOG_DEBUG(kTag, "PreRecording → Recording (灯保持 ON,开始录音)"); } }); @@ -185,10 +182,9 @@ void VoiceInputService::onHotkeyDeactivated() { state_ = Idle; LOG_DEBUG(kTag, "短按,恢复 CapsLock 灯"); } else if (state_ == Recording) { - // 长按后松开 → 先恢复 CapsLock,再开始识别 - simulateCapsLock(); + // 长按后松开 → 灯保持 ON,等待识别完成后复位 state_ = Idle; - LOG_DEBUG(kTag, "Recording → Idle (松开转写)"); + LOG_DEBUG(kTag, "Recording → Idle (松开转写,灯保持 ON)"); stopRecordingAndTranscribe(); } @@ -207,6 +203,8 @@ void VoiceInputService::onAudioData(const std::vector& samples, int sampl void VoiceInputService::stopRecordingAndTranscribe() { if (audioBuffer_.empty()) { + // 无音频 → 复位 CapsLock 灯 + simulateCapsLock(); emit statusChanged("未检测到音频输入"); return; } @@ -235,6 +233,9 @@ void VoiceInputService::stopRecordingAndTranscribe() { } void VoiceInputService::onRecognitionComplete(const QString& text) { + // 识别完成后,复位 CapsLock 灯 + simulateCapsLock(); + if (text.isEmpty()) { emit statusChanged("识别结果:无语音输入"); return; diff --git a/src/core/voice_input_service.h b/src/core/voice_input_service.h index 7f814aa..cb0625a 100644 --- a/src/core/voice_input_service.h +++ b/src/core/voice_input_service.h @@ -18,13 +18,19 @@ class ConfigManager; * @brief CapsLock 语音输入服务 * * CapsLock 灯作为录音状态指示器: - * 按下 → 灯亮 (PreRecording) → 1s 后灯灭 → 正式录音 (Recording) - * → 松开 → 识别 → 注入 → 复位 CapsLock 状态 + * 按下 → 灯亮 (PreRecording) → 1s 后开始正式录音 (Recording,灯保持亮) + * → 松开 → 识别 → 注入文本 → 复位 CapsLock 灯 + * + * 状态完全通过托盘图标指示: + * 绿色 ○ — 就绪(静默) + * 黄色 ○ — 等待长按确认 + * 红色 ● — 正在录音 + * 橙色 ◉ — 正在识别 * * 状态机: * Idle — 空闲 * PreRecording — 按下,灯亮,等待长按确认 - * Recording — 1s 后灯灭,正式录音(屏蔽 Portal 信号) + * Recording — 1s 后正式录音(屏蔽 Portal 信号,灯保持亮) * Cooldown — 松开后冷却,防止误触 */ class VoiceInputService : public QObject {