title: Global Hotkey with X11/Xlib
body: <p>My goal is to have a program that sleeps in the background but can be activated by the user via some "hotkey". From digging around the Xlib manual and the Xlib O'reilly manual, I gather that the correct way to to this is with XGrabKey. However my understanding of the process is incorrect as a simple proof of concept does not work.</p>
  
  <p>My understanding is that if I call XGrabKey with the root window as the grab_window, and owner_events false, then whenever my hotkey is pressed the event will be sent <em>only</em> to the root window. If I then select KeyPress events from the root window, and then listen for X events, I should get a key press event when the hotkey is pressed. I've pasted a minimal example below.</p>
  
  <p>What I expect is that when the program is run, regardless of what window has focus, if Ctrl+Shift+K is pressed, my program should output "Hot key pressed!" in the console, and then terminate.</p>
  
  <p>Furthermore, it is my understanding that if the XGrabKey fails, the default error handler will display a message, and since it does not I am assuming that the call succeeds.</p>
  
  <p>Obviously, my understanding is flawed somehow. Can anyone point me in the right direction? </p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;X11/Xlib.h&gt;
  #include &lt;X11/Xutil.h&gt;
  
  
  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, &amp;ev);
          switch(ev.type)
          {
              case KeyPress:
                  cout &lt;&lt; "Hot key pressed!" &lt;&lt; endl;
                  XUngrabKey(dpy,keycode,modifiers,grab_window);
                  shouldQuit = true;
  
              default:
                  break;
          }
  
          if(shouldQuit)
              break;
      }
  
      XCloseDisplay(dpy);
      return 0;
  }
  </code></pre>