{-# LANGUAGE DeriveDataTypeable #-}
module XMonad.Util.PositionStore (
getPosStore,
modifyPosStore,
posStoreInsert,
posStoreMove,
posStoreQuery,
posStoreRemove,
PositionStore,
) where
import XMonad
import qualified XMonad.Util.ExtensibleState as XS
import qualified Data.Map as M
data PositionStore = PS (M.Map Window PosStoreRectangle)
deriving (Read,Show,Typeable)
data PosStoreRectangle = PSRectangle Double Double Double Double
deriving (Read,Show,Typeable)
instance ExtensionClass PositionStore where
initialValue = PS M.empty
extensionType = PersistentExtension
getPosStore :: X (PositionStore)
getPosStore = XS.get
modifyPosStore :: (PositionStore -> PositionStore) -> X ()
modifyPosStore = XS.modify
posStoreInsert :: PositionStore -> Window -> Rectangle -> Rectangle -> PositionStore
posStoreInsert (PS posStoreMap) w (Rectangle x y wh ht) (Rectangle srX srY srWh srHt) =
let offsetX = x - srX
offsetY = y - srY
in PS $ M.insert w (PSRectangle (fromIntegral offsetX / fromIntegral srWh)
(fromIntegral offsetY / fromIntegral srHt)
(fromIntegral wh / fromIntegral srWh)
(fromIntegral ht / fromIntegral srHt)) posStoreMap
posStoreRemove :: PositionStore -> Window -> PositionStore
posStoreRemove (PS posStoreMap) w = PS $ M.delete w posStoreMap
posStoreQuery :: PositionStore -> Window -> Rectangle -> Maybe Rectangle
posStoreQuery (PS posStoreMap) w (Rectangle srX srY srWh srHt) = do
(PSRectangle x y wh ht) <- M.lookup w posStoreMap
let realWh = fromIntegral srWh * wh
realHt = fromIntegral srHt * ht
realOffsetX = fromIntegral srWh * x
realOffsetY = fromIntegral srHt * y
return (Rectangle (srX + round realOffsetX) (srY + round realOffsetY)
(round realWh) (round realHt))
posStoreMove :: PositionStore -> Window -> Position -> Position -> Rectangle -> Rectangle -> PositionStore
posStoreMove posStore w x y oldSr newSr =
case (posStoreQuery posStore w oldSr) of
Nothing -> posStore
Just (Rectangle _ _ wh ht) -> posStoreInsert posStore w (Rectangle x y wh ht) newSr