diff options
author | Tomas Janousek <tomi@nomi.cz> | 2019-08-13 21:41:15 +0200 |
---|---|---|
committer | Tomas Janousek <tomi@nomi.cz> | 2020-02-22 22:15:44 +0000 |
commit | 32fc8214c567c7f4a4caad10fab98c760a1685b7 (patch) | |
tree | fc9725cae245446e08ef95fa295a3affbac06fab /src/Xmobar/App/Main.hs | |
parent | 2a71487437ca4afed6f35acc1e16c2e03bfc053c (diff) | |
download | xmobar-32fc8214c567c7f4a4caad10fab98c760a1685b7.tar.gz xmobar-32fc8214c567c7f4a4caad10fab98c760a1685b7.tar.bz2 |
Implement timer coalescing (noticeably less CPU/power usage)
xmobar currently runs every monitor in its own thread. Monitors that do
periodic updates simply sleep and loop. This unfortunately leads to
these threads coming out of sync, and xmobar ends up waking up and
redrawing for every periodic monitor. In my case, that is 7 times per
second, which is enough for xmobar to be at the top of "top" with more
than 1% CPU usage, and to have a noticeable impact on battery life.
This commit adds a central timer coordination thread which makes sure
that periodic updates happen together and that we only redraw once
they're all done.
Together with PR #409, I managed to lower the idle power draw of my
laptop from 4W to 3W.
Diffstat (limited to 'src/Xmobar/App/Main.hs')
-rw-r--r-- | src/Xmobar/App/Main.hs | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/src/Xmobar/App/Main.hs b/src/Xmobar/App/Main.hs index 29504f4..e0b0329 100644 --- a/src/Xmobar/App/Main.hs +++ b/src/Xmobar/App/Main.hs @@ -40,9 +40,10 @@ import Xmobar.X11.Types import Xmobar.X11.Text import Xmobar.X11.Window import Xmobar.App.Opts (recompileFlag, verboseFlag, getOpts, doOpts) -import Xmobar.App.EventLoop (startLoop, startCommand) +import Xmobar.App.EventLoop (startLoop, startCommand, newRefreshLock, refreshLock) import Xmobar.App.Compile (recompile, trace) import Xmobar.App.Config +import Xmobar.App.Timer (withTimer) xmobar :: Config -> IO () xmobar conf = withDeferSignals $ do @@ -53,14 +54,16 @@ xmobar conf = withDeferSignals $ do cls <- mapM (parseTemplate (commands conf) (sepChar conf)) (splitTemplate (alignSep conf) (template conf)) sig <- setupSignalHandler - bracket (mapM (mapM $ startCommand sig) cls) - cleanupThreads - $ \vars -> do - (r,w) <- createWin d fs conf - let ic = Map.empty - to = textOffset conf - ts = textOffsets conf ++ replicate (length fl) (-1) - startLoop (XConf d r w (fs:fl) (to:ts) ic conf) sig vars + refLock <- newRefreshLock + withTimer (refreshLock refLock) $ + bracket (mapM (mapM $ startCommand sig) cls) + cleanupThreads + $ \vars -> do + (r,w) <- createWin d fs conf + let ic = Map.empty + to = textOffset conf + ts = textOffsets conf ++ replicate (length fl) (-1) + startLoop (XConf d r w (fs:fl) (to:ts) ic conf) sig refLock vars configFromArgs :: Config -> IO Config configFromArgs cfg = getArgs >>= getOpts >>= doOpts cfg . fst |