Search code examples
clinuxhaskellx11xlib

Haskell fetchName from X11 library does not return the name of the window


Having the following Haskell code:

import           Control.Concurrent
import           Data.Time.Clock
import           Debug.Trace
import           Graphics.X11
import           Graphics.X11.Xlib.Extras

main :: IO ()
main = do
  d <- openDisplay ""
  loop d

loop :: Display -> IO ()
loop d = do
  time <- getCurrentTime
  (w, _) <- getInputFocus d
  maybeName <- fetchName d w
  windowAttrs <- getWindowAttributes d w
  print $ show time ++ " Name: " ++ show maybeName ++ " Width: " ++ show (wa_width windowAttrs)
  threadDelay 1000000
  loop d

The window title returned by fetchName is always Nothing.

Haskell X11 library is a wrapper around Xlib

Possibly related issues:


Solution

  • It looks like fetchName isn't always filled in. Instead you need to use the _NET_WM_NAME property:

    import           Control.Concurrent
    import           Data.Time.Clock
    import           Debug.Trace
    import           Graphics.X11
    import           Graphics.X11.Xlib.Extras
    
    main :: IO ()
    main = do
      d <- openDisplay ""
      loop d
    
    loop :: Display -> IO ()
    loop d = do
      time <- getCurrentTime
      (w, _) <- getInputFocus d
      a <- internAtom d "_NET_WM_NAME" False
      p <- getTextProperty d w a
      ps <- wcTextPropertyToTextList d p
      windowAttrs <- getWindowAttributes d w
      print $ show time ++ " Name: " ++ show ps ++ " Width: " ++ show (wa_width windowAttrs)
      threadDelay 1000000
      loop d
    

    This is what XMonad does:

    https://github.com/xmonad/xmonad/blob/8b055621e92e7ade127043e968f50713c15a00a0/src/XMonad/ManageHook.hs#L71-L80