Haskell 来自 X11 库的 fetchName 没有 return window 的名称
Haskell fetchName from X11 library does not return the name of the window
具有以下 Haskell 代码:
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
fetchName返回的window标题总是Nothing
。
Haskell X11 library is a wrapper around Xlib
可能相关的问题:
- window 的宽度正确或值为
1
。
- XFetchName always returns 0
看起来 fetchName
并不总是填写。相反,您需要使用 _NET_WM_NAME
属性:
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
这就是 XMonad 所做的:
最后我不得不将 Brian 的回答改编为 XMonad 中更完整的定义(因为某些 windows 抛出异常):
import Control.Exception.Extensible (SomeException (..),
bracket)
import qualified Control.Exception.Extensible as E
import Graphics.X11
import Graphics.X11.Xlib.Extras
getWindowTitle :: Display -> IO String
getWindowTitle d = do
(w, _) <- getInputFocus d
let getProp =
(internAtom d "_NET_WM_NAME" False >>= getTextProperty d w)
`E.catch` \(SomeException _) -> getTextProperty d w wM_NAME
extract prop = do l <- wcTextPropertyToTextList d prop
return $ if null l then "" else head l
bracket getProp (xFree . tp_value) extract `E.catch` \(SomeException _) -> return ""
具有以下 Haskell 代码:
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
fetchName返回的window标题总是Nothing
。
Haskell X11 library is a wrapper around Xlib
可能相关的问题:
- window 的宽度正确或值为
1
。 - XFetchName always returns 0
看起来 fetchName
并不总是填写。相反,您需要使用 _NET_WM_NAME
属性:
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
这就是 XMonad 所做的:
最后我不得不将 Brian 的回答改编为 XMonad 中更完整的定义(因为某些 windows 抛出异常):
import Control.Exception.Extensible (SomeException (..),
bracket)
import qualified Control.Exception.Extensible as E
import Graphics.X11
import Graphics.X11.Xlib.Extras
getWindowTitle :: Display -> IO String
getWindowTitle d = do
(w, _) <- getInputFocus d
let getProp =
(internAtom d "_NET_WM_NAME" False >>= getTextProperty d w)
`E.catch` \(SomeException _) -> getTextProperty d w wM_NAME
extract prop = do l <- wcTextPropertyToTextList d prop
return $ if null l then "" else head l
bracket getProp (xFree . tp_value) extract `E.catch` \(SomeException _) -> return ""