diff --git a/XMonad/Hooks/DynamicIcons.hs b/XMonad/Hooks/DynamicIcons.hs
index c57298b2..fe180d42 100644
--- a/XMonad/Hooks/DynamicIcons.hs
+++ b/XMonad/Hooks/DynamicIcons.hs
@@ -18,11 +18,11 @@ module XMonad.Hooks.DynamicIcons (
-- $usage
-- * Creating Dynamic Icons
- dynamicLogIconsWithPP, dynamicIconsPP,
+ dynamicLogIconsWithPP, appIcon,
- -- * Data Types
- appIcon, IconSet,
- IconConfig(..), Icon(..),
+ -- * Customization
+ dynamicIconsPP, getWorkspaceIcons,
+ IconConfig(..),
iconsFmtAppend, iconsFmtReplace, wrapUnwords,
) where
@@ -32,8 +32,9 @@ import qualified XMonad.StackSet as S
import qualified Data.Map as M
import XMonad.Hooks.DynamicLog
+import Data.Functor ((<&>))
import Data.Traversable (for)
-import Control.Monad ((<=<))
+import Control.Monad ((<=<), (>=>))
-- $usage
-- Dynamically changes a 'Workspace's 'WorkspaceId' based on the 'Window's inside the Workspace.
@@ -65,48 +66,20 @@ import Control.Monad ((<=<))
-- NOTE: You can use any string you want here. The example shown here, uses NerdFont Icons to represent open applications
--- | Custom datatype for custom icons based on the state of the 'Workspace'
--- For example,
---
--- > Icon "discord" "discord" "discord" ""
---
--- Then you can add it to your IconSet.
---
--- > icons :: IconSet
--- > icons = mconcat
--- > [ className =? "discord" --> pure [Icon "discord" "discord" "discord" ""]
--- > ]
-data Icon = Icon
- { iconCurrent :: !String -- ^ If the 'Workspace' is the current workspace
- , iconVisible :: !String -- ^ If the 'Workspace' is visible (Xinerama only)
- , iconHidden :: !String -- ^ If the 'Workspace' isnt visible but still has windows
- , iconHiddenNoWindows :: !String -- ^ If the 'Workspace' isnt visible and has no windows
- }
-
--- | The set of Icons to use
-type IconSet = Query [Icon]
-
-baseIconSet :: String -> Icon
-baseIconSet x =
- Icon { iconCurrent = x
- , iconVisible = x
- , iconHidden = x
- , iconHiddenNoWindows = x
- }
-
--- | Create an 'IconSet' from a 'String'
-appIcon :: String -> IconSet
-appIcon x = pure [baseIconSet x]
+-- | Shortcut for configuring single icons.
+appIcon :: String -> Query [String]
+appIcon = pure . pure
-- | Adjusts the 'PP' and then runs 'dynamicLogWithPP'
-dynamicLogIconsWithPP :: IconSet -- ^ The 'IconSet' to use
+dynamicLogIconsWithPP :: Query [String] -- ^ The 'IconSet' to use
-> PP -- ^ The 'PP' to alter
-> X () -- ^ The resulting 'X' action
-dynamicLogIconsWithPP iconset = dynamicLogWithPP <=< dynamicIconsPP def{ iconConfigIcons = iconset }
+dynamicLogIconsWithPP q = dynamicLogWithPP <=< dynamicIconsPP def{ iconConfigIcons = q }
-- | Datatype for expanded 'Icon' configurations
data IconConfig = IconConfig
- { iconConfigIcons :: IconSet -- ^ The 'IconSet' to use
+ { iconConfigIcons :: Query [String]
+ -- ^ What icons to use for each window.
, iconConfigFmt :: WorkspaceId -> [String] -> String
-- ^ How to format the result, see 'iconsFmtReplace', 'iconsFmtAppend'.
}
@@ -166,20 +139,17 @@ wrapUnwords l r xs = wrap l r (unwords xs)
-- | Modify "XMonad.Hooks.DynamicLog"\'s pretty-printing format to augment
-- workspace names with icons based on the contents (windows) of the workspace.
dynamicIconsPP :: IconConfig -> PP -> X PP
-dynamicIconsPP IconConfig{..} pp = do
- icons <- getWorkspaceIcons iconConfigIcons
- pure $ pp
- { ppCurrent = ppSection ppCurrent iconCurrent icons
- , ppVisible = ppSection ppVisible iconVisible icons
- , ppHidden = ppSection ppHidden iconHidden icons
- , ppHiddenNoWindows = ppSection ppHiddenNoWindows iconHiddenNoWindows icons
- }
- where
- ppSection ppField icField icons wks =
- ppField pp $ iconConfigFmt wks $ map icField $ M.findWithDefault [] wks icons
+dynamicIconsPP ic pp = getWorkspaceIcons ic <&> \ren -> pp{ ppRename = ppRename pp >=> ren }
-getWorkspaceIcons :: IconSet -> X (M.Map WorkspaceId [Icon])
-getWorkspaceIcons iconSet = do
+-- | Returns a function for 'ppRename' that augments workspaces with icons
+-- according to the provided 'IconConfig'.
+getWorkspaceIcons :: IconConfig -> X (String -> WindowSpace -> String)
+getWorkspaceIcons IconConfig{..} = fmt <$> getWorkspaceIcons' iconConfigIcons
+ where
+ fmt icons s w = iconConfigFmt s (M.findWithDefault [] (S.tag w) icons)
+
+getWorkspaceIcons' :: Query [String] -> X (M.Map WorkspaceId [String])
+getWorkspaceIcons' q = do
ws <- gets (S.workspaces . windowset)
- is <- for ws $ foldMap (runQuery iconSet) . S.integrate' . S.stack
+ is <- for ws $ foldMap (runQuery q) . S.integrate' . S.stack
pure $ M.fromList (zip (map S.tag ws) is)