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