------------------------------------------------------------------------------- |-- Module : XMonad.Hooks.DynamicBars-- Copyright : (c) Ben Boeckel 2012-- License : BSD-style (as xmonad)---- Maintainer : mathstuf@gmail.com-- Stability : unstable-- Portability : unportable---- Manage per-screen status bars.-------------------------------------------------------------------------------moduleXMonad.Hooks.DynamicBars(-- * Usage-- $usageDynamicStatusBar,DynamicStatusBarCleanup,dynStatusBarStartup,dynStatusBarEventHook,multiPP)whereimportPreludeimportControl.Concurrent.MVarimportControl.MonadimportControl.Monad.Trans(lift)importControl.Monad.Writer(WriterT,execWriterT,tell)importData.MaybeimportData.MonoidimportData.Traversable(traverse)importGraphics.X11.XineramaimportGraphics.X11.XlibimportGraphics.X11.Xlib.ExtrasimportGraphics.X11.XrandrimportSystem.IOimportSystem.IO.UnsafeimportXMonadimportqualifiedXMonad.StackSetasWimportXMonad.Hooks.DynamicLog-- $usage-- Provides a few helper functions to manage per-screen status bars while-- dynamically responding to screen changes. A startup action, event hook, and-- a way to separate PP styles based on the screen's focus are provided:---- * The 'dynStatusBarStartup' hook which initializes the status bars.---- * The 'dynStatusBarEventHook' hook which respawns status bars when the-- number of screens changes.---- * The 'multiPP' function which allows for different output based on whether-- the screen for the status bar has focus.---- The hooks take a 'DynamicStatusBar' function which is given the id of the-- screen to start up and returns the 'Handle' to the pipe to write to. The-- 'DynamicStatusBarCleanup' argument should tear down previous instances. It-- is called when the number of screens changes and on startup.--dataDynStatusBarInfo=DynStatusBarInfo{dsbInfoScreens::[ScreenId],dsbInfoHandles::[Handle]}typeDynamicStatusBar=ScreenId->IOHandletypeDynamicStatusBarCleanup=IO()-- Global statestatusBarInfo::MVarDynStatusBarInfostatusBarInfo=unsafePerformIO$newMVar(DynStatusBarInfo[][])dynStatusBarStartup::DynamicStatusBar->DynamicStatusBarCleanup->X()dynStatusBarStartupsbcleanup=liftIO$dodpy<-openDisplay""xrrSelectInputdpy(defaultRootWindowdpy)rrScreenChangeNotifyMaskcloseDisplaydpyupdateStatusBarssbcleanupdynStatusBarEventHook::DynamicStatusBar->DynamicStatusBarCleanup->Event->XAlldynStatusBarEventHooksbcleanup(RRScreenChangeNotifyEvent{})=liftIO(updateStatusBarssbcleanup)>>return(AllTrue)dynStatusBarEventHook___=return(AllTrue)updateStatusBars::DynamicStatusBar->DynamicStatusBarCleanup->IO()updateStatusBarssbcleanup=liftIO$dodsbInfo<-takeMVarstatusBarInfoscreens<-getScreensif(screens/=(dsbInfoScreensdsbInfo))thendomapMhClose(dsbInfoHandlesdsbInfo)cleanupnewHandles<-mapMsbscreensputMVarstatusBarInfo(DynStatusBarInfoscreensnewHandles)elseputMVarstatusBarInfodsbInfo------------------------------------------------------------------------------- The following code is from adamvo's xmonad.hs file.-- http://www.haskell.org/haskellwiki/Xmonad/Config_archive/adamvo%27s_xmonad.hsmultiPP::PP-- ^ The PP to use if the screen is focused->PP-- ^ The PP to use otherwise->X()multiPPfocusPPunfocusPP=dodsbInfo<-liftIO$readMVarstatusBarInfomultiPP'dynamicLogStringfocusPPunfocusPP(dsbInfoHandlesdsbInfo)multiPP'::(PP->XString)->PP->PP->[Handle]->X()multiPP'dynlStrfocusPPunfocusPPhandles=dost<-getletpickPP::WorkspaceId->WriterT(LastXState)XStringpickPPws=doletisFoc=(ws==).W.tag.W.workspace.W.current$windowsetstputst{windowset=W.viewws$windowsetst}out<-lift$dynlStr$ifisFocthenfocusPPelseunfocusPPwhenisFoc$get>>=tell.Last.Justreturnouttraverseput.getLast=<<execWriterT.(io.zipWithM_hPutStrLnhandles<=<mapMpickPP).catMaybes=<<mapMscreenWorkspace(zipWithconst[0..]handles)return()getScreens::IO[ScreenId]getScreens=doscreens<-dodpy<-openDisplay""rects<-getScreenInfodpycloseDisplaydpyreturnrectsletids=zip[0..]screensreturn$mapfstids