----------------------------------------------------------------------------- -- | -- Module : XMonad.Actions.RandomBackground -- Copyright : (c) 2009 Anze Slosar -- translation to Haskell by Adam Vogt -- License : BSD3-style (see LICENSE) -- -- Maintainer : -- Stability : unstable -- Portability : unportable -- -- An action to start terminals with a random background color -- ----------------------------------------------------------------------------- module XMonad.Actions.RandomBackground ( -- * Usage -- $usage randomBg', randomBg, RandomColor(HSV,RGB) ) where import XMonad(X, XConf(config), XConfig(terminal), io, spawn, MonadIO, asks) import System.Random import Control.Monad(liftM) import Numeric(showHex) -- $usage -- -- Add to your keybindings something like: -- -- > ,((modm .|. shiftMask, xK_Return), randomBg $ HSV 0xff 0x20 -- | RandomColor fixes constraints when generating random colors. All -- parameters should be in the range 0 -- 0xff data RandomColor = RGB { _colorMin :: Int , _colorMax :: Int } -- ^ specify the minimum and maximum lowest values for each color channel. | HSV { _colorSaturation :: Double , _colorValue :: Double } -- ^ specify the saturation and value, leaving the hue random. toHex :: [Int] -> String toHex = ("'#"++) . (++"'") . concatMap (ensure 2 . ($ "") . showHex) where ensure x = reverse . take x . (++repeat '0') . reverse randPermutation :: (RandomGen g) => [a] -> g -> [a] randPermutation xs g = swap $ zip (randoms g) xs where swap ((True,x):(c,y):ys) = y:swap ((c,x):ys) swap ((False,x):ys) = x:swap ys swap x = map snd x -- | @randomBg'@ produces a random hex number in the form @'#xxyyzz'@ randomBg' :: (MonadIO m) => RandomColor -> m String randomBg' (RGB l h) = io $ liftM (toHex . take 3 . randomRs (l,h)) newStdGen randomBg' (HSV s v) = io $ do g <- newStdGen let x = (^(2::Int)) $ fst $ randomR (0,sqrt $ pi / 3) g return $ toHex $ map round $ randPermutation [v,(v-s)*x + s,s] g -- | @randomBg@ starts a terminal with the background color taken from 'randomBg'' -- -- This depends on the your 'terminal' configuration field accepting an -- argument like @-bg '#ff0023'@ randomBg :: RandomColor -> X () randomBg x = do t <- asks (terminal . config) c <- randomBg' x spawn $ t ++ " -bg " ++ c