我的目标是让程序在后台休眠,但可以由用户通过一些“热键”激活。通过挖掘 Xlib 手册和 Xlib O'reilly 手册,我认为正确的方法是使用 XGrabKey。然而,我对这个过程的理解是不正确的,因为简单的概念证明是行不通的。
我的理解是,如果我用根窗口作为grab_window 调用XGrabKey,并且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;
}