captura entrada e envia eventos chave ao mesmo tempo

2

Estou procurando criar um programa de método de entrada simples. Atualmente, eu sou capaz de capturar a entrada de qualquer janela usando as teclas passivas ( agradece ao usuário dirkt! ).

Separadamente, também posso enviar pressionamentos de tecla usando XTestFakeKeyEvent() .

A questão é que não posso colocar essas duas partes juntas. Ao emitir um evento de chave falso, ele é recebido pelo meu programa em vez do aplicativo pretendido que tem foco. Isso ocorre mesmo que meu programa não tenha uma captura passiva no código de chave emitido pelo evento falso. Eu suspeito que isso seja porque estou obtendo eventos da janela raiz, mas se eu não fizer isso, não acho que posso capturar a entrada de outras janelas.

#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;
}
    
por Elfalem 05.11.2017 / 08:37

0 respostas