[英]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.