{-# LANGUAGE RecordWildCards #-}
module XMonad.Hooks.DynamicIcons (
iconsPP, dynamicLogIconsWithPP, appIcon,
dynamicIconsPP, getWorkspaceIcons,
IconConfig(..),
iconsFmtAppend, iconsFmtReplace, wrapUnwords,
iconsGetAll, iconsGetFocus,
) where
import XMonad
import qualified XMonad.StackSet as S
import qualified Data.Map as M
import XMonad.Hooks.StatusBar.PP
import XMonad.Prelude (for, maybeToList, (<&>), (<=<), (>=>))
appIcon :: String -> Query [String]
appIcon :: String -> Query [String]
appIcon = [String] -> Query [String]
forall a. a -> Query a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([String] -> Query [String])
-> (String -> [String]) -> String -> Query [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure
dynamicLogIconsWithPP :: Query [String]
-> PP
-> X ()
dynamicLogIconsWithPP :: Query [String] -> PP -> X ()
dynamicLogIconsWithPP Query [String]
q = PP -> X ()
dynamicLogWithPP (PP -> X ()) -> (PP -> X PP) -> PP -> X ()
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Query [String] -> PP -> X PP
iconsPP Query [String]
q
iconsPP :: Query [String]
-> PP
-> X PP
iconsPP :: Query [String] -> PP -> X PP
iconsPP Query [String]
q = IconConfig -> PP -> X PP
dynamicIconsPP IconConfig
forall a. Default a => a
def{ iconConfigIcons = q }
dynamicIconsPP :: IconConfig -> PP -> X PP
dynamicIconsPP :: IconConfig -> PP -> X PP
dynamicIconsPP IconConfig
ic PP
pp = IconConfig -> X (String -> WindowSpace -> String)
getWorkspaceIcons IconConfig
ic X (String -> WindowSpace -> String)
-> ((String -> WindowSpace -> String) -> PP) -> X PP
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \String -> WindowSpace -> String
ren -> PP
pp{ ppRename = ppRename pp >=> ren }
getWorkspaceIcons :: IconConfig -> X (String -> WindowSpace -> String)
getWorkspaceIcons :: IconConfig -> X (String -> WindowSpace -> String)
getWorkspaceIcons conf :: IconConfig
conf@IconConfig{Query [String]
String -> [String] -> String
Maybe (Stack Window) -> X [Window]
iconConfigIcons :: IconConfig -> Query [String]
iconConfigIcons :: Query [String]
iconConfigFmt :: String -> [String] -> String
iconConfigFilter :: Maybe (Stack Window) -> X [Window]
iconConfigFilter :: IconConfig -> Maybe (Stack Window) -> X [Window]
iconConfigFmt :: IconConfig -> String -> [String] -> String
..} = Map String [String] -> String -> WindowSpace -> String
forall {k} {l} {a}.
Ord k =>
Map k [String] -> String -> Workspace k l a -> String
fmt (Map String [String] -> String -> WindowSpace -> String)
-> X (Map String [String]) -> X (String -> WindowSpace -> String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IconConfig -> X (Map String [String])
getWorkspaceIcons' IconConfig
conf
where
fmt :: Map k [String] -> String -> Workspace k l a -> String
fmt Map k [String]
icons String
s Workspace k l a
w = String -> [String] -> String
iconConfigFmt String
s ([String] -> k -> Map k [String] -> [String]
forall k a. Ord k => a -> k -> Map k a -> a
M.findWithDefault [] (Workspace k l a -> k
forall i l a. Workspace i l a -> i
S.tag Workspace k l a
w) Map k [String]
icons)
getWorkspaceIcons' :: IconConfig -> X (M.Map WorkspaceId [String])
getWorkspaceIcons' :: IconConfig -> X (Map String [String])
getWorkspaceIcons' IconConfig{Query [String]
String -> [String] -> String
Maybe (Stack Window) -> X [Window]
iconConfigIcons :: IconConfig -> Query [String]
iconConfigFilter :: IconConfig -> Maybe (Stack Window) -> X [Window]
iconConfigFmt :: IconConfig -> String -> [String] -> String
iconConfigIcons :: Query [String]
iconConfigFmt :: String -> [String] -> String
iconConfigFilter :: Maybe (Stack Window) -> X [Window]
..} = do
[WindowSpace]
ws <- (XState -> [WindowSpace]) -> X [WindowSpace]
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets (StackSet String (Layout Window) Window ScreenId ScreenDetail
-> [WindowSpace]
forall i l a s sd. StackSet i l a s sd -> [Workspace i l a]
S.workspaces (StackSet String (Layout Window) Window ScreenId ScreenDetail
-> [WindowSpace])
-> (XState
-> StackSet String (Layout Window) Window ScreenId ScreenDetail)
-> XState
-> [WindowSpace]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. XState
-> StackSet String (Layout Window) Window ScreenId ScreenDetail
windowset)
[[String]]
is <- [WindowSpace] -> (WindowSpace -> X [String]) -> X [[String]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [WindowSpace]
ws ((WindowSpace -> X [String]) -> X [[String]])
-> (WindowSpace -> X [String]) -> X [[String]]
forall a b. (a -> b) -> a -> b
$ (Window -> X [String]) -> [Window] -> X [String]
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Query [String] -> Window -> X [String]
forall a. Query a -> Window -> X a
runQuery Query [String]
iconConfigIcons) ([Window] -> X [String])
-> (WindowSpace -> X [Window]) -> WindowSpace -> X [String]
forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< Maybe (Stack Window) -> X [Window]
iconConfigFilter (Maybe (Stack Window) -> X [Window])
-> (WindowSpace -> Maybe (Stack Window))
-> WindowSpace
-> X [Window]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WindowSpace -> Maybe (Stack Window)
forall i l a. Workspace i l a -> Maybe (Stack a)
S.stack
Map String [String] -> X (Map String [String])
forall a. a -> X a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Map String [String] -> X (Map String [String]))
-> Map String [String] -> X (Map String [String])
forall a b. (a -> b) -> a -> b
$ [(String, [String])] -> Map String [String]
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ([String] -> [[String]] -> [(String, [String])]
forall a b. [a] -> [b] -> [(a, b)]
zip ((WindowSpace -> String) -> [WindowSpace] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map WindowSpace -> String
forall i l a. Workspace i l a -> i
S.tag [WindowSpace]
ws) [[String]]
is)
data IconConfig = IconConfig
{ IconConfig -> Query [String]
iconConfigIcons :: Query [String]
, IconConfig -> String -> [String] -> String
iconConfigFmt :: WorkspaceId -> [String] -> String
, IconConfig -> Maybe (Stack Window) -> X [Window]
iconConfigFilter :: Maybe (S.Stack Window) -> X [Window]
}
instance Default IconConfig where
def :: IconConfig
def = IconConfig
{ iconConfigIcons :: Query [String]
iconConfigIcons = Query [String]
forall a. Monoid a => a
mempty
, iconConfigFmt :: String -> [String] -> String
iconConfigFmt = ([String] -> String) -> String -> [String] -> String
iconsFmtReplace (String -> String -> [String] -> String
wrapUnwords String
"{" String
"}")
, iconConfigFilter :: Maybe (Stack Window) -> X [Window]
iconConfigFilter = Maybe (Stack Window) -> X [Window]
iconsGetAll
}
iconsFmtReplace :: ([String] -> String) -> WorkspaceId -> [String] -> String
iconsFmtReplace :: ([String] -> String) -> String -> [String] -> String
iconsFmtReplace [String] -> String
cat String
ws [String]
is | [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
is = String
ws
| Bool
otherwise = [String] -> String
cat [String]
is
iconsFmtAppend :: ([String] -> String) -> WorkspaceId -> [String] -> String
iconsFmtAppend :: ([String] -> String) -> String -> [String] -> String
iconsFmtAppend [String] -> String
cat String
ws [String]
is | [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
is = String
ws
| Bool
otherwise = String
ws String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char
':' Char -> String -> String
forall a. a -> [a] -> [a]
: [String] -> String
cat [String]
is
wrapUnwords :: String -> String -> [String] -> String
wrapUnwords :: String -> String -> [String] -> String
wrapUnwords String
_ String
_ [String
x] = String
x
wrapUnwords String
l String
r [String]
xs = String -> String -> String -> String
wrap String
l String
r ([String] -> String
unwords [String]
xs)
iconsGetAll :: Maybe (S.Stack Window) -> X [Window]
iconsGetAll :: Maybe (Stack Window) -> X [Window]
iconsGetAll = [Window] -> X [Window]
forall a. a -> X a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Window] -> X [Window])
-> (Maybe (Stack Window) -> [Window])
-> Maybe (Stack Window)
-> X [Window]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (Stack Window) -> [Window]
forall a. Maybe (Stack a) -> [a]
S.integrate'
iconsGetFocus :: Maybe (S.Stack Window) -> X [Window]
iconsGetFocus :: Maybe (Stack Window) -> X [Window]
iconsGetFocus = [Window] -> X [Window]
forall a. a -> X a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Window] -> X [Window])
-> (Maybe (Stack Window) -> [Window])
-> Maybe (Stack Window)
-> X [Window]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe Window -> [Window]
forall a. Maybe a -> [a]
maybeToList (Maybe Window -> [Window])
-> (Maybe (Stack Window) -> Maybe Window)
-> Maybe (Stack Window)
-> [Window]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Stack Window -> Window) -> Maybe (Stack Window) -> Maybe Window
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Stack Window -> Window
forall a. Stack a -> a
S.focus