aboutsummaryrefslogtreecommitdiff
path: root/src/Rahm/Desktop/XMobarLog.hs
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2022-04-10 13:26:16 -0600
committerJosh Rahm <joshuarahm@gmail.com>2022-10-09 12:19:46 -0600
commita652c330707e2e9bbe963e01af79ce730cf3452e (patch)
tree047655195f50efcbd51db8f825acf589dc6abead /src/Rahm/Desktop/XMobarLog.hs
parent381a3e5a00813314249bb74b5460f5ff5a4006bb (diff)
downloadrde-a652c330707e2e9bbe963e01af79ce730cf3452e.tar.gz
rde-a652c330707e2e9bbe963e01af79ce730cf3452e.tar.bz2
rde-a652c330707e2e9bbe963e01af79ce730cf3452e.zip
Rename Internal to Rahm.Desktop
Diffstat (limited to 'src/Rahm/Desktop/XMobarLog.hs')
-rw-r--r--src/Rahm/Desktop/XMobarLog.hs78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/Rahm/Desktop/XMobarLog.hs b/src/Rahm/Desktop/XMobarLog.hs
new file mode 100644
index 0000000..f3beb86
--- /dev/null
+++ b/src/Rahm/Desktop/XMobarLog.hs
@@ -0,0 +1,78 @@
+module Rahm.Desktop.XMobarLog ( XMobarLog, spawnXMobar, xMobarLogHook ) where
+
+import Control.Arrow (second)
+import Control.Monad (forM_)
+import Control.Monad.Writer (tell, execWriter)
+import Data.List (sortBy)
+import Data.Maybe (mapMaybe)
+import Data.Ord (comparing)
+import Rahm.Desktop.LayoutDraw (drawLayout)
+import System.IO (Handle, hSetEncoding, hPutStrLn, utf8)
+import XMonad.Util.NamedWindows (getName)
+import XMonad.Util.Run (spawnPipe)
+import XMonad (X)
+import Rahm.Desktop.Lib (getPopulatedWorkspaces, WorkspaceState(..))
+
+import qualified XMonad as X
+import qualified XMonad.StackSet as S
+
+data XMobarLog = XMobarLog Handle
+
+-- The log hook for XMobar. This is a custom log hook that does not use any
+-- of the Xmonad dynamic log libraries.
+--
+-- This is because the given dynamic log libraries don't handle unicode properly
+-- and this has been causing issues. It is also more flexible and frankly easier
+-- to just DIY.
+
+spawnXMobar :: IO XMobarLog
+spawnXMobar = do
+ pipe <- spawnPipe "xmobar"
+ hSetEncoding pipe utf8
+ return (XMobarLog pipe)
+
+
+-- XMonad Log Hook meant to be used with the XMonad config logHook.
+xMobarLogHook :: XMobarLog -> X ()
+xMobarLogHook (XMobarLog xmproc) = do
+ (_, _, layoutXpm) <- drawLayout
+
+ winset <- X.gets X.windowset
+ title <- maybe (pure "") (fmap show . getName) . S.peek $ winset
+ let wss = getPopulatedWorkspaces winset
+
+ X.liftIO $ do
+ hPutStrLn xmproc $ trunc 80 $ execWriter $ do
+ tell layoutXpm
+ tell $ "<fc=#404040> │ </fc>"
+
+ forM_ wss $ \(t, ws) -> do
+ case t of
+ Current -> tell "<fn=1><fc=#ff8888>"
+ Visible -> tell "<fn=6><fc=#8888ff>"
+ Hidden -> tell "<fn=2><fc=#888888>"
+ tell (S.tag ws)
+ tell " </fc></fn>"
+
+ tell $ "<fc=#404040>│ </fc><fc=#a0a0a0><fn=3>"
+ tell $ title
+ tell $ "</fn></fc>"
+
+-- Truncate an XMobar string to the provided number of _visible_ characters.
+-- This is to keep long window titles from overrunning the whole bar.
+trunc :: Int -> String -> String
+trunc amt str = reverse $ trunc' False amt str []
+ where
+ trunc' _ _ [] acc = acc
+ trunc' ignore amt (a:as) acc =
+ case a of
+ '<' -> trunc' True amt as (a : acc)
+ '>' -> trunc' False amt as (a : acc)
+ _ ->
+ if ignore
+ then trunc' True amt as (a : acc)
+ else
+ case amt of
+ 0 -> trunc' False 0 as acc
+ 3 -> trunc' False 0 as ("..." ++ acc)
+ _ -> trunc' False (amt - 1) as (a : acc)