XTest:XTestFakeKeyEvent基于单个或多个布局的行为有所不同

时间:2017-07-20 12:28:34

标签: input keyboard x11

关于XTestFakeKeyEvent,我遇到了一个小问题。我编写了这个示例程序来演示问题:

#include <stdio.h>
#include <stdlib.h>
#include <X11/X.h>
#include <X11/XKBlib.h>
#include <X11/extensions/XTest.h>
#include <unistd.h>

int main(int argc, const char * argv[]) {
    Display * display;

    //Try to attach to the default X11 display.
    display = XOpenDisplay(NULL);
    if(display == NULL) {
        printf("Error: Could not open display!\n");
        return EXIT_FAILURE;
    }

    KeyCode inject = 29; // Should be XKB_KEY_Y

    sleep(10);

    XTestFakeKeyEvent(display, inject, True, 0);
    XTestFakeKeyEvent(display, inject, False, 0);
    XFlush(display);

    return 0;
}

编译:{{1​​}}

此程序的作用:它连接到X11服务器,等待10秒,然后在键盘上注入键码gcc -o xkb_test xkb_test.c -lX11 -lXtst,这对应于美国键盘上的29键。

现在出现问题:我有一个德语键盘布局(与美国相比,例如z和y被切换),该程序将根据以下条件注入yy

当我在MATE中配置多个布局时注入z(所以我在状态栏中有这个布局切换小程序) 当我在MATE

中只配置了一个布局时,注入z

为什么这种行为有所不同?我怎样才能引发一致的行为?

1 个答案:

答案 0 :(得分:1)

XTestFakeKeyEvent接受密码。密钥代码对应于物理密钥,而不是映射到它们的字符。如果要发送字符,则需要确定它在当前布局中映射到的键。

在现代系统中,您可能会使用Xkb,而Xkb布局则称为组。您可以使用XkbStateRecXkbGetState中获取当前组,然后逐个翻译有效的密钥代码,直到获得所需的密钥为止。

使用Xkb翻译键码可能有点令人生畏,我不知道一个简单的防弹方法。 This SO answer有一个工作例程,它唯一缺少的是该组(它使用group = 0,您需要将其替换为state.group,其中state是您从XkbGetState获得的{{1}} {1}})。

请注意,最终发送的符号取决于当前的班次和大写锁定状态。如果您需要特定的字符大小写,则必须在注入密钥代码之前修改键盘状态。