Search code examples
haskellx11pid

X11 lib - How to obtain PID of the current window?


How to obtain PID of the current window using X11 lib?

I tried checking the _NET_WM_PID property of the window and its parents and it was always unset.


Solution

  • In the end, I figured out what I was doing wrong. Code adapted from ARBTT:

    getParent :: Display -> Window -> IO Window
    getParent dpy w = do
      (_, parent, _) <- queryTree dpy w `catchIOError` const (return (0,0,[]))
      return parent
    
    followTreeUntil :: Display -> (Window -> IO Bool) -> Window -> IO Window
    followTreeUntil dpy cond = go
      where go w = do
              match <- cond w
              if match
                then return w
                else
                  do p <- getParent dpy w
                     if p == 0 then return w
                               else go p
    
    getFocusedWindowPID :: Display -> IO String
    getFocusedWindowPID d = do
      (w, _) <- getInputFocus d
      wt <- followTreeUntil d (hasCorrectPID d) w
      getWindowPID d wt
    
    getWindowPID :: Display -> Window -> IO String
    getWindowPID d w = do
      nWP <- internAtom d "_NET_WM_PID" False
      pid' <- getWindowProperty32 d nWP w
      let pid = case pid' of
                  Just [pid''] -> show pid''
                  _            -> ""
      return pid
    
    hasCorrectPID :: Display -> Window -> IO Bool
    hasCorrectPID d w = do
      pid <- getWindowPID d w
      return $ pid /= ""
    
    printPIDs :: IO ()
    printPIDs = do
      d <- openDisplay ""
      pid <- getFocusedWindowPID d
      print pid
      closeDisplay d
      threadDelay 1000000
      printPIDs
    

    This will display the PID of the focused window once every second.