----------------------------------------------------------------------------
-- |
-- Module : XMonad.PositionStore
-- Copyright : (c) Jan Vornberger 2009
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : jan.vornberger@informatik.uni-oldenburg.de
-- Stability : unstable
-- Portability : not portable
--
-----------------------------------------------------------------------------
module XMonad.PositionStore (
PositionStore,
posStoreInsert,
posStoreMove,
posStoreQuery,
posStoreRemove
) where
import Graphics.X11.Xlib
-- Store window positions relative to the upper left screen edge
-- and windows sizes as well as positions as fractions of the screen size.
-- This way windows can be easily relocated and scaled when switching screens.
type PositionStore a = [(a, PosStoreRectangle)]
data PosStoreRectangle = PSRectangle Double Double Double Double
posStoreInsert :: (Eq a) => PositionStore a -> a -> Rectangle -> Rectangle -> PositionStore a
posStoreInsert posStore w (Rectangle x y wh ht) (Rectangle srX srY srWh srHt) =
let offsetX = x - srX
offsetY = y - srY
in posStoreInsert' posStore w (PSRectangle (fromIntegral offsetX / fromIntegral srWh)
(fromIntegral offsetY / fromIntegral srHt)
(fromIntegral wh / fromIntegral srWh)
(fromIntegral ht / fromIntegral srHt))
posStoreInsert' :: (Eq a) => PositionStore a -> a -> PosStoreRectangle -> PositionStore a
posStoreInsert' posStore w psRect = (w, psRect) : (posStoreRemove posStore w)
posStoreRemove :: (Eq a) => PositionStore a -> a -> PositionStore a
posStoreRemove posStore w = filter (\(w', _) -> w /= w') posStore
posStoreQuery :: (Eq a) => PositionStore a -> a -> Rectangle -> Maybe Rectangle
posStoreQuery posStore w (Rectangle srX srY srWh srHt) = do
(PSRectangle x y wh ht) <- lookup w posStore
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 :: (Eq a) => PositionStore a -> a -> Position -> Position -> Rectangle -> Rectangle -> PositionStore a
posStoreMove posStore w x y oldSr newSr =
case (posStoreQuery posStore w oldSr) of
Nothing -> posStore -- not in store, can't move -> do nothing
Just (Rectangle _ _ wh ht) -> posStoreInsert posStore w (Rectangle x y wh ht) newSr