From e909c3b8c6887b2fcee1debf34499794e5accac1 Mon Sep 17 00:00:00 2001 From: Jose Antonio Ortega Ruiz Date: Sat, 22 Jan 2011 03:33:08 +0100 Subject: Bug fix: don't get confused by align separators in input (issue 14) This solves the common case of a template separator character (such as {) popping up in xmobar's input (e.g., inside a window title) and confusing the parser. --- NEWS | 4 ++++ src/Main.hs | 19 +++++++++++++++++-- src/Plugins/StdinReader.hs | 3 ++- src/Xmobar.hs | 26 +++++++++++--------------- 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/NEWS b/NEWS index 839c0dc..6d5ecd2 100644 --- a/NEWS +++ b/NEWS @@ -17,12 +17,16 @@ _Bug fixes_ - Text is now correctly centered vertically. - `FullBM` border spec fixed. + - [issue 14]: `StdinReader` and other plugins accepting external + input don't get confused anymore when characters from `alignSep` + appear in their input. - [issue 27]: `BottomSize` placement now respects its width argument. - [issue 28]: Compilation in Mac OS X fixed. - [issue 30]: `Mail` plugin can be specified anywhere in commands list. - [issue 36]: Battery monitor now supports non-standard locations of the `/sys/class/power_supply/AC/online` file. +[issue 14]: http://code.google.com/p/xmobar/issues/detail?id=14 [issue 27]: http://code.google.com/p/xmobar/issues/detail?id=27 [issue 28]: http://code.google.com/p/xmobar/issues/detail?id=28 [issue 30]: http://code.google.com/p/xmobar/issues/detail?id=30 diff --git a/src/Main.hs b/src/Main.hs index aad87e7..c069b8e 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -60,11 +60,26 @@ main = do doOpts civ o conf <- readIORef civ fs <- initFont d (font conf) - cl <- parseTemplate conf (template conf) - vars <- mapM startCommand cl + 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 +-- | Splits the template in its parts +splitTemplate :: Config -> [String] +splitTemplate conf = + case break (==l) t of + (le,_:re) -> case break (==r) re of + (ce,_:ri) -> [le, ce, ri] + _ -> def + _ -> def + where [l, r] = if length (alignSep conf) == 2 + then alignSep conf + else alignSep defaultConfig + t = template conf + def = [t, "", ""] + + -- | Reads the configuration files or quits with an error readConfig :: FilePath -> IO (Config,[String]) readConfig f = do diff --git a/src/Plugins/StdinReader.hs b/src/Plugins/StdinReader.hs index 2ee217e..935d76a 100644 --- a/src/Plugins/StdinReader.hs +++ b/src/Plugins/StdinReader.hs @@ -26,7 +26,8 @@ data StdinReader = StdinReader instance Exec StdinReader where start StdinReader cb = do - cb =<< catch (hGetLineSafe stdin) (\(SomeException e) -> do hPrint stderr e; return "") + cb =<< catch (hGetLineSafe stdin) + (\(SomeException e) -> do hPrint stderr e; return "") eof <- hIsEOF stdin if eof then exitImmediately ExitSuccess diff --git a/src/Xmobar.hs b/src/Xmobar.hs index f3e0907..566f8e8 100644 --- a/src/Xmobar.hs +++ b/src/Xmobar.hs @@ -73,23 +73,27 @@ data WakeUp = WakeUp deriving (Show,Typeable) instance Exception WakeUp -- | The event loop -eventLoop :: XConf -> [(Maybe ThreadId, TVar String)] -> IO () +eventLoop :: XConf -> [[(Maybe ThreadId, TVar String)]] -> IO () eventLoop xc@(XConf d _ w fs c) v = block $ do tv <- atomically $ newTVar [] t <- myThreadId - ct <- forkIO (checker t tv "" `catch` \(SomeException _) -> return ()) + ct <- forkIO (checker t tv [] `catch` \(SomeException _) -> return ()) go tv ct where -- interrupt the drawing thread every time a var is updated checker t tvar ov = do nval <- atomically $ do - nv <- fmap concat $ mapM (readTVar . snd) v + nv <- mapM concatV v guard (nv /= ov) writeTVar tvar nv return nv throwTo t WakeUp checker t tvar nval + concatV xs = do + s <- mapM (readTVar . snd) xs + return $ concat s + -- Continuously wait for a timer interrupt or an expose event go tv ct = do catch (unblock $ allocaXEvent $ \e -> @@ -217,21 +221,13 @@ getStaticStrutValues (Static cx cy cw ch) rwh xe = xs + cw getStaticStrutValues _ _ = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -updateWin :: TVar String -> X () +updateWin :: TVar [String] -> X () updateWin v = do xc <- ask + s <- io $ atomically $ readTVar v let (conf,rec) = (config &&& rect) xc - [lc,rc] = if length (alignSep conf) == 2 - then alignSep conf - else alignSep defaultConfig - i <- io $ atomically $ readTVar v - let def = [i,[],[]] - [l,c,r] = case break (==lc) i of - (le,_:re) -> case break (==rc) re of - (ce,_:ri) -> [le,ce,ri] - _ -> def - _ -> def - ps <- io $ mapM (parseString conf) [l,c,r] + l:c:r:_ = s ++ repeat "" + ps <- io $ mapM (parseString conf) [l, c, r] drawInWin rec ps -- $print -- cgit v1.2.3