我的xlib代码可以监听键盘事件,但它在某些窗口中失败
我有这个代码来监听活动窗口的键盘事件:
#include<X11/Xlib.h>
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
#include <thread>
using namespace std;
#define IR_MODE 8192
#define SHIFT_MODE 16
#define US_MODE 0
static int ErrorHandler (Display *display, XErrorEvent *error)
{
cout<< "An error ocurred. We don't know anything.";
return 0;
}
int main()
{
Display *d = XOpenDisplay(0);
if(d == 0)
{
cout<< "Cannot open displayn";
exit(0);
}
Window root = DefaultRootWindow(d);
XSetErrorHandler(ErrorHandler);
Window current_window;
int rev;
XGetInputFocus(d,¤t_window,&rev);
XSelectInput(d,current_window, KeyPressMask | KeyReleaseMask | FocusChangeMask);
while(true)
{
XEvent e;
XNextEvent(d, &e);
switch(e.type)
{
case FocusOut:
XGetInputFocus(d,¤t_window,&rev);
if(current_window == PointerRoot || current_window == None)
{
current_window = root;
}
XSelectInput(d,current_window, KeyPressMask | KeyReleaseMask | FocusChangeMask);
break;
case KeyPress:
{
cout<< "key pressedn";
break;
}
case KeyRelease:
cout<< "key releasedn";
break;
}
}
XCloseDisplay(d);//*/
}
它适用于很多窗口。 但它在某些窗口中失败,特别是对于侏儒应用程序,例如鹦鹉螺。 为什么会发生这种情况,我该如何解决这个问题?
该程序只是试图听不到任何干扰的键盘。 就好像键盘有点不同:程序不打算丢失语言布局信息。 当按下某个键时,根据语言布局选择一些包括ASCII码的信息并将其附加到键盘事件上,然后发送键盘事件。 该计划需要附加信息的关键事件。 所以该程序并不打算抓住键盘。 它不关心主动或重点窗口。 即使程序的窗口没有激活,它也会试图收听按键。 有些程序使用XQueryKeymap
进行定期检查,但我不打算使用它。 因为它耗尽了CPU,那么它将不仅仅是一个公平的倾听者。 另外如果检查不频繁,某些键可能会逃脱。
我猜你的程序不能用于使用xinput2的GTK3窗口。 如果GTK3是在没有--disable-xinput
情况下构建的,那么这是真的。
AFAIK XSelectInput()
不适用于xinput2,您需要XISelectEvents()
用于此类窗口。
查看Mutter来源的meta_core_select_events()
函数。 它适用于xinput2和传统窗口。 这个补丁可能也有帮助。
上一篇: My xlib code can listen to keyboard events but it fails for some windows
下一篇: How do international keyboards work with JavaScript keyboard events?