Я пытаюсь создать программу, которая реагирует на нажатия клавиш пользователя для отображения информации на экране.
Мне удалось создать окно для отображения информации, но у меня проблемы с захватом нажатий клавиш - или, более конкретно, захватом нажатий клавиш при запуске программы не непосредственно с моего терминала.
Если я просто запускаю его как ./program
, нажатия клавиш регистрируются, как и ожидалось, но если я запускаю его из сопоставления sxhkd, оно не работает.
Я собрал урезанный версия программы без отображения информации для иллюстрации проблемы:
#include <X11/Xlib.h>
#include <stdlib.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,
0, 0, InputOnly,
CopyFromParent,
0, NULL);
XSetWindowAttributes winattr;
winattr.override_redirect = 1;
XChangeWindowAttributes(display, window, CWOverrideRedirect, &winattr);
XGrabKeyboard(display, rootwindow, False, GrabModeAsync, GrabModeAsync, CurrentTime);
XMapWindow(display, window);
XSelectInput(display, rootwindow, KeyPressMask | KeyReleaseMask );
while (1)
{
XNextEvent(display, &event);
/* keyboard events */
if (event.type == KeyPress)
{
printf( "KeyPress: %x\n", event.xkey.keycode );
system("echo test >> ~/output");
/* exit on ESC key press */
if ( event.xkey.keycode == 0x09 )
break;
}
else if (event.type == KeyRelease)
{
printf( "KeyRelease: %x\n", event.xkey.keycode );
}
}
XUngrabKeyboard(display, CurrentTime);
XUnmapWindow(display, window);
XCloseDisplay(display);
return 0;
}
Вы можете создать ее с помощью gcc main.c -o program -lX11 -lXfixes -lXtst
.
Если вы запустите ./program
в своем терминале, вы должны увидеть Распечатывается информация KeyPress и KeyRelease, и вы можете остановить программу с помощью ES C.
Но если вы сопоставите его с сочетанием клавиш где-то, чтобы он не запускался таким образом, программа не будет реагировать на нажатия клавиш и не выйдет на ES C (вам потребуется чтобы убить его вручную).
Я думаю, виновник устанавливает override_redirect
для созданного окна, но мне нужно это сделать, поскольку я не хочу, чтобы программа открывала новое управляемое окно, а наложила .
Я не совсем уверен, в чем проблема, поэтому, возможно, потребуется исправить заголовок этого вопроса.
Возможно ли то, чего я пытаюсь достичь? И если так, что я делаю не так?
lsof
вывод:
0r CHR 1,3 0t0 2051 /dev/null
1w CHR 1,3 0t0 2051 /dev/null
2w REG 8,3 3590712 524358 /home/eyfl/.xsession-errors
3u unix 0x00000000648e641e 0t0 4028921 type=STREAM
4u unix 0x00000000f842df04 0t0 24192 /tmp/bspwm_0_0-socket type=STREAM