diff options
| -rw-r--r-- | src/Main.hs | 4 | ||||
| -rw-r--r-- | src/Xmobar.hs | 40 | 
2 files changed, 31 insertions, 13 deletions
| diff --git a/src/Main.hs b/src/Main.hs index 18e05e2..941a844 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -42,6 +42,7 @@ import Control.Monad (unless)  main :: IO ()  main = do    d   <- openDisplay "" +  d'  <- openDisplay ""    args     <- getArgs    (o,file) <- getOpts args    (c,defaultings) <- case file of @@ -60,7 +61,8 @@ main = do    cls   <- mapM (parseTemplate conf) (splitTemplate conf)    vars  <- mapM (mapM startCommand) cls    (r,w) <- createWin d fs conf -  eventLoop (XConf d r w fs conf) vars +  _ <- enableXRandrEventListen d' +  eventLoop (XConf d d' r w fs conf) vars  -- | Splits the template in its parts  splitTemplate :: Config -> [String] diff --git a/src/Xmobar.hs b/src/Xmobar.hs index 462de14..97d6990 100644 --- a/src/Xmobar.hs +++ b/src/Xmobar.hs @@ -23,7 +23,7 @@ module Xmobar      , startCommand      -- * Window Management      -- $window -    , createWin, updateWin +    , createWin, updateWin, enableXRandrEventListen      -- * Printing      -- $print      , drawInWin, printStrings @@ -60,6 +60,7 @@ type X = ReaderT XConf IO  -- | The ReaderT inner component  data XConf =      XConf { display :: Display +          , xrrDspy :: Display --  display used for XRandr events            , rect    :: Rectangle            , window  :: Window            , fontS   :: XFont @@ -75,7 +76,7 @@ instance Exception WakeUp  -- | The event loop  eventLoop :: XConf -> [[(Maybe ThreadId, TVar String)]] -> IO () -eventLoop xc@(XConf d _ w fs c) vs = block $ do +eventLoop xc@(XConf d xrrD _ w fs c) vs = block $ do      tv <- atomically $ newTVar []      t  <- myThreadId      ct <- forkIO (checker t tv [] `catch` \(SomeException _) -> return ()) @@ -101,16 +102,24 @@ eventLoop xc@(XConf d _ w fs c) vs = block $ do        go tv ct      -- event hanlder -    handle _ _ (ConfigureEvent {}) = return () +    handle _ ct (ConfigureEvent {}) = recreateWindow ct -    handle tvar _ (ExposeEvent {}) = runX xc (updateWin tvar) +    handle tvar ct (ExposeEvent {}) = block $ do +          --  check if there are XRandr events pending +          num <- pending xrrD +          if num == 0 then +              --  if no pending events, make a update +              runX xc (updateWin tvar) +           else +              recreateWindow ct -    --  this catches the RRScreenChangeNotify -    handle _ ct _  = block $ do -                      killThread ct -                      destroyWindow d w -                      (r',w') <- createWin d fs c -                      eventLoop (XConf d r' w' fs c) vs +    handle _ _ _  = return () + +    recreateWindow ct = do +              killThread ct +              destroyWindow d w +              (r',w') <- createWin d fs c +              eventLoop (XConf d xrrD r' w' fs c) vs  -- $command @@ -129,6 +138,14 @@ startCommand (com,s,ss)  -- $window +-- | The function to enable notifications from XRandr +enableXRandrEventListen :: Display -> IO () +enableXRandrEventListen d = do +  let dflt = defaultScreen d +  rootw <- rootWindow d dflt +  --  RRScreenChangeNotifyMask has the same value as keyPressMask +  xrrSelectInput  d rootw keyPressMask +  -- | The function to create the initial window  createWin :: Display -> XFont -> Config -> IO (Rectangle,Window)  createWin d fs c = do @@ -139,8 +156,7 @@ createWin d fs c = do    let ht    = as + ds + 4        (r,o) = setPosition (position c) srs (fi ht)    win <- newWindow  d (defaultScreenOfDisplay d) rootw r o -  --  RRScreenChangeNotifyMask has the same value as keyPressMask -  xrrSelectInput    d rootw keyPressMask +  selectInput       d win (exposureMask .|. structureNotifyMask)    setProperties r c d win srs    when (lowerOnStart c) (lowerWindow d win)    mapWindow         d win | 
