Моя цель - иметь программу, которая спит в фоновом режиме, но может быть активирована пользователем с помощью некоторой «горячей клавиши».Из изучения руководства Xlib и руководства Xlib O'reilly я понял, что правильный путь к этому - с помощью XGrabKey.Однако мое понимание процесса неверно, так как простое доказательство концепции не работает.
Насколько я понимаю, если я вызываю XGrabKey с корневым окном как grab_window, а owner_events false, то всякий раз, когда нажимается моя горячая клавишасобытие будет отправлено только в корневое окно.Если я затем выбираю события KeyPress из корневого окна, а затем прослушиваю события X, я должен получить событие нажатия клавиши при нажатии горячей клавиши.Ниже приведен минимальный пример.
Я ожидаю, что при запуске программы, независимо от того, какое окно имеет фокус, при нажатии Ctrl + Shift + K моя программа должна вывести «Горячая клавиша нажата»!»в консоли, а затем завершите.
Кроме того, я понимаю, что в случае сбоя XGrabKey обработчик ошибок по умолчанию отобразит сообщение, а поскольку это не так, я предполагаю, что вызов выполнен успешно.
Очевидно, мое понимание как-то ошибочно.Может кто-то указать мне верное направление?
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
using namespace std;
int main()
{
Display* dpy = XOpenDisplay(0);
Window root = DefaultRootWindow(dpy);
XEvent ev;
unsigned int modifiers = ControlMask | ShiftMask;
int keycode = XKeysymToKeycode(dpy,XK_Y);
Window grab_window = root;
Bool owner_events = False;
int pointer_mode = GrabModeAsync;
int keyboard_mode = GrabModeAsync;
XGrabKey(dpy, keycode, modifiers, grab_window, owner_events, pointer_mode,
keyboard_mode);
XSelectInput(dpy, root, KeyPressMask );
while(true)
{
bool shouldQuit = false;
XNextEvent(dpy, &ev);
switch(ev.type)
{
case KeyPress:
cout << "Hot key pressed!" << endl;
XUngrabKey(dpy,keycode,modifiers,grab_window);
shouldQuit = true;
default:
break;
}
if(shouldQuit)
break;
}
XCloseDisplay(dpy);
return 0;
}