aboutsummaryrefslogblamecommitdiffstats
path: root/Decoration.hs
blob: e31c93fd2b18bc8c94c6722af3f2d03e13e832c7 (plain) (tree)
1
2
3
4
5
6
7


                                                       
                          

                                           
                        





                                                                                                       
                                                             
                                                                      
                                                              




                                                                          
                                                                
                           

                                                                                        








                                                                                                    
                                                                         

                                                               


                                                                        





                                                                           
module XMonadContrib.Decoration ( newDecoration ) where

import qualified Data.Map as M
import Data.Bits ( (.|.) )
import Control.Monad.Reader ( asks )
import Control.Monad.State ( modify, gets )
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras ( Event(AnyEvent,ButtonEvent), ev_subwindow, ev_event_type, ev_window )

import XMonad
import Operations ( ModifyWindows(ModifyWindows) )
import qualified StackSet as W

newDecoration :: Window -> Rectangle -> Int -> Pixel -> Pixel
              -> (Display -> Window -> GC -> X ()) -> X () -> X Window
newDecoration decfor (Rectangle x y w h) th fg bg draw click =
    do d <- asks display
       rt <- asks theRoot
       n <- (W.tag . W.workspace . W.current) `fmap` gets windowset
       Just (l,ls) <- M.lookup n `fmap` gets layouts
       win <- io $ createSimpleWindow d rt x y w h (fromIntegral th) fg bg
       io $ selectInput d win $ exposureMask .|. buttonPressMask
       io $ mapWindow d win
       let draw' = withGC win draw
           modml :: (SomeMessage -> X (Maybe Layout)) -> SomeMessage -> X (Maybe Layout)
           modml oldml m | Just ModifyWindows == fromMessage m = io (destroyWindow d win) >> oldml m
                         | Just e <- fromMessage m = handle_event e >> oldml m
                         | otherwise = fmap modl `fmap` oldml m
           modl :: Layout -> Layout
           modl oldl = oldl { modifyLayout = modml (modifyLayout oldl) }
           handle_event (ButtonEvent {ev_subwindow = thisw,ev_event_type = t})
               | t == buttonPress && thisw == win = click
           handle_event (ButtonEvent {ev_window = thisw,ev_event_type = t})
               | t == buttonPress && thisw == win = click
           handle_event (AnyEvent {ev_window = thisw, ev_event_type = t})
               | thisw == win    && t == expose         = draw'
               | thisw == decfor && t == propertyNotify = draw'
           handle_event _ = return ()
       modify $ \s -> s { layouts = M.insert n (modl l,ls) (layouts s) }
       return win

-- FIXME: withGC should use bracket (but can't, unless draw is an IO thing)
withGC :: Drawable -> (Display -> Drawable -> GC -> X ()) -> X ()
withGC w f = withDisplay $ \d -> do gc <- io $ createGC d w
                                    f d w gc
                                    io $ freeGC d gc