XSelectInput 不报告 Button 事件

问题描述 投票:0回答:2

我正在用 C 语言编写一个简单的程序,我想捕获正在发生的所有鼠标和键盘事件。 我尝试使用

XGrabPointer
,但它会导致屏幕锁定,并且我无法访问其他应用程序。 然后我尝试使用
XSelectInput()
,现在我成功接收键盘事件,但我没有收到任何按钮事件。

关于如何做到这一点有什么想法吗?

代码片段如下:

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>

int main(int argc, char **argv)
{
    Display *dpy;
    Window root;

    if((dpy = XOpenDisplay(NULL)) == NULL) {
        perror(argv[0]);
        exit(1);
    }

    root = XDefaultRootWindow(dpy);

    int state;
    XWindowAttributes attributes;
    
    XGetInputFocus(dpy,&root,&state);
    printf("window id = %d\n"); 

    unsigned long event_mask = FocusChangeMask | KeyPressMask |
        KeyReleaseMask | ButtonPressMask  | ButtonReleaseMask;
    XSelectInput(dpy,root,event_mask);

    XEvent ev;

    while(1) {
        XNextEvent(dpy, &ev);
        if(ev.type == ButtonRelease){
            printf("button release\n");
        }

        if (ev.type == KeyPress) {
            printf("keypress event\n");
        }
    }

    return 0;
}
c x11 xlib
2个回答
3
投票

当您使用根窗口时,可能还有其他东西获取事件,为了确保您获取所有事件,您需要抓住鼠标,但没有其他东西会获取事件,因此您需要一种像 q 键那样退出的方法在这个例子中:

#include <stdio.h>
#include <stdlib.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>

int main(int argc, char **argv)
{
    Display *dpy;
    Window root;

    if((dpy = XOpenDisplay(NULL)) == NULL) {
        perror(argv[0]);
        exit(1);
    }

    root = XDefaultRootWindow(dpy);

    XGrabPointer(dpy, root, False, ButtonReleaseMask, GrabModeAsync, 
             GrabModeAsync, None, None, CurrentTime);

    int state;
    XWindowAttributes attributes;

    XGetInputFocus(dpy,&root,&state);
    printf("window id = %d\n"); 

    unsigned long event_mask = KeyReleaseMask | ButtonReleaseMask;
    XSelectInput(dpy,root,event_mask);

    XEvent ev;

    while(1) {
        XNextEvent(dpy, &ev);
        printf("Type: %d\n", ev.type);
        if(ev.type == ButtonRelease){
            printf("button release\n");
        }

        if (ev.type == KeyPress) {
            printf("keypress event\n");
            if (XLookupKeysym(&ev.xkey, 0) == XK_q) {
                exit(0);
            }
        }
    }

    return 0;
}

0
投票

正在寻找解决方案来跟踪按键事件,即使根本没有窗口。我把它留在这里以防万一它可以帮助别人

bool key_is_pressed(KeySym ks) {
    Display *dpy = XOpenDisplay(":0");
    char keys_return[32];
    XQueryKeymap(dpy, keys_return);
    KeyCode kc2 = XKeysymToKeycode(dpy, ks);
    bool isPressed = !!(keys_return[kc2 >> 3] & (1 << (kc2 & 7)));
    XCloseDisplay(dpy);
    return isPressed;
}

bool ctrl_is_pressed() {
    return key_is_pressed(XK_Control_L) || key_is_pressed(XK_Control_R);
}

取自 Check keypress in C++ on Linux

祝你好运

© www.soinside.com 2019 - 2024. All rights reserved.