我正在寻找创建一个简单的输入法程序。目前,我可以使用被动按键抓取从任何窗口捕获输入(感谢用户dirkt!)。
另外,我还可以使用 发送按键XTestFakeKeyEvent()
。
问题是我无法将这两部分放在一起。当发出假按键事件时,它被我的程序接收,而不是具有焦点的预期应用程序。即使我的程序没有被动地获取假事件发出的键码,也会发生这种情况。我怀疑这是因为我从根窗口获取事件,但如果我不这样做,我认为我无法捕获来自其他窗口的输入。
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/extensions/XTest.h>
#include <stdio.h>
int main()
{
Display *display;
Window rootwindow;
XEvent event;
display = XOpenDisplay(NULL);
rootwindow = DefaultRootWindow(display);
XSelectInput(display, rootwindow, KeyPressMask);
unsigned int modifiers[] = {
0,
ShiftMask,
LockMask, //capslock
Mod2Mask, //numlock
ShiftMask | LockMask,
ShiftMask | Mod2Mask,
LockMask | Mod2Mask,
LockMask | Mod2Mask | ShiftMask,
};
int keys [] = {
XKeysymToKeycode(display, XK_A),
XKeysymToKeycode(display, XK_B),
...
XKeysymToKeycode(display, XK_Z)
};
int l;
int m;
for(l = 0; l < sizeof(keys)/sizeof(int); l++){
for(m = 0; m < sizeof(modifiers)/sizeof(unsigned int); m++){
XGrabKey(display, keys[l], modifiers[m], rootwindow, False, GrabModeAsync, GrabModeAsync);
}
}
int repeat = 0;
while (1) {
XNextEvent(display, &event);
if (event.type == KeyPress && event.xkey.send_event == 0) {
printf("KeyPress: keycode %u state %u send-event %d\n", event.xkey.keycode, event.xkey.state, event.xkey.send_event);
fflush(stdout);
if(repeat == 0){ //to avoid infinite loops
repeat = 1;
XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_7), 1, CurrentTime);
XTestFakeKeyEvent(display, XKeysymToKeycode(display, XK_7), 0, CurrentTime);
}
}
}
XCloseDisplay(display);
return 0;
}