title: How do I bring a processes window to the foreground on X Windows? (C++)
body: <p>I have the PID for the process (and the name), I want to bring it to the front on linux (ubuntu). On mac I would simply do <code>SetFrontProcess(pid)</code>, on windows I'd enumerate the windows, pick out the one I wanted, and call <code>SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);</code> but I'm at a loss of what to do on linux. I've looked at X Lib a bit, but most/all of those functions seem to operate on windows inside your process.</p>
  
  <hr>
  
  <p>Edit: Using bdk's answer I added these helpers to my code to get the Window</p>
  
  <pre><code>bool searchHelper(Display* display, Window w, Atom&amp; atomPID, unsigned long pid, Window&amp; result)
  {
      bool ret = false;
  
      Atom atomType;
      int format;
      unsigned long nItems;
      unsigned long bytesAfter;
      unsigned char* propPID = 0;
      if (Success == XGetWindowProperty(display,w,atomPID,0,1,False,XA_CARDINAL,&amp;atomType,&amp;format,&amp;nItems,&amp;bytesAfter,&amp;propPID))
      {
          if (propPID != 0)
          {
              if (pid == *((unsigned long *)propPID))
              {
                  result = w;
                  ret = true;
              }
              XFree(propPID);
          }
      }
  
      if (ret)
          return ret; //we found we can stop
  
      //check the children of the window
      Window wRoot;
      Window wParent;
      Window *wChild=NULL;
      unsigned nChildren=0;
      if (XQueryTree(display, w, &amp;wRoot, &amp;wParent, &amp;wChild, &amp;nChildren) != 0 )
      {
          for (unsigned i=0; i&lt;nChildren; ++i)
          {
              ret = searchHelper(display, wChild[i], atomPID, pid, result);
              if (ret)
                  break;
          }
      }
      return ret;
  }
  
  bool getWindowFromPid(unsigned long pid, Display* display, Window&amp; result)
  {
      Window window = XDefaultRootWindow(display);
      Atom atomPID = XInternAtom(display, "_NET_WM_PID", true);
      if (atomPID == None)
      {
          qDebug("XInternAtom failure");
          return false;
      }
      return searchHelper(display, window, atomPID, pid, result);
  }
  </code></pre>
  
  <p>Now I get the window successfully, but when I do the following</p>
  
  <pre><code>if (getWindowFromPid(pid,display,window))
  {
      qDebug("Found window ID:%d", window);
      int result = XRaiseWindow(display,window);
      qDebug("XRaiseWindow returned:%d", result);
  }
  </code></pre>
  
  <p>XRaiseWindow returns 1 (BadRequest). The documentation for XRaiseWindow does not mention the return code of BadRequest being a possible result. I'm not sure what is wrong. Am I not allowed to call it for windows in a different process? Is this focus steeling prevention hampering me? Any thoughts?</p>
  
  <p>Edit edit:</p>
  
  <p>So looking at what xwininfo.c does when you call it with -frame I changed my code as follows based on bdk's suggestion.</p>
  
  <pre><code>if (getWindowFromPid(pid,display,window))
      {
          qDebug("Found window ID:%d", window);
  
          //Need the windowmanger frame (or parent) id not window id
          Window root, parent;
          Window *childlist;
          unsigned int ujunk;
          int status = XQueryTree(display, window, &amp;root, &amp;parent, &amp;childlist, &amp;ujunk);
          if (status &amp;&amp; parent &amp;&amp; parent != root)
          {
              qDebug("Found frame window ID:%d",parent);
              window = parent;
          }
  
          XSetWindowAttributes xswa;
          xswa.override_redirect=True;
          int result = XChangeWindowAttributes (display,window,CWOverrideRedirect,&amp;xswa);
          qDebug("XChangeWindowAttributes returned:%d", result);
          result = XRaiseWindow(display,window);
          qDebug("XRaiseWindow returned:%d", result);
      }
      else
          qDebug("unable to find the window for the pid");
  </code></pre>
  
  <p>At this point I do find the window frame ID, but I get a return code of "1" from both XChangeWindowAttributes and XRaiseWindow. Am I just not allowed to modify another process' window?</p>