module XMonad.Util.DebugWindow (debugWindow) where
import Prelude
import XMonad
import Codec.Binary.UTF8.String (decodeString)
import Control.Exception.Extensible as E
import Control.Monad (when)
import Data.List (unfoldr
,intercalate
)
import Foreign
import Foreign.C.String
import Numeric (showHex)
import System.Exit
debugWindow :: Window -> X String
debugWindow :: Window -> X String
debugWindow 0 = String -> X String
forall (m :: * -> *) a. Monad m => a -> m a
return "-no window-"
debugWindow w :: Window
w = do
let wx :: String
wx = Int -> Char -> String -> String
pad 8 '0' (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ Window -> String -> String
forall a. (Integral a, Show a) => a -> String -> String
showHex Window
w ""
Maybe WindowAttributes
w' <- (Display -> X (Maybe WindowAttributes))
-> X (Maybe WindowAttributes)
forall a. (Display -> X a) -> X a
withDisplay ((Display -> X (Maybe WindowAttributes))
-> X (Maybe WindowAttributes))
-> (Display -> X (Maybe WindowAttributes))
-> X (Maybe WindowAttributes)
forall a b. (a -> b) -> a -> b
$ \d :: Display
d -> IO (Maybe WindowAttributes) -> X (Maybe WindowAttributes)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (Display -> Window -> IO (Maybe WindowAttributes)
safeGetWindowAttributes Display
d Window
w)
case Maybe WindowAttributes
w' of
Nothing ->
String -> X String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> X String) -> String -> X String
forall a b. (a -> b) -> a -> b
$ "(deleted window " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
wx String -> String -> String
forall a. [a] -> [a] -> [a]
++ ")"
Just (WindowAttributes
{ wa_x :: WindowAttributes -> CInt
wa_x = CInt
x
, wa_y :: WindowAttributes -> CInt
wa_y = CInt
y
, wa_width :: WindowAttributes -> CInt
wa_width = CInt
wid
, wa_height :: WindowAttributes -> CInt
wa_height = CInt
ht
, wa_border_width :: WindowAttributes -> CInt
wa_border_width = CInt
bw
, wa_map_state :: WindowAttributes -> CInt
wa_map_state = CInt
m
, wa_override_redirect :: WindowAttributes -> Bool
wa_override_redirect = Bool
o
}) -> do
Maybe [CChar]
c' <- (Display -> X (Maybe [CChar])) -> X (Maybe [CChar])
forall a. (Display -> X a) -> X a
withDisplay ((Display -> X (Maybe [CChar])) -> X (Maybe [CChar]))
-> (Display -> X (Maybe [CChar])) -> X (Maybe [CChar])
forall a b. (a -> b) -> a -> b
$ \d :: Display
d ->
IO (Maybe [CChar]) -> X (Maybe [CChar])
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (Display -> Window -> Window -> IO (Maybe [CChar])
getWindowProperty8 Display
d Window
wM_CLASS Window
w)
let c :: String
c = case Maybe [CChar]
c' of
Nothing -> ""
Just c'' :: [CChar]
c'' -> String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate "/" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$
((String -> Maybe (String, String)) -> String -> [String])
-> String -> (String -> Maybe (String, String)) -> [String]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (String -> Maybe (String, String)) -> String -> [String]
forall b a. (b -> Maybe (a, b)) -> b -> [a]
unfoldr ((CChar -> Char) -> [CChar] -> String
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
forall a. Enum a => Int -> a
toEnum (Int -> Char) -> (CChar -> Int) -> CChar -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CChar -> Int
forall a. Enum a => a -> Int
fromEnum) [CChar]
c'') ((String -> Maybe (String, String)) -> [String])
-> (String -> Maybe (String, String)) -> [String]
forall a b. (a -> b) -> a -> b
$
\s :: String
s -> if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
s
then Maybe (String, String)
forall a. Maybe a
Nothing
else let (w'' :: String
w'',s'' :: String
s'') = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\NUL') String
s
s' :: String
s' = if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
s''
then String
s''
else String -> String
forall a. [a] -> [a]
tail String
s''
in (String, String) -> Maybe (String, String)
forall a. a -> Maybe a
Just (String
w'',String
s')
String
t <- X String -> X String -> X String
forall a. X a -> X a -> X a
catchX' (String -> String
wrap (String -> String) -> X String -> X String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` String -> Window -> X String
getEWMHTitle "VISIBLE" Window
w) (X String -> X String) -> X String -> X String
forall a b. (a -> b) -> a -> b
$
X String -> X String -> X String
forall a. X a -> X a -> X a
catchX' (String -> String
wrap (String -> String) -> X String -> X String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` String -> Window -> X String
getEWMHTitle "" Window
w) (X String -> X String) -> X String -> X String
forall a b. (a -> b) -> a -> b
$
X String -> X String -> X String
forall a. X a -> X a -> X a
catchX' (String -> String
wrap (String -> String) -> X String -> X String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Window -> X String
getICCCMTitle Window
w) (X String -> X String) -> X String -> X String
forall a b. (a -> b) -> a -> b
$
String -> X String
forall (m :: * -> *) a. Monad m => a -> m a
return ""
String
h' <- Window -> X String
getMachine Window
w
let h :: String
h = if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
h' then "" else '@'Char -> String -> String
forall a. a -> [a] -> [a]
:String
h'
[String]
p' <- (Display -> X [String]) -> X [String]
forall a. (Display -> X a) -> X a
withDisplay ((Display -> X [String]) -> X [String])
-> (Display -> X [String]) -> X [String]
forall a b. (a -> b) -> a -> b
$ \d :: Display
d -> Display -> Window -> X [String]
safeGetCommand Display
d Window
w
let p :: String
p = if [String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
p' then "" else String -> String
wrap (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate " " [String]
p'
Window
nWP <- String -> X Window
getAtom "_NET_WM_PID"
Maybe [CLong]
pid' <- (Display -> X (Maybe [CLong])) -> X (Maybe [CLong])
forall a. (Display -> X a) -> X a
withDisplay ((Display -> X (Maybe [CLong])) -> X (Maybe [CLong]))
-> (Display -> X (Maybe [CLong])) -> X (Maybe [CLong])
forall a b. (a -> b) -> a -> b
$ \d :: Display
d -> IO (Maybe [CLong]) -> X (Maybe [CLong])
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO (Maybe [CLong]) -> X (Maybe [CLong]))
-> IO (Maybe [CLong]) -> X (Maybe [CLong])
forall a b. (a -> b) -> a -> b
$ Display -> Window -> Window -> IO (Maybe [CLong])
getWindowProperty32 Display
d Window
nWP Window
w
let pid :: String
pid = case Maybe [CLong]
pid' of
Just [pid'' :: CLong
pid''] -> '('Char -> String -> String
forall a. a -> [a] -> [a]
:CLong -> String
forall a. Show a => a -> String
show CLong
pid'' String -> String -> String
forall a. [a] -> [a] -> [a]
++ ")"
_ -> ""
let cmd :: String
cmd = String
p String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pid String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
h
let (lb :: String
lb,rb :: String
rb) = case () of
() | CInt
m CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
waIsViewable -> ("","")
| Bool
otherwise -> ("[","]")
o' :: String
o' = if Bool
o then "!" else ""
String -> X String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> X String) -> String -> X String
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [String
lb
,String
o'
,String
wx
,String
t
," "
,CInt -> String
forall a. Show a => a -> String
show CInt
wid
,'x'Char -> String -> String
forall a. a -> [a] -> [a]
:CInt -> String
forall a. Show a => a -> String
show CInt
ht
,if CInt
bw CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== 0 then "" else '+'Char -> String -> String
forall a. a -> [a] -> [a]
:CInt -> String
forall a. Show a => a -> String
show CInt
bw
,"@"
,CInt -> String
forall a. Show a => a -> String
show CInt
x
,','Char -> String -> String
forall a. a -> [a] -> [a]
:CInt -> String
forall a. Show a => a -> String
show CInt
y
,if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
c then "" else ' 'Char -> String -> String
forall a. a -> [a] -> [a]
:String
c
,if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
cmd then "" else ' 'Char -> String -> String
forall a. a -> [a] -> [a]
:String
cmd
,String
rb
]
getEWMHTitle :: String -> Window -> X String
getEWMHTitle :: String -> Window -> X String
getEWMHTitle sub :: String
sub w :: Window
w = do
Window
a <- String -> X Window
getAtom (String -> X Window) -> String -> X Window
forall a b. (a -> b) -> a -> b
$ "_NET_WM_" String -> String -> String
forall a. [a] -> [a] -> [a]
++ (if String -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
sub then "" else '_'Char -> String -> String
forall a. a -> [a] -> [a]
:String
sub) String -> String -> String
forall a. [a] -> [a] -> [a]
++ "_NAME"
(Just t :: [CLong]
t) <- (Display -> X (Maybe [CLong])) -> X (Maybe [CLong])
forall a. (Display -> X a) -> X a
withDisplay ((Display -> X (Maybe [CLong])) -> X (Maybe [CLong]))
-> (Display -> X (Maybe [CLong])) -> X (Maybe [CLong])
forall a b. (a -> b) -> a -> b
$ \d :: Display
d -> IO (Maybe [CLong]) -> X (Maybe [CLong])
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO (Maybe [CLong]) -> X (Maybe [CLong]))
-> IO (Maybe [CLong]) -> X (Maybe [CLong])
forall a b. (a -> b) -> a -> b
$ Display -> Window -> Window -> IO (Maybe [CLong])
getWindowProperty32 Display
d Window
a Window
w
String -> X String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> X String) -> String -> X String
forall a b. (a -> b) -> a -> b
$ (CLong -> Char) -> [CLong] -> String
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
forall a. Enum a => Int -> a
toEnum (Int -> Char) -> (CLong -> Int) -> CLong -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CLong -> Int
forall a. Enum a => a -> Int
fromEnum) [CLong]
t
getICCCMTitle :: Window -> X String
getICCCMTitle :: Window -> X String
getICCCMTitle w :: Window
w = Window -> Window -> X String
getDecodedStringProp Window
w Window
wM_NAME
getDecodedStringProp :: Window -> Atom -> X String
getDecodedStringProp :: Window -> Window -> X String
getDecodedStringProp w :: Window
w a :: Window
a = do
t :: TextProperty
t@(TextProperty t' :: CString
t' _ 8 _) <- (Display -> X TextProperty) -> X TextProperty
forall a. (Display -> X a) -> X a
withDisplay ((Display -> X TextProperty) -> X TextProperty)
-> (Display -> X TextProperty) -> X TextProperty
forall a b. (a -> b) -> a -> b
$ \d :: Display
d -> IO TextProperty -> X TextProperty
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO TextProperty -> X TextProperty)
-> IO TextProperty -> X TextProperty
forall a b. (a -> b) -> a -> b
$ Display -> Window -> Window -> IO TextProperty
getTextProperty Display
d Window
w Window
a
[s :: String
s] <- X [String] -> X [String] -> X [String]
forall a. X a -> X a -> X a
catchX' (TextProperty -> X [String]
tryUTF8 TextProperty
t) (X [String] -> X [String]) -> X [String] -> X [String]
forall a b. (a -> b) -> a -> b
$
X [String] -> X [String] -> X [String]
forall a. X a -> X a -> X a
catchX' (TextProperty -> X [String]
tryCompound TextProperty
t) (X [String] -> X [String]) -> X [String] -> X [String]
forall a b. (a -> b) -> a -> b
$
IO [String] -> X [String]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io ((String -> [String] -> [String]
forall a. a -> [a] -> [a]
:[]) (String -> [String]) -> IO String -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` CString -> IO String
peekCString CString
t')
String -> X String
forall (m :: * -> *) a. Monad m => a -> m a
return String
s
tryUTF8 :: TextProperty -> X [String]
tryUTF8 :: TextProperty -> X [String]
tryUTF8 (TextProperty s :: CString
s enc :: Window
enc _ _) = do
Window
uTF8_STRING <- String -> X Window
getAtom "UTF8_STRING"
Bool -> X () -> X ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Window
enc Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
== Window
uTF8_STRING) (X () -> X ()) -> X () -> X ()
forall a b. (a -> b) -> a -> b
$ String -> X ()
forall a. HasCallStack => String -> a
error "String is not UTF8_STRING"
((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
decodeString ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
splitNul) (String -> [String]) -> X String -> X [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` IO String -> X String
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (CString -> IO String
peekCString CString
s)
tryCompound :: TextProperty -> X [String]
tryCompound :: TextProperty -> X [String]
tryCompound t :: TextProperty
t@(TextProperty _ enc :: Window
enc _ _) = do
Window
cOMPOUND_TEXT <- String -> X Window
getAtom "COMPOUND_TEXT"
Bool -> X () -> X ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Window
enc Window -> Window -> Bool
forall a. Eq a => a -> a -> Bool
== Window
cOMPOUND_TEXT) (X () -> X ()) -> X () -> X ()
forall a b. (a -> b) -> a -> b
$ String -> X ()
forall a. HasCallStack => String -> a
error "String is not COMPOUND_TEXT"
(Display -> X [String]) -> X [String]
forall a. (Display -> X a) -> X a
withDisplay ((Display -> X [String]) -> X [String])
-> (Display -> X [String]) -> X [String]
forall a b. (a -> b) -> a -> b
$ \d :: Display
d -> IO [String] -> X [String]
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO [String] -> X [String]) -> IO [String] -> X [String]
forall a b. (a -> b) -> a -> b
$ Display -> TextProperty -> IO [String]
wcTextPropertyToTextList Display
d TextProperty
t
splitNul :: String -> [String]
splitNul :: String -> [String]
splitNul "" = []
splitNul s :: String
s = let (s' :: String
s',ss' :: String
ss') = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\NUL') String
s in String
s' String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String -> [String]
splitNul String
ss'
pad :: Int -> Char -> String -> String
pad :: Int -> Char -> String -> String
pad w :: Int
w c :: Char
c s :: String
s = Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
w Int -> Int -> Int
forall a. Num a => a -> a -> a
- String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s) Char
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s
catchX' :: X a -> X a -> X a
catchX' :: X a -> X a -> X a
catchX' job :: X a
job errcase :: X a
errcase = do
XState
st <- X XState
forall s (m :: * -> *). MonadState s m => m s
get
XConf
c <- X XConf
forall r (m :: * -> *). MonadReader r m => m r
ask
(a :: a
a, s' :: XState
s') <- IO (a, XState) -> X (a, XState)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO (a, XState) -> X (a, XState))
-> IO (a, XState) -> X (a, XState)
forall a b. (a -> b) -> a -> b
$ XConf -> XState -> X a -> IO (a, XState)
forall a. XConf -> XState -> X a -> IO (a, XState)
runX XConf
c XState
st X a
job IO (a, XState)
-> (SomeException -> IO (a, XState)) -> IO (a, XState)
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`E.catch` \e :: SomeException
e -> case SomeException -> Maybe ExitCode
forall e. Exception e => SomeException -> Maybe e
fromException SomeException
e of
Just x :: ExitCode
x -> SomeException -> IO (a, XState)
forall a e. Exception e => e -> a
throw SomeException
e IO (a, XState) -> ExitCode -> IO (a, XState)
forall a b. a -> b -> a
`const` (ExitCode
x ExitCode -> ExitCode -> ExitCode
forall a. a -> a -> a
`asTypeOf` ExitCode
ExitSuccess)
_ -> XConf -> XState -> X a -> IO (a, XState)
forall a. XConf -> XState -> X a -> IO (a, XState)
runX XConf
c XState
st X a
errcase
XState -> X ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put XState
s'
a -> X a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
wrap :: String -> String
wrap :: String -> String
wrap s :: String
s = ' ' Char -> String -> String
forall a. a -> [a] -> [a]
: '"' Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
wrap' String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\""
where
wrap' :: String -> String
wrap' (s' :: Char
s':ss :: String
ss) | Char
s' Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '"' = '\\' Char -> String -> String
forall a. a -> [a] -> [a]
: Char
s' Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
wrap' String
ss
| Char
s' Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\\' = '\\' Char -> String -> String
forall a. a -> [a] -> [a]
: Char
s' Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
wrap' String
ss
| Bool
otherwise = Char
s' Char -> String -> String
forall a. a -> [a] -> [a]
: String -> String
wrap' String
ss
wrap' "" = ""
safeGetWindowAttributes :: Display -> Window -> IO (Maybe WindowAttributes)
safeGetWindowAttributes :: Display -> Window -> IO (Maybe WindowAttributes)
safeGetWindowAttributes d :: Display
d w :: Window
w = (Ptr WindowAttributes -> IO (Maybe WindowAttributes))
-> IO (Maybe WindowAttributes)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr WindowAttributes -> IO (Maybe WindowAttributes))
-> IO (Maybe WindowAttributes))
-> (Ptr WindowAttributes -> IO (Maybe WindowAttributes))
-> IO (Maybe WindowAttributes)
forall a b. (a -> b) -> a -> b
$ \p :: Ptr WindowAttributes
p -> do
CInt
s <- Display -> Window -> Ptr WindowAttributes -> IO CInt
xGetWindowAttributes Display
d Window
w Ptr WindowAttributes
p
case CInt
s of
0 -> Maybe WindowAttributes -> IO (Maybe WindowAttributes)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe WindowAttributes
forall a. Maybe a
Nothing
_ -> WindowAttributes -> Maybe WindowAttributes
forall a. a -> Maybe a
Just (WindowAttributes -> Maybe WindowAttributes)
-> IO WindowAttributes -> IO (Maybe WindowAttributes)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Ptr WindowAttributes -> IO WindowAttributes
forall a. Storable a => Ptr a -> IO a
peek Ptr WindowAttributes
p
safeGetCommand :: Display -> Window -> X [String]
safeGetCommand :: Display -> Window -> X [String]
safeGetCommand d :: Display
d w :: Window
w = do
Window
wC <- String -> X Window
getAtom "WM_COMMAND"
Maybe [CChar]
p <- IO (Maybe [CChar]) -> X (Maybe [CChar])
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO (Maybe [CChar]) -> X (Maybe [CChar]))
-> IO (Maybe [CChar]) -> X (Maybe [CChar])
forall a b. (a -> b) -> a -> b
$ Display -> Window -> Window -> IO (Maybe [CChar])
getWindowProperty8 Display
d Window
wC Window
w
case Maybe [CChar]
p of
Nothing -> [String] -> X [String]
forall (m :: * -> *) a. Monad m => a -> m a
return []
Just cs' :: [CChar]
cs' -> do
let cs :: String
cs = (CChar -> Char) -> [CChar] -> String
forall a b. (a -> b) -> [a] -> [b]
map (Int -> Char
forall a. Enum a => Int -> a
toEnum (Int -> Char) -> (CChar -> Int) -> CChar -> Char
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CChar -> Int
forall a. Enum a => a -> Int
fromEnum) [CChar]
cs'
go :: ([String], (String, String)) -> ([String], (String, String))
go (a :: [String]
a,(s :: String
s,"\NUL")) = (String
sString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
a,("",""))
go (a :: [String]
a,(s :: String
s,'\NUL':ss :: String
ss)) = ([String], (String, String)) -> ([String], (String, String))
go (String
sString -> [String] -> [String]
forall a. a -> [a] -> [a]
:[String]
a,String -> (String, String)
go' String
ss)
go r :: ([String], (String, String))
r = ([String], (String, String))
r
go' :: String -> (String, String)
go' = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\NUL')
in [String] -> X [String]
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> X [String]) -> [String] -> X [String]
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
forall a. [a] -> [a]
reverse ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ ([String], (String, String)) -> [String]
forall a b. (a, b) -> a
fst (([String], (String, String)) -> [String])
-> ([String], (String, String)) -> [String]
forall a b. (a -> b) -> a -> b
$ ([String], (String, String)) -> ([String], (String, String))
go ([],String -> (String, String)
go' String
cs)
getMachine :: Window -> X String
getMachine :: Window -> X String
getMachine w :: Window
w = X String -> X String -> X String
forall a. X a -> X a -> X a
catchX' (String -> X Window
getAtom "WM_CLIENT_MACHINE" X Window -> (Window -> X String) -> X String
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Window -> Window -> X String
getDecodedStringProp Window
w) (String -> X String
forall (m :: * -> *) a. Monad m => a -> m a
return "")