检查按键是否按下:xlib XNextEvent

4

我正在使用xlib来获取键盘输入,我想模拟Windows的getAsynckeystate()函数来检查按钮是否被按下。我尝试使用定时器来修复结果,但仍然存在问题。如果“z”键被按住,该函数应始终返回true,即使同时按下或释放其他键(目前无法正常工作)

以下是代码:

bool KeyboardState::keyPressed(Display* d, Window curFocus,int revert, Window root) {
XEvent ev;
XNextEvent(d, &ev);
clock_t startTime;
switch (ev.type) {
    case FocusOut:
        if (curFocus != root)
            XSelectInput(d, curFocus, 0);

        XGetInputFocus(d, &curFocus, &revert);
        printf("New focus is %d\n", (int) curFocus);

        if (curFocus == PointerRoot)
            curFocus = root;

        XSelectInput(d, curFocus, KeyReleaseMask | FocusChangeMask | KeyPressMask);
        break;

    case KeyPress:
        ks = XLookupKeysym(&(ev.xkey), 0);

        if (ks == XK_z) {

            keyState = true;
            startTime = clock();
        }
        break;
    case KeyRelease:
        if(ks == XK_z && startTime - clock() > 0){

        ks = XLookupKeysym(&(ev.xkey), 0);
            keyState = false;
        }
}
return keyState;
}

1
如果您先使用一个变量然后再给它赋值,您的程序可能会出现轻微的错误行为。此外,用 clock() 函数进行检查是不正确的,原因有很多,而且这种检查本身也是冗余的。按键释放不能早于按键按下。 - n. m.
我无法解析你的句子。在 case KeyRelease 之后,你的程序有一个错误,请修复它。抱歉,我不知道“HOLD KEY”事件是什么以及它因何而闻名。 - n. m.
为了保持像在Windows中这样的按键,例如if(getasynckeystate('z')){},为什么Linux中不能存在相同的东西,难怪没有人使用这个操作系统... - Mercenary_Frank
https://tronche.com/gui/x/xlib/input/XQueryKeymap.html - n. m.
谢谢,它能用了。很抱歉我之前那么生气,我花了一整天的时间找那个函数。 - Mercenary_Frank
显示剩余3条评论
2个回答

3

1
我编写了以下代码片段,以帮助使用多个非修饰键进行键盘快捷键,例如super + up + right
#include <X11/Xlib.h>

// Returns 0 if key is not down;
// A non-zero integer if it is down.
// targetString should be appropriate for XStringToKeysym.
int is_down(Display *dis, char *targetString)
{
    char keys_return[32] = {0};
    KeySym targetSym = XStringToKeysym(targetString);
    KeyCode targetCode = XKeysymToKeycode(dis, targetSym);

    int targetByte = targetCode / 8;
    int targetBit = targetCode % 8;
    int targetMask = 0x01 << targetBit;
    
    XQueryKeymap(dis, keys_return);
    return keys_return[targetByte] & targetMask;
}

我已经发布了一个更完整的示例,其中包含编译说明在GitHub上。您可以在名为X11/keysymdef.h的文件中找到完整的键名列表;在我的Arch电脑上,它位于/usr/include/X11/keysymdef.h。我也发现了一个示例在网上, 它是谷歌搜索“x11 keysymdef”的第二个结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接