module XMonad.Util.WindowProperties (
Property(..), hasProperty, focusedHasProperty, allWithProperty,
propertyToQuery,
getProp32, getProp32s)
where
import Control.Monad
import Foreign.C.Types (CLong)
import XMonad
import XMonad.Actions.TagWindows (hasTag)
import qualified XMonad.StackSet as W
data Property = Title String
| ClassName String
| Resource String
| Role String
| Machine String
| And Property Property
| Or Property Property
| Not Property
| Const Bool
| Tagged String
deriving (Read, Show)
infixr 9 `And`
infixr 8 `Or`
hasProperty :: Property -> Window -> X Bool
hasProperty p w = runQuery (propertyToQuery p) w
focusedHasProperty :: Property -> X Bool
focusedHasProperty p = do
ws <- gets windowset
let ms = W.stack $ W.workspace $ W.current ws
case ms of
Just s -> hasProperty p $ W.focus s
Nothing -> return False
allWithProperty :: Property -> X [Window]
allWithProperty prop = withDisplay $ \dpy -> do
rootw <- asks theRoot
(_,_,wins) <- io $ queryTree dpy rootw
hasProperty prop `filterM` wins
propertyToQuery :: Property -> Query Bool
propertyToQuery (Title s) = title =? s
propertyToQuery (Resource s) = resource =? s
propertyToQuery (ClassName s) = className =? s
propertyToQuery (Role s) = stringProperty "WM_WINDOW_ROLE" =? s
propertyToQuery (Machine s) = stringProperty "WM_CLIENT_MACHINE" =? s
propertyToQuery (And p1 p2) = propertyToQuery p1 <&&> propertyToQuery p2
propertyToQuery (Or p1 p2) = propertyToQuery p1 <||> propertyToQuery p2
propertyToQuery (Not p) = not `fmap` propertyToQuery p
propertyToQuery (Const b) = return b
propertyToQuery (Tagged s) = ask >>= \w -> liftX (hasTag s w)
getProp32 :: Atom -> Window -> X (Maybe [CLong])
getProp32 a w = withDisplay $ \dpy -> io $ getWindowProperty32 dpy a w
getProp32s :: String -> Window -> X (Maybe [CLong])
getProp32s str w = do { a <- getAtom str; getProp32 a w }