mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-07-31 20:21:51 -07:00
The base that comes with ghc-7.6.1 no longer includes Prelude.catch; so these modules were changed so that there is no warning for import Prelude hiding (catch) At the same time these changes should be compatible with older GHCs, since the catch being has never been the one in the Prelude.
91 lines
3.2 KiB
Haskell
91 lines
3.2 KiB
Haskell
{-# LANGUAGE ScopedTypeVariables #-}
|
|
-----------------------------------------------------------------------------
|
|
-- |
|
|
-- Module : XMonad.Hooks.XPropManage
|
|
-- Copyright : (c) Karsten Schoelzel <kuser@gmx.de>
|
|
-- License : BSD
|
|
--
|
|
-- Maintainer : Karsten Schoelzel <kuser@gmx.de>
|
|
-- Stability : unstable
|
|
-- Portability : unportable
|
|
--
|
|
-- A ManageHook matching on XProperties.
|
|
-----------------------------------------------------------------------------
|
|
|
|
module XMonad.Hooks.XPropManage (
|
|
-- * Usage
|
|
-- $usage
|
|
xPropManageHook, XPropMatch, pmX, pmP
|
|
) where
|
|
|
|
import Control.Exception as E
|
|
import Data.Char (chr)
|
|
import Data.Monoid (mconcat, Endo(..))
|
|
|
|
import Control.Monad.Trans (lift)
|
|
|
|
import XMonad
|
|
|
|
-- $usage
|
|
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
|
|
--
|
|
-- > import XMonad.Hooks.XPropManage
|
|
-- > import qualified XMonad.StackSet as W
|
|
-- > import XMonad.Actions.TagWindows
|
|
-- > import Data.List
|
|
--
|
|
-- > manageHook = xPropManageHook xPropMatches
|
|
-- >
|
|
-- > xPropMatches :: [XPropMatch]
|
|
-- > xPropMatches = [ ([ (wM_CLASS, any ("gimp"==))], (\w -> float w >> return (W.shift "2")))
|
|
-- > , ([ (wM_COMMAND, any ("screen" ==)), (wM_CLASS, any ("xterm" ==))], pmX (addTag "screen"))
|
|
-- > , ([ (wM_NAME, any ("Iceweasel" `isInfixOf`))], pmP (W.shift "3"))
|
|
-- > ]
|
|
--
|
|
-- Properties known to work: wM_CLASS, wM_NAME, wM_COMMAND
|
|
--
|
|
-- A XPropMatch consists of a list of conditions and function telling what to do.
|
|
--
|
|
-- The list entries are pairs of an XProperty to match on (like wM_CLASS, wM_NAME)^1,
|
|
-- and an function which matches onto the value of the property (represented as a List
|
|
-- of Strings).
|
|
--
|
|
-- If a match succeeds the function is called immediately, can perform any action and then return
|
|
-- a function to apply in 'windows' (see Operations.hs). So if the action does only work on the
|
|
-- WindowSet use just 'pmP function'.
|
|
--
|
|
-- \*1 You can get the available properties of an application with the xprop utility. STRING properties
|
|
-- should work fine. Others might not work.
|
|
--
|
|
|
|
type XPropMatch = ([(Atom, [String] -> Bool)], (Window -> X (WindowSet -> WindowSet)))
|
|
|
|
pmX :: (Window -> X ()) -> Window -> X (WindowSet -> WindowSet)
|
|
pmX f w = f w >> return id
|
|
|
|
pmP :: (WindowSet -> WindowSet) -> Window -> X (WindowSet -> WindowSet)
|
|
pmP f _ = return f
|
|
|
|
xPropManageHook :: [XPropMatch] -> ManageHook
|
|
xPropManageHook tms = mconcat $ map propToHook tms
|
|
where
|
|
propToHook (ms, f) = fmap and (mapM mkQuery ms) --> mkHook f
|
|
mkQuery (a, tf) = fmap tf (getQuery a)
|
|
mkHook func = ask >>= Query . lift . fmap Endo . func
|
|
|
|
getProp :: Display -> Window -> Atom -> X ([String])
|
|
getProp d w p = do
|
|
prop <- io $ E.catch (getTextProperty d w p >>= wcTextPropertyToTextList d) (\(_ :: IOException) -> return [[]])
|
|
let filt q | q == wM_COMMAND = concat . map splitAtNull
|
|
| otherwise = id
|
|
return (filt p prop)
|
|
|
|
getQuery :: Atom -> Query [String]
|
|
getQuery p = ask >>= \w -> Query . lift $ withDisplay $ \d -> getProp d w p
|
|
|
|
splitAtNull :: String -> [String]
|
|
splitAtNull s = case dropWhile (== (chr 0)) s of
|
|
"" -> []
|
|
s' -> w : splitAtNull s''
|
|
where (w, s'') = break (== (chr 0)) s'
|