title: Receive focused widget changing events with X11/Xlib
body: <p>I am currently searching for a way to receive widgets focus change events from X server on Linux OS.</p>
  <p>I have tried using <code>XSelectInput(dpy, focuswin, FocusChangeMask);</code>, but the server notifies me only when the focused window changes, not the focused widget (e.g. a text input) inside a specific window.</p>
  <p>I want to accomplish this in order to show a virtual keyboard whenever an editable text area gains focus.</p>
  <p>The code written until now is:</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;X11/Xlib.h&gt;
  #include &lt;X11/Intrinsic.h&gt;
  
  static Display *dpy;
  static Window focuswin = None;
  
  static void attach_to_focuswin(void) {
      int revert_to = 0;
  
      XGetInputFocus(dpy, &amp;focuswin, &amp;revert_to);
      XSetWindowAttributes attr;
      attr.event_mask = FocusChangeMask;
      XChangeWindowAttributes(dpy, focuswin, CWEventMask, &amp;attr);
  
      if (focuswin != None)
              XSelectInput(dpy, focuswin, FocusChangeMask);
      else
          sleep(1);
  }
  
  static void handle_event(void) {
      XEvent ev;
      char buf[100];
      int len;
  
      XNextEvent(dpy, &amp;ev);
      if (ev.xany.type == FocusOut) {
          focuswin = None;
          fprintf(stdout, &quot;func: handle_event -&gt; focusing out of window\n\n\n&quot;);
      } else if (ev.xany.type == FocusIn) {
          fprintf(stdout, &quot;func: handle_event -&gt; focusing out of window\n\n\n&quot;);
      } else if (ev.xany.type == KeyPress) {
          len = XLookupString(&amp;ev.xkey, buf, 99, 0, 0);
          buf[len] = 0;
          printf(&quot;%s&quot;, buf);
          fflush(stdout);
      } else {
          fprintf(stdout, &quot;func: handle_event -&gt; something else %d\n\n\n&quot;, ev.type);
      }
  }
  
  int main(void) {
  
      dpy = XOpenDisplay(getenv(&quot;DISPLAY&quot;));
  
      if (dpy == NULL) {
          fprintf(stdout, &quot;cannot init display\n&quot;);
          exit(1);
      }
  
      while (1) {
          if (focuswin == None)
              attach_to_focuswin();
          else
              handle_event();
      }
  }
  </code></pre>