Estou tentando capturar todas as entradas de teclado com base no código de esta resposta . A captura real de chaves está funcionando bem. No entanto, a execução do código no Linux Mint Cinnamon causa outros problemas:
- Não consigo arrastar ou redimensionar nenhuma janela usando o mouse
- Clicar nas opções da barra de menus em xed e nemo (arquivo, visualização, etc ...) não abre as opções de submenu
- Clicar no menu Iniciar exibe a lista de aplicativos, mas o foco é mantido pela janela atrás dele, portanto, não posso passar o mouse, rolar ou clicar nos itens da lista de aplicativos.
Uma versão simplificada, mas funcional, do código segue. Reduzi a causa para a presença da máscara de evento StructureNotifyMask
em XSelectInput
. Sem essa máscara de evento, nenhum dos problemas acima está presente. Mas isso também significa que o programa não é notificado quando a janela é mapeada e, portanto, a captura não funciona.
Como posso obter a captura para funcionar sem nenhuma das questões acima? Eu tentei incluir um segundo XSelectInput
após o programa ser notificado do mapeamento que tem apenas a tecla pressionada e liberar máscaras de evento. No entanto, isso não parece resolver o problema.
#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <stdio.h>
int main()
{
Display *display;
Window window, rootwindow;
XEvent event;
KeySym escape;
display = XOpenDisplay(NULL);
rootwindow = DefaultRootWindow(display);
window = XCreateWindow(display, rootwindow,
-99, -99, 1, 1, /* x, y, width, height */
0, 0, InputOnly, /* border, depth, class */
CopyFromParent, /* visual */
0, NULL); /* valuemask and attributes */
XSelectInput(display, window, StructureNotifyMask | KeyPressMask | KeyReleaseMask);
XMapWindow(display, window);
do {
XNextEvent(display, &event);
} while (event.type != MapNotify);
XGrabKeyboard(display, window, False, GrabModeAsync, GrabModeAsync, CurrentTime);
escape = XKeysymToKeycode(display, XK_Escape);
printf("\nPress ESC to exit.\n\n");
fflush(stdout);
while (1) {
XNextEvent(display, &event);
if (event.type == KeyPress) {
printf("KeyPress: keycode %u state %u\n", event.xkey.keycode, event.xkey.state);
fflush(stdout);
} else
if (event.type == KeyRelease) {
printf("KeyRelease: keycode %u state %u\n", event.xkey.keycode, event.xkey.state);
fflush(stdout);
if (event.xkey.keycode == escape)
break;
} else {
printf("Event type %d\n", event.type);
fflush(stdout);
}
}
XUngrabKeyboard(display, CurrentTime);
XDestroyWindow(display, window);
XCloseDisplay(display);
return 0;
}