fix: 修复 CapsLock 长按松开后未恢复大小写状态的问题
- 长按松开后调用 simulateCapsLock 模拟一次 CapsLock 按键恢复原始状态 - 新增 simulateKeysym 方法,正确处理 X11 keysym → keycode 转换 - Windows 端添加 X11 keysym → VK 虚拟键码映射 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
8c2e787a25
commit
271fccb39b
@ -152,6 +152,8 @@ void VoiceInputService::onHotkeyDeactivated() {
|
|||||||
} else {
|
} else {
|
||||||
// 长按 → 停止录音并转写
|
// 长按 → 停止录音并转写
|
||||||
stopRecordingAndTranscribe();
|
stopRecordingAndTranscribe();
|
||||||
|
// 恢复 CapsLock 原始状态(系统已处理了一次 CapsLock 切换)
|
||||||
|
simulateCapsLock();
|
||||||
}
|
}
|
||||||
|
|
||||||
longPressDetected_ = false;
|
longPressDetected_ = false;
|
||||||
@ -213,9 +215,8 @@ void VoiceInputService::onRecognitionComplete(const QString& text) {
|
|||||||
|
|
||||||
void VoiceInputService::simulateCapsLock() {
|
void VoiceInputService::simulateCapsLock() {
|
||||||
if (impl_->injector && impl_->injector->isInitialized()) {
|
if (impl_->injector && impl_->injector->isInitialized()) {
|
||||||
// CapsLock keysym = 0xffe5
|
// XK_Caps_Lock = 0xffe5,使用 simulateKeysym 自动转换为 keycode
|
||||||
unsigned int capslockKeysym = 0xffe5;
|
impl_->injector->simulateKeysym(0xffe5);
|
||||||
impl_->injector->simulateKeycode(capslockKeysym);
|
|
||||||
LOG_DEBUG(kTag, "模拟 CapsLock 按键已注入");
|
LOG_DEBUG(kTag, "模拟 CapsLock 按键已注入");
|
||||||
} else {
|
} else {
|
||||||
LOG_WARNING(kTag, "文本注入器未初始化,无法模拟 CapsLock");
|
LOG_WARNING(kTag, "文本注入器未初始化,无法模拟 CapsLock");
|
||||||
|
|||||||
@ -178,4 +178,17 @@ bool WaylandTextInjector::simulateKeycode(unsigned int keycode) {
|
|||||||
return true;
|
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
|
} // namespace impress
|
||||||
|
|||||||
@ -30,6 +30,9 @@ public:
|
|||||||
/** @brief 模拟 X11 keycode 按下+释放(用于 CapsLock 等系统按键) */
|
/** @brief 模拟 X11 keycode 按下+释放(用于 CapsLock 等系统按键) */
|
||||||
bool simulateKeycode(unsigned int keycode);
|
bool simulateKeycode(unsigned int keycode);
|
||||||
|
|
||||||
|
/** @brief 模拟 keysym 按下+释放(自动转换为 keycode) */
|
||||||
|
bool simulateKeysym(unsigned long keysym);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void error(const QString& message);
|
void error(const QString& message);
|
||||||
|
|
||||||
|
|||||||
@ -111,4 +111,27 @@ bool WaylandTextInjector::simulateKeycode(unsigned int keycode) {
|
|||||||
#endif
|
#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
|
} // namespace impress
|
||||||
|
|||||||
@ -29,6 +29,9 @@ public:
|
|||||||
/** @brief 模拟 keycode 按下+释放(Windows 使用虚拟键码) */
|
/** @brief 模拟 keycode 按下+释放(Windows 使用虚拟键码) */
|
||||||
bool simulateKeycode(unsigned int keycode);
|
bool simulateKeycode(unsigned int keycode);
|
||||||
|
|
||||||
|
/** @brief 模拟 keysym 按下+释放(X11 keysym,自动映射为 Windows VK 键码) */
|
||||||
|
bool simulateKeysym(unsigned long keysym);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void error(const QString& message);
|
void error(const QString& message);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user