blob: 830f068a75b627533af5c3fe5a2778d7d3af73c6 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
{-# LANGUAGE DeriveDataTypeable #-}
----------------------------------------------------------------------------
-- |
-- Module : XMonad.Util.PositionStore
-- Copyright : (c) Jan Vornberger 2009
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : jan.vornberger@informatik.uni-oldenburg.de
-- Stability : unstable
-- Portability : not portable
--
-- A utility module to store information about position and size of a window.
-- See "XMonad.Layout.PositionStoreFloat" for a layout that makes use of this.
--
-----------------------------------------------------------------------------
module XMonad.Util.PositionStore (
getPosStore,
modifyPosStore,
posStoreInsert,
posStoreMove,
posStoreQuery,
posStoreRemove
) where
import XMonad
import qualified XMonad.Util.ExtensibleState as XS
import Graphics.X11.Xlib
import Graphics.X11.Types
import Data.Typeable
import qualified Data.Map as M
-- 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.
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 -- not in store, can't move -> do nothing
Just (Rectangle _ _ wh ht) -> posStoreInsert posStore w (Rectangle x y wh ht) newSr
|