aboutsummaryrefslogtreecommitdiffstats
path: root/Wm.hs
blob: c95648d8e20122cad40e451e1495f6b5d0071e61 (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
-----------------------------------------------------------------------------
-- |
-- Module      :  Wm.hs
-- Copyright   :  (c) Spencer Janssen 2007
-- License     :  BSD3-style (see LICENSE)
-- 
-- Maintainer  :  sjanssen@cse.unl.edu
-- Stability   :  unstable
-- Portability :  not portable, uses cunning newtype deriving
--
-----------------------------------------------------------------------------
--
-- The Wm monad, a state monad transformer over IO, for the window manager state.
--

module Wm where

import Data.Sequence
import Control.Monad.State
import System.IO (hFlush, hPutStrLn, stderr)
import Graphics.X11.Xlib

data WmState = WmState
    { display       :: Display
    , screenWidth   :: !Int
    , screenHeight  :: !Int
    , windows       :: Seq Window
    }

newtype Wm a = Wm (StateT WmState IO a)
    deriving (Monad, MonadIO{-, MonadState WmState-})

runWm :: Wm a -> WmState -> IO (a, WmState)
runWm (Wm m) = runStateT m

io :: IO a -> Wm a
io = liftIO

trace msg = io $ do
    hPutStrLn stderr msg
    hFlush stderr

withIO :: (forall b. (a -> IO b) -> IO b) -> (a -> Wm c) -> Wm c
withIO f g = do
    s <- Wm get
    (y, s') <- io $ f $ \x -> runWm (g x) s
    Wm (put s')
    return y

getDisplay = Wm (gets display)

getWindows = Wm (gets windows)

getScreenWidth = Wm (gets screenWidth)

getScreenHeight = Wm (gets screenHeight)

setWindows x = Wm (modify (\s -> s {windows = x}))

modifyWindows :: (Seq Window -> Seq Window) -> Wm ()
modifyWindows f = Wm (modify (\s -> s {windows = f (windows s)}))