packages feed

taffybar 3.0.0 → 3.1.0

raw patch · 20 files changed

+202/−81 lines, 20 filesdep +bytestringdep +scottydep −xmonad-contribdep ~dbusdep ~gi-glibdep ~gtk-sni-tray

Dependencies added: bytestring, scotty

Dependencies removed: xmonad-contrib

Dependency ranges changed: dbus, gi-glib, gtk-sni-tray, status-notifier-item

Files

CHANGELOG.md view
@@ -1,3 +1,10 @@+# 3.1.0++## New Features++ * A new module Chrome which makes it so that Workspaces can display the+   favicons of the website that the chrome window is currently visiting.+ # 3.0.0  ## Breaking Changes
app/Main.hs view
@@ -26,7 +26,7 @@ versionOption = infoOption                 (printf "taffybar %s" $ showVersion version)                 (  long "version"-                <> help "Show the version number of gtk-sni-tray"+                <> help "Show the version number of taffybar"                 )  main :: IO ()
src/System/Taffybar.hs view
@@ -154,8 +154,8 @@   dataDir <- getDataDir   return (dataDir </> name) -startCSS :: IO Gtk.CssProvider-startCSS = do+startCSS :: Maybe FilePath -> IO Gtk.CssProvider+startCSS configCssPath = do   -- Override the default GTK theme path settings.  This causes the   -- bar (by design) to ignore the real GTK theme and just use the   -- provided minimal theme to set the background and text colors.@@ -165,6 +165,7 @@         doesFileExist filePath >>=         flip when (Gtk.cssProviderLoadFromPath taffybarProvider (T.pack filePath))   loadIfExists =<< getDefaultConfigFile "taffybar.css"+  mapM_ loadIfExists configCssPath   loadIfExists =<< getUserConfigFile "taffybar" "taffybar.css"   Just scr <- Gdk.screenGetDefault   Gtk.styleContextAddProviderForScreen scr taffybarProvider 800@@ -181,7 +182,7 @@   _ <- initThreads   _ <- Gtk.init Nothing   GIThreading.setCurrentThreadAsGUIThread-  _ <- startCSS+  _ <- startCSS $ cssPath config   _ <- buildContext config    Gtk.main
src/System/Taffybar/Context.hs view
@@ -84,6 +84,7 @@   { dbusClientParam :: Maybe DBus.Client   , startupHook :: TaffyIO ()   , getBarConfigsParam :: BarConfigGetter+  , cssPath :: Maybe FilePath   , errorMsg :: Maybe String   } @@ -96,6 +97,7 @@   { dbusClientParam = Nothing   , startupHook = return ()   , getBarConfigsParam = return []+  , cssPath = Nothing   , errorMsg = Nothing   } @@ -216,7 +218,8 @@               newConfs = filter (`notElem` currentConfigs) barConfigs               (remainingWindows, removedWindows) =                 partition ((`elem` barConfigs) . sel1) currentWindows-              setPropertiesFromPair (barConf, window) = setupStrutWindow (strutConfig barConf) window+              setPropertiesFromPair (barConf, window) =+                setupStrutWindow (strutConfig barConf) window            newWindowPairs <- lift $ do             logIO DEBUG $ printf "removedWindows: %s" $@@ -320,8 +323,8 @@   identifier <- lift newUnique   listenersVar <- asks listeners   let-    -- This type annotation probably has something to do with the warnings that-    -- occur without MonoLocalBinds, but it still seems to be necessary+    -- XXX: This type annotation probably has something to do with the warnings+    -- that occur without MonoLocalBinds, but it still seems to be necessary     addListener :: SubscriptionList -> SubscriptionList     addListener = ((identifier, listener):)   lift $ MV.modifyMVar_ listenersVar (return . addListener)
src/System/Taffybar/DBus/Toggle.hs view
@@ -27,6 +27,7 @@ import qualified Data.Map as M import           Data.Maybe import qualified GI.Gdk as Gdk+import qualified GI.Gtk as Gtk import           Graphics.UI.GIGtkStrut import           Paths_taffybar ( getDataDir ) import           Prelude@@ -135,6 +136,7 @@           , autoMethod "showOnMonitor" $             takeInt $ toggleTaffyOnMon (const True)           , autoMethod "refresh" $ runReaderT refreshTaffyWindows ctx+          , autoMethod "exit" (Gtk.mainQuit :: IO ())           ]         }   lift $ do
src/System/Taffybar/Hooks.hs view
@@ -1,7 +1,11 @@ module System.Taffybar.Hooks   ( module System.Taffybar.DBus   , module System.Taffybar.Hooks+  , ChromeTabImageData(..)   , refreshBatteriesOnPropChange+  , getX11WindowToChromeTabId+  , getChromeTabImageDataChannel+  , getChromeTabImageDataTable   ) where  import           Control.Applicative@@ -15,6 +19,7 @@ import           System.Taffybar.Context import           System.Taffybar.DBus import           System.Taffybar.Information.Battery+import           System.Taffybar.Information.Chrome import           System.Taffybar.Information.Network import           System.Taffybar.Information.XDG.DesktopEntry import           System.Taffybar.Util
+ src/System/Taffybar/Information/Chrome.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE OverloadedStrings #-}+module System.Taffybar.Information.Chrome where++import           Control.Concurrent+import           Control.Monad+import           Control.Monad.Trans.Class+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as LBS+import qualified Data.Map as M+import           Data.Maybe+import qualified GI.GLib as Gdk+import qualified GI.GdkPixbuf as Gdk+import           Prelude+import           System.Log.Logger+import           System.Taffybar.Context hiding (logIO, logT)+import           System.Taffybar.Information.EWMHDesktopInfo+import           System.Taffybar.Information.SafeX11+import           Text.Read hiding (lift)+import           Text.Regex+import           Web.Scotty++logIO :: System.Log.Logger.Priority -> String -> IO ()+logIO = logM "System.Taffybar.Information.Chrome"++data ChromeTabImageData = ChromeTabImageData+  { tabImageData :: Gdk.Pixbuf+  , tabImageDataId :: Int+  }++newtype ChromeTabImageDataState =+  ChromeTabImageDataState+  (MVar (M.Map Int ChromeTabImageData), Chan ChromeTabImageData)++getChromeTabImageDataState :: TaffyIO ChromeTabImageDataState+getChromeTabImageDataState = do+  ChromeFaviconServerPort port <- fromMaybe (ChromeFaviconServerPort 5000) <$> getState+  getStateDefault (listenForChromeFaviconUpdates port)++getChromeTabImageDataChannel :: TaffyIO (Chan ChromeTabImageData)+getChromeTabImageDataChannel = do+  ChromeTabImageDataState (_, chan) <- getChromeTabImageDataState+  return chan++getChromeTabImageDataTable :: TaffyIO (MVar (M.Map Int ChromeTabImageData))+getChromeTabImageDataTable = do+  ChromeTabImageDataState (table, _) <- getChromeTabImageDataState+  return table++newtype ChromeFaviconServerPort = ChromeFaviconServerPort Int++listenForChromeFaviconUpdates :: Int -> TaffyIO ChromeTabImageDataState+listenForChromeFaviconUpdates port = do+  infoVar <- lift $ newMVar M.empty+  chan <- lift newChan+  _ <- lift $ forkIO $ scotty port $+    post "/setTabImageData/:tabID" $ do+      tabID <- param "tabID"+      imageData <- LBS.toStrict <$> body+      when (BS.length imageData > 0) $ lift $ do+        loader <- Gdk.pixbufLoaderNew+        Gdk.pixbufLoaderWriteBytes loader =<< Gdk.bytesNew (Just imageData)+        Gdk.pixbufLoaderClose loader+        pixbuf <- Gdk.pixbufLoaderGetPixbuf loader+        let chromeTabImageData =+              ChromeTabImageData+              { tabImageData = pixbuf+              , tabImageDataId = tabID+              }+        modifyMVar_ infoVar $ \currentMap -> do+          writeChan chan chromeTabImageData+          return $ M.insert tabID chromeTabImageData currentMap+  return $ ChromeTabImageDataState (infoVar, chan)++newtype X11WindowToChromeTabId = X11WindowToChromeTabId (MVar (M.Map X11Window Int))++getX11WindowToChromeTabId :: TaffyIO X11WindowToChromeTabId+getX11WindowToChromeTabId =+  getStateDefault $ X11WindowToChromeTabId <$> maintainX11WindowToChromeTabId++maintainX11WindowToChromeTabId :: TaffyIO (MVar (M.Map X11Window Int))+maintainX11WindowToChromeTabId = do+  startTabMap <- updateTabMap M.empty+  tabMapVar <- lift $ newMVar startTabMap+  let handleEvent PropertyEvent { ev_window = window } =+        do+          title <- runX11Def "" $ getWindowTitle window+          lift $ modifyMVar_ tabMapVar $ \currentMap -> do+            let newMap = addTabIdEntry currentMap (window, title)+            logIO DEBUG (show newMap)+            return newMap+      handleEvent _ = return ()+  subscribeToEvents ["_NET_WM_NAME"] handleEvent+  return tabMapVar++tabIDRegex :: Regex+tabIDRegex = mkRegexWithOpts "[|]%([0-9]*)%[|]" True True++getTabIdFromTitle :: String -> Maybe Int+getTabIdFromTitle title =+  matchRegex tabIDRegex title >>= listToMaybe >>= readMaybe++addTabIdEntry :: M.Map X11Window Int -> (X11Window, String) -> M.Map X11Window Int+addTabIdEntry theMap (win, title) =+          maybe theMap ((flip $ M.insert win) theMap) $ getTabIdFromTitle title++updateTabMap :: M.Map X11Window Int -> TaffyIO (M.Map X11Window Int)+updateTabMap tabMap =+  runX11Def tabMap $ do+    wins <- getWindows+    titles <- mapM getWindowTitle wins+    let winsWithTitles = zip wins titles+    return $ foldl addTabIdEntry tabMap winsWithTitles
src/System/Taffybar/SimpleConfig.hs view
@@ -29,8 +29,8 @@ import           Graphics.UI.GIGtkStrut import           System.Taffybar.Information.X11DesktopInfo import           System.Taffybar-import qualified System.Taffybar.Context as BC (BarConfig(..))-import           System.Taffybar.Context hiding (BarConfig(..))+import qualified System.Taffybar.Context as BC (BarConfig(..), TaffybarConfig(..))+import           System.Taffybar.Context hiding (BarConfig(..), cssPath) import           System.Taffybar.Util  -- | The side of the monitor at which taffybar should be displayed.@@ -57,6 +57,9 @@   , centerWidgets :: [TaffyIO Gtk.Widget]   -- | Widget constructors whose results are placed at the end of the bar   , endWidgets :: [TaffyIO Gtk.Widget]+  -- | Optional path to CSS stylesheet (loaded in addition to stylesheet found+  -- in XDG data directory).+  , cssPath :: Maybe FilePath   }  -- | Sensible defaults for most of the fields of 'SimpleTaffyConfig'. You'll@@ -72,6 +75,7 @@   , startWidgets = []   , centerWidgets = []   , endWidgets = []+  , cssPath = Nothing   }  toStrutConfig :: SimpleTaffyConfig -> Int -> StrutConfig@@ -108,7 +112,10 @@ newtype SimpleBarConfigs = SimpleBarConfigs (MV.MVar [(Int, BC.BarConfig)])  toTaffyConfig :: SimpleTaffyConfig -> TaffybarConfig-toTaffyConfig conf = defaultTaffybarConfig { getBarConfigsParam = configGetter }+toTaffyConfig conf =+    defaultTaffybarConfig { getBarConfigsParam = configGetter+                          , BC.cssPath = cssPath conf+                          }   where     configGetter = do       SimpleBarConfigs configsVar <-
src/System/Taffybar/Util.hs view
@@ -26,8 +26,6 @@ import qualified Data.GI.Gtk.Threading as Gtk import qualified Data.Text as T import           Data.Tuple.Sequence-import           GI.GLib.Constants-import           GI.Gdk (threadsAddIdle) import qualified GI.GdkPixbuf.Objects.Pixbuf as Gdk import           System.Exit (ExitCode (..)) import           System.Log.Logger@@ -137,12 +135,5 @@             printf "Failed to load icon from filepath %s" filepath   return $ rightToMaybe result -postGUIASync action =-  threadsAddIdle PRIORITY_DEFAULT_IDLE (action >> return False) >> return ()---- XXX: This has serious problems becuase it will cause a hang if it is used--- when already on the UI Thread-postGUISync action = do-  ans <- newEmptyMVar-  threadsAddIdle PRIORITY_DEFAULT_IDLE $ action >>= putMVar ans >> return False-  takeMVar ans+postGUIASync = Gtk.postGUIASync+postGUISync = Gtk.postGUISync
src/System/Taffybar/Widget/Battery.hs view
@@ -109,12 +109,16 @@   ctx <- ask   liftIO $ do     image <- imageNew+    styleCtx <- widgetGetStyleContext =<< toWidget image     defaultTheme <- iconThemeGetDefault     let getCurrentBatteryIconNameString =           T.pack . batteryIconName <$> runReaderT getDisplayBatteryInfo ctx+        extractPixbuf info =+          fst <$> iconInfoLoadSymbolicForContext info styleCtx         setIconForSize size = do           name <- getCurrentBatteryIconNameString-          iconThemeLoadIcon defaultTheme name size themeLoadFlags >>=-                            traverse (scalePixbufToSize size OrientationHorizontal)+          iconThemeLookupIcon defaultTheme name size themeLoadFlags >>=+            traverse extractPixbuf >>=+              traverse (scalePixbufToSize size OrientationHorizontal)     updateImage <- autoSizeImage image setIconForSize OrientationHorizontal     toWidget =<< channelWidgetNew image chan (const $ postGUIASync updateImage)
src/System/Taffybar/Widget/FreedesktopNotifications.hs view
@@ -121,8 +121,8 @@                            Nothing -> Just timeout                            Just maxTimeout -> Just (min maxTimeout timeout) -  escapedSummary <- markupEscapeText summary (fromIntegral $ T.length summary)-  escapedBody <- markupEscapeText body (fromIntegral $ T.length body)+  escapedSummary <- markupEscapeText summary (-1)+  escapedBody <- markupEscapeText body (-1)   let n = Notification { noteAppName = appName                        , noteReplaceId = replaceId                        , noteSummary = escapedSummary@@ -194,7 +194,7 @@ startTimeoutThread s Notification {..} = case noteExpireTimeout of   Nothing -> return ()   Just timeout -> void $ forkIO $ do-    threadDelay (fromIntegral timeout * 10^(6 :: Int))+    threadDelay (fromIntegral timeout * 10^(3 :: Int))     notePurge s noteId     wakeupDisplayThread s 
src/System/Taffybar/Widget/MPRIS2.hs view
@@ -144,7 +144,7 @@  playingText :: MonadIO m => Int -> Int -> NowPlaying -> m T.Text playingText artistMax songMax NowPlaying {npArtists = artists, npTitle = title} =-  G.markupEscapeText formattedText (fromIntegral $ T.length formattedText)+  G.markupEscapeText formattedText (-1)   where formattedText = T.pack $ printf            "%s - %s"            (truncateString artistMax $ intercalate "," artists)
src/System/Taffybar/Widget/SNITray.hs view
@@ -13,6 +13,7 @@  import           Control.Monad.Trans.Class import           Control.Monad.Trans.Reader+import           Data.Ratio import qualified GI.Gtk import           Graphics.UI.GIGtkStrut import qualified StatusNotifier.Host.Service as H@@ -48,6 +49,7 @@         , trayImageSize = Expand         , trayIconExpand = False         , trayAlignment = End+        , trayOverlayScale = 3 % 5         }     _ <- widgetSetClassGI tray "sni-tray"     GI.Gtk.widgetShowAll tray@@ -57,5 +59,6 @@ sniTrayNew = getHost False >>= sniTrayNewFromHost  sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt :: TaffyIO GI.Gtk.Widget-sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt = getHost True >>= sniTrayNewFromHost+sniTrayThatStartsWatcherEvenThoughThisIsABadWayToDoIt =+  getHost True >>= sniTrayNewFromHost 
src/System/Taffybar/Widget/Util.hs view
@@ -15,7 +15,7 @@ module System.Taffybar.Widget.Util where  import           Control.Concurrent ( forkIO )-import           Control.Monad ( forever, void )+import           Control.Monad import           Control.Monad.IO.Class import           Control.Monad.Trans.Maybe import           Data.Functor ( ($>) )@@ -130,22 +130,10 @@   ]  getImageForDesktopEntry :: Int32 -> DesktopEntry -> IO (Maybe GI.Pixbuf)-getImageForDesktopEntry size entry = runMaybeT $ do-  iconName <- MaybeT $ return $ deIcon entry-  let iconNameText = T.pack iconName-  MaybeT $ do-    iconTheme <- Gtk.iconThemeGetDefault-    hasIcon <- Gtk.iconThemeHasIcon iconTheme iconNameText-    logPrintFDebug "System.Taffybar.Widget.Util" "Entry: %s" entry-    logPrintFDebug "System.Taffybar.Widget.Util" "Icon present: %s" hasIcon-    if hasIcon-    then-      Gtk.iconThemeLoadIcon iconTheme iconNameText size themeLoadFlags-    else do-      exists <- doesFileExist iconName-      if isAbsolute iconName && exists-      then Just <$> GI.pixbufNewFromFile iconName-      else return Nothing+getImageForDesktopEntry size entry = fmap join $ traverse run $ deIcon entry+  where run iconName =+          maybeTCombine (loadPixbufByName size $ T.pack iconName)+                        (getPixbufFromFilePath iconName)  loadPixbufByName :: Int32 -> T.Text -> IO (Maybe GI.Pixbuf) loadPixbufByName size name = do@@ -183,4 +171,3 @@ renderWithContext :: GI.Cairo.Context -> C.Render () -> IO () renderWithContext ct r = GI.Cairo.withManagedPtr ct $ \p ->   runReaderT (runRender r) (Cairo (castPtr p))-
src/System/Taffybar/Widget/Weather.hs view
@@ -241,12 +241,12 @@         DefaultWeatherFormatter -> do           let rawLabel = T.pack $ defaultFormatter labelTpl wi           let rawTooltip = T.pack $ defaultFormatter tooltipTpl wi-          lbl <- markupEscapeText rawLabel (fromIntegral $ T.length rawLabel)-          tooltip <- markupEscapeText rawTooltip (fromIntegral $ T.length rawTooltip)+          lbl <- markupEscapeText rawLabel (-1)+          tooltip <- markupEscapeText rawTooltip (-1)           return (lbl, Just tooltip)         WeatherFormatter f -> do           let rawLabel = T.pack $ f wi-          lbl <- markupEscapeText rawLabel (fromIntegral $ T.length rawLabel)+          lbl <- markupEscapeText rawLabel (-1)           return (lbl, Just lbl)     Left err -> do       putStrLn err
src/System/Taffybar/Widget/Windows.hs view
@@ -14,15 +14,7 @@ -- which to switch the focus. ----------------------------------------------------------------------------- -module System.Taffybar.Widget.Windows (-  -- * Usage-  -- $usage-    windowsNew-  , WindowsConfig(..)-  , defaultWindowsConfig-  , truncatedGetActiveLabel-  , truncatedGetMenuLabel-) where+module System.Taffybar.Widget.Windows where  import           Control.Monad import           Control.Monad.Trans.Class@@ -37,16 +29,6 @@ import           System.Taffybar.Widget.Generic.DynamicMenu import           System.Taffybar.Widget.Util --- $usage------ The window switcher widget requires that the EwmhDesktops hook from the--- XMonadContrib project be installed in your @xmonad.hs@ file:------ > import XMonad.Hooks.EwmhDesktops (ewmh)--- > main = do--- >   xmonad $ ewmh $ defaultConfig--- > ...- data WindowsConfig = WindowsConfig   { getMenuLabel :: X11Window -> TaffyIO T.Text   -- ^ A monadic function that will be used to make a label for the window in@@ -58,11 +40,12 @@ defaultGetMenuLabel :: X11Window -> TaffyIO T.Text defaultGetMenuLabel window = do   windowString <- runX11Def "(nameless window)" (getWindowTitle window)-  markupEscapeText (T.pack windowString) $ fromIntegral $ length windowString+  return $ T.pack windowString  defaultGetActiveLabel :: TaffyIO T.Text-defaultGetActiveLabel = fromMaybe "" <$>-  (runX11Def Nothing getActiveWindow >>= traverse defaultGetMenuLabel)+defaultGetActiveLabel = do+  label <- fromMaybe "" <$> (runX11Def Nothing getActiveWindow >>= traverse defaultGetMenuLabel)+  markupEscapeText label (-1)  truncatedGetActiveLabel :: Int -> TaffyIO T.Text truncatedGetActiveLabel maxLength =@@ -75,8 +58,8 @@ defaultWindowsConfig :: WindowsConfig defaultWindowsConfig =   WindowsConfig-  { getMenuLabel = defaultGetMenuLabel-  , getActiveLabel = defaultGetActiveLabel+  { getMenuLabel = truncatedGetMenuLabel 35+  , getActiveLabel = truncatedGetActiveLabel 35   }  -- | Create a new Windows widget that will use the given Pager as
src/System/Taffybar/Widget/Workspaces.hs view
@@ -23,7 +23,6 @@ import           Control.Monad.Trans.Maybe import           Control.Monad.Trans.Reader import           Control.RateLimit-import qualified Data.Char as Char import qualified Data.Foldable as F import           Data.Int import           Data.List (intersect, sortBy)@@ -628,6 +627,10 @@ getWindowIconPixbufFromDesktopEntry :: WindowIconPixbufGetter getWindowIconPixbufFromDesktopEntry size windowData =   getWindowIconFromDesktopEntryByClasses size (windowClass windowData)++getWindowIconPixbufFromChrome :: WindowIconPixbufGetter+getWindowIconPixbufFromChrome _ windowData =+  getPixBufFromChromeData $ windowId windowData  defaultGetWindowIconPixbuf :: WindowIconPixbufGetter defaultGetWindowIconPixbuf =
src/System/Taffybar/WindowIcon.hs view
@@ -1,5 +1,6 @@ module System.Taffybar.WindowIcon where +import           Control.Concurrent import           Control.Monad import           Control.Monad.IO.Class import           Control.Monad.Trans.Class@@ -7,6 +8,7 @@ import           Data.Bits import           Data.Int import           Data.List+import qualified Data.Map as M import           Data.Maybe import qualified Data.MultiMap as MM import           Data.Ord@@ -21,6 +23,7 @@ import           System.Log.Logger import           System.Taffybar.Context import           System.Taffybar.Hooks+import           System.Taffybar.Information.Chrome import           System.Taffybar.Information.EWMHDesktopInfo import           System.Taffybar.Information.X11DesktopInfo import           System.Taffybar.Information.XDG.DesktopEntry@@ -88,7 +91,7 @@   :: MonadIO m   => Int32 -> Word32 -> m Gdk.Pixbuf pixBufFromColor imgSize c = do-  Just pixbuf <- Gdk.pixbufNew Gdk.ColorspaceRgb True 8 imgSize imgSize+  pixbuf <- fromJust <$> Gdk.pixbufNew Gdk.ColorspaceRgb True 8 imgSize imgSize   Gdk.pixbufFill pixbuf c   return pixbuf @@ -124,3 +127,10 @@ getWindowIconFromClasses =   getWindowIconForAllClasses getWindowIconFromClass   where getWindowIconFromClass size klass = loadPixbufByName size (T.pack klass)++getPixBufFromChromeData :: X11Window -> TaffyIO (Maybe Gdk.Pixbuf)+getPixBufFromChromeData window = do+  imageData <- getChromeTabImageDataTable >>= lift . readMVar+  X11WindowToChromeTabId x11LookupMapVar <- getX11WindowToChromeTabId+  x11LookupMap <- lift $ readMVar x11LookupMapVar+  return $ tabImageData <$> (M.lookup window x11LookupMap >>= flip M.lookup imageData)
taffybar.cabal view
@@ -1,5 +1,5 @@ name: taffybar-version: 3.0.0+version: 3.1.0 synopsis: A desktop bar similar to xmobar, but with more GUI license: BSD3 license-file: LICENSE@@ -43,9 +43,10 @@                , HStringTemplate >= 0.8 && < 0.9                , HTTP                , X11 >= 1.5.0.1+               , bytestring                , cairo                , containers-               , dbus >= 1.0.0 && < 2.0.0+               , dbus >= 1.2.1 && < 2.0.0                , dbus-hslogger >= 0.1.0.1 && < 0.2.0.0                , directory                , dyre >= 0.8.6 && < 0.9@@ -56,12 +57,12 @@                , gi-gdk                , gi-gdkpixbuf >= 2.0.16                , gi-gdkx11-               , gi-glib+               , gi-glib >= 2.0.17                , gi-gtk                , gi-gtk-hs                , gi-pango                , glib-               , gtk-sni-tray >= 0.1.4.0+               , gtk-sni-tray >= 0.1.5.0                , gtk-strut >= 0.1.2.1                , haskell-gi >= 0.21.2                , haskell-gi-base >= 0.21.1@@ -73,8 +74,9 @@                , rate-limit >= 1.1.1                , regex-compat                , safe >= 0.3 && < 1+               , scotty >= 11.2 && < 12.0                , split >= 0.1.4.2-               , status-notifier-item >= 0.3.0.0+               , status-notifier-item >= 0.3.0.1                , stm                , template-haskell                , text@@ -90,7 +92,6 @@                , xml                , xml-helpers                , xmonad-               , xmonad-contrib    if flag(network-uri)     build-depends: network-uri >= 2.6 && < 3, network >= 2.6 && < 3@@ -107,6 +108,7 @@                  , System.Taffybar.Information.Battery                  , System.Taffybar.Information.CPU                  , System.Taffybar.Information.CPU2+                 , System.Taffybar.Information.Chrome                  , System.Taffybar.Information.DiskIO                  , System.Taffybar.Information.EWMHDesktopInfo                  , System.Taffybar.Information.MPRIS2
taffybar.hs.example view
@@ -1,4 +1,5 @@ -- -*- mode:haskell -*-+{-# LANGUAGE OverloadedStrings #-} module Main where  import System.Taffybar