[英]X11/Xlib: virtual keyboard input and keyboard mapping synchronization issue
对于自动化测试应用程序,我必须将大量 unicode 键盘输入模拟到旧的 X11 应用程序(我没有任何源代码访问权限)。 我的程序通过标准输入从 UCS-2 LE 编码的输入流中获取输入,基本操作如下:
XDisplayKeycodes
、 XGetKeyboardMapping
、 XkbGetState
)XkbLockModifiers
)n
唯一符号,其中n
是XDisplayKeycodes
返回的可能键码的数量。XChangeKeyboardMapping
在n
可用的 KeyCode 上映射这n
唯一的 X11 KeySymXTestFakeKeyEvent
为所有排队的 KeySym 键入正确的XTestFakeKeyEvent
基本上,这个系统比我目前见过的任何虚拟 X11 键输入工具工作得更好,性能也更高。
但是,有一个问题我目前只能使用丑陋的延迟来解决:
与任何其他 X11 应用程序一样,在我的应用程序成功更改键盘映射表后,目标应用程序会收到来自 X 服务器的MappingNotify
(request==Keyboard) 事件。 X11 客户端的通常响应是调用XRefreshKeyboardMapping
来更新 Xlib 对新键盘布局的了解。
现在,如果客户端在处理其 X11 事件队列时有一些滞后,则XRefreshKeyboardMapping
调用可能会返回一个太新的映射,该映射在未来已经是几代太远了。 例如,当目标应用程序刚刚到达处理其 XEvent 队列处理程序中的第二个MappingNotify
事件时,我的输入生成器已经完成了第四个XChangeKeyboardMapping
。 实际上它应该得到第二代地图,当时在X服务器上不再可用。
不幸的是,键盘MappingNotify
事件中没有地图 id 或任何类型的版本,因此XRefreshKeyboardMapping
可以引用特定地图……而且 X 服务器似乎也没有保留历史记录。
结果是 X11 应用程序的KeyCode
到KeySym
转换以无效布局运行并生成错误的 KeySym。
所以基本上我必须等到所有客户端(或至少是具有输入焦点的客户端)请求并收到我的最后一个XChangeKeyboardMapping
映射,然后我才能执行下一个XChangeKeyboardMapping
。
我可以在XChangeKeyboardMapping
之前使用延迟来修复 99.9% 的错误,并且该延迟是通过一些丑陋的巫术(击键次数等)计算出来的,如果必须达到 100% 的准确度,则该延迟会很高。
所以我的问题是是否有任何方法以编程方式通知或检查 X11 客户端是否已完成XRefreshKeyboardMapping
或其地图是否与服务器地图同步?
如果没有,有没有办法通过 xlib 获取另一个 X11 客户端的当前映射(检查映射是否是当前的)?
感谢您的任何提示!
我过去在 Windows 上做过类似的事情。 我有幸使用SendInput
函数,该函数接受带有 KEYEVENTF_UNICODE 标志的 KEYBDINPUT 结构。 不幸的是,X11 不支持 Unicode 字符的直接按键合成。
由于我还不能发表评论,我不得不给出一个建议作为答案:
您是否考虑过使用剪贴板来将您的“ unicode 输入”传输到此 X11 应用程序的输入字段中?
如果该应用程序使用支持此功能的工具包,您也可以考虑使用直接 Unicode 输入:
例如,基于 GTK+ 的程序(包括所有 GNOME 应用程序)支持 Unicode 输入。
按住Ctrl
+ Shift
并键入u
后跟 Unicode 十六进制数字,然后再次释放Ctrl
和Shift
。
我想使用 Xtest 扩展来合成这些序列应该很容易。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.