diff --git a/src/core/voice_input_service.cpp b/src/core/voice_input_service.cpp index 5241e81..d0a43cb 100644 --- a/src/core/voice_input_service.cpp +++ b/src/core/voice_input_service.cpp @@ -152,6 +152,8 @@ void VoiceInputService::onHotkeyDeactivated() { } else { // 长按 → 停止录音并转写 stopRecordingAndTranscribe(); + // 恢复 CapsLock 原始状态(系统已处理了一次 CapsLock 切换) + simulateCapsLock(); } longPressDetected_ = false; @@ -213,9 +215,8 @@ void VoiceInputService::onRecognitionComplete(const QString& text) { void VoiceInputService::simulateCapsLock() { if (impl_->injector && impl_->injector->isInitialized()) { - // CapsLock keysym = 0xffe5 - unsigned int capslockKeysym = 0xffe5; - impl_->injector->simulateKeycode(capslockKeysym); + // XK_Caps_Lock = 0xffe5,使用 simulateKeysym 自动转换为 keycode + impl_->injector->simulateKeysym(0xffe5); LOG_DEBUG(kTag, "模拟 CapsLock 按键已注入"); } else { LOG_WARNING(kTag, "文本注入器未初始化,无法模拟 CapsLock"); diff --git a/src/core/wayland_text_injector.cpp b/src/core/wayland_text_injector.cpp index 07cee05..ce50c85 100644 --- a/src/core/wayland_text_injector.cpp +++ b/src/core/wayland_text_injector.cpp @@ -178,4 +178,17 @@ bool WaylandTextInjector::simulateKeycode(unsigned int keycode) { return true; } +bool WaylandTextInjector::simulateKeysym(unsigned long keysym) { + if (!impl_->display || !impl_->XKeysymToKeycode) return false; + + unsigned int keycode = impl_->XKeysymToKeycode(impl_->display, keysym); + if (keycode == 0) { + LOG_WARNING(kTag, QString("keysym 0x%1 无法转换为 keycode").arg(keysym, 0, 16)); + return false; + } + + LOG_DEBUG(kTag, QString("模拟 keysym 0x%1 → keycode %2").arg(keysym, 0, 16).arg(keycode)); + return simulateKeycode(keycode); +} + } // namespace impress diff --git a/src/core/wayland_text_injector.h b/src/core/wayland_text_injector.h index 171bb0d..79819ea 100644 --- a/src/core/wayland_text_injector.h +++ b/src/core/wayland_text_injector.h @@ -30,6 +30,9 @@ public: /** @brief 模拟 X11 keycode 按下+释放(用于 CapsLock 等系统按键) */ bool simulateKeycode(unsigned int keycode); + /** @brief 模拟 keysym 按下+释放(自动转换为 keycode) */ + bool simulateKeysym(unsigned long keysym); + signals: void error(const QString& message); diff --git a/src/core/win_text_injector.cpp b/src/core/win_text_injector.cpp index 2abdaed..b69105a 100644 --- a/src/core/win_text_injector.cpp +++ b/src/core/win_text_injector.cpp @@ -111,4 +111,27 @@ bool WaylandTextInjector::simulateKeycode(unsigned int keycode) { #endif } +bool WaylandTextInjector::simulateKeysym(unsigned long keysym) { +#ifdef Q_OS_WIN + // X11 keysym → Windows Virtual Key 映射 + WORD vk = 0; + switch (keysym) { + case 0xffe5: vk = 0x14; break; // XK_Caps_Lock → VK_CAPITAL + case 0xffe1: vk = 0x10; break; // XK_Shift_L → VK_SHIFT + case 0xffe2: vk = 0x10; break; // XK_Shift_R → VK_SHIFT + case 0xffe3: vk = 0x11; break; // XK_Control_L → VK_CONTROL + case 0xffe4: vk = 0x11; break; // XK_Control_R → VK_CONTROL + case 0xffe9: vk = 0x12; break; // XK_Alt_L → VK_MENU + case 0xffea: vk = 0x12; break; // XK_Alt_R → VK_MENU + default: + LOG_WARNING(kTag, QString("不支持的 keysym 映射: 0x%1").arg(keysym, 0, 16)); + return false; + } + return simulateKeycode(vk); +#else + (void)keysym; + return false; +#endif +} + } // namespace impress diff --git a/src/core/win_text_injector.h b/src/core/win_text_injector.h index 46809c2..3fc843b 100644 --- a/src/core/win_text_injector.h +++ b/src/core/win_text_injector.h @@ -29,6 +29,9 @@ public: /** @brief 模拟 keycode 按下+释放(Windows 使用虚拟键码) */ bool simulateKeycode(unsigned int keycode); + /** @brief 模拟 keysym 按下+释放(X11 keysym,自动映射为 Windows VK 键码) */ + bool simulateKeysym(unsigned long keysym); + signals: void error(const QString& message);