]> code.delx.au - dotfiles/blob - .xmonad/xmonad.hs
xmonad: use mapM to avoid duplicate xmobar lines
[dotfiles] / .xmonad / xmonad.hs
1 {-# LANGUAGE FlexibleContexts #-}
2 import System.IO
3 import XMonad
4 import XMonad.Actions.PhysicalScreens
5 import XMonad.Hooks.DynamicLog
6 import XMonad.Hooks.EwmhDesktops
7 import XMonad.Hooks.ICCCMFocus
8 import XMonad.Hooks.ManageDocks
9 import XMonad.Hooks.ManageHelpers
10 import XMonad.Hooks.Script
11 import XMonad.Hooks.SetWMName
12 import XMonad.Layout.IM
13 import XMonad.Layout.LayoutHints
14 import qualified XMonad.Layout.Magnifier as Mag
15 import XMonad.Layout.Master
16 import XMonad.Layout.NoBorders
17 import XMonad.Layout.NoFrillsDecoration
18 import XMonad.Layout.PerWorkspace
19 import XMonad.Layout.Renamed
20 import XMonad.Layout.Reflect
21 import XMonad.Layout.Tabbed
22 import XMonad.Layout.ThreeColumns
23 import XMonad.Util.Run(spawnPipe)
24 import XMonad.Util.WindowProperties(getProp32s)
25 import qualified Data.Map as M
26 import qualified XMonad.StackSet as W
27
28
29 myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $
30 [
31 ((modm .|. shiftMask, xK_h), spawn "xfce4-session-logout"),
32 ((modm .|. shiftMask, xK_l), spawn "xscreensaver-command --lock"),
33
34 ((modm, xK_n), spawn "xfce4-terminal"),
35 ((modm, xK_i), spawn "firefox"),
36 ((modm, xK_p), spawn "kupfer"),
37
38 ((modm .|. shiftMask, xK_c ), kill),
39 ((modm, xK_space ), sendMessage NextLayout),
40 ((modm .|. shiftMask, xK_space ), setLayout $ XMonad.layoutHook conf),
41 ((modm, xK_Tab ), windows W.focusDown),
42 ((modm .|. shiftMask, xK_Tab ), windows W.focusUp),
43 ((modm, xK_j ), windows W.focusDown),
44 ((modm, xK_k ), windows W.focusUp ),
45 ((modm, xK_m ), windows W.focusMaster ),
46 ((modm, xK_Return), windows W.swapMaster),
47 ((modm .|. shiftMask, xK_j ), windows W.swapDown ),
48 ((modm .|. shiftMask, xK_k ), windows W.swapUp ),
49 ((modm, xK_h ), sendMessage Shrink),
50 ((modm, xK_l ), sendMessage Expand),
51 ((modm, xK_t ), withFocused $ windows . W.sink),
52 ((modm , xK_comma ), sendMessage (IncMasterN 1)),
53 ((modm , xK_period), sendMessage (IncMasterN (-1))),
54 ((modm , xK_b ), sendMessage ToggleStruts),
55 ((modm , xK_z ), sendMessage Mag.Toggle)
56 ]
57 ++
58
59 -- mod-{o,e,u}, Switch to physical/Xinerama screens 1, 2, or 3
60 -- mod-shift-{o,e,u}, Move client to screen 1, 2, or 3
61 [((m .|. modm, key), f sc)
62 | (key, sc) <- zip [xK_o, xK_e, xK_u] [0..]
63 , (f, m) <- [(viewScreen, 0), (sendToScreen, shiftMask)]
64 ]
65 ++
66
67 -- mod-[1..9], Switch to workspace N
68 -- mod-shift-[1..9], Move client to workspace N
69 [((m .|. modm, k), windows $ f i)
70 | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9]
71 , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]
72 ]
73
74
75 avoidMaster = W.modify' $ \c -> case c of
76 W.Stack t [] (r:rs) -> W.Stack t [r] rs
77 otherwise -> c
78
79 isTransient = ask >>= \w -> liftX $ do
80 r <- getProp32s "WM_TRANSIENT_FOR" w
81 return $ case r of
82 Just [_] -> True
83 _ -> False
84
85 isSkipTaskBar = isInProperty "_NET_WM_STATE" "_NET_WM_STATE_SKIP_TASKBAR"
86
87
88 myManageHook =
89 manageDocks <+>
90 composeOne [
91 (className =? "Kupfer.py" <&&> resource =? "kupfer.py") -?> doFloat,
92 (className =? "Xfce4-appfinder" <&&> resource =? "xfce4-appfinder") -?> doFloatAt 0.1 0.1,
93 (isSkipTaskBar -?> doFloat),
94 (isDialog -?> doFloatAt 0.1 0.1),
95 (isTransient -?> doFloatAt 0.1 0.1),
96 (isFullscreen -?> doFullFloat),
97 (fmap Just $ doF avoidMaster)
98 ]
99
100
101 myWorkspaces = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
102
103 myPP = xmobarPP
104 {
105 ppCurrent = xmobarColor "#A01010" "" . wrap "[" "]",
106 ppTitle = xmobarColor "#10A010" ""
107 }
108
109 myLogHook hooks = do
110 mapM (\h -> dynamicLogWithPP myPP { ppOutput = hPutStrLn h }) hooks
111 takeTopFocus -- fix for Java Swing apps
112
113 myStartupHook = do
114 setWMName "LG3D" -- fix for Java Swing apps
115
116
117 goldenRatio = (toRational (2/(1+sqrt(5)::Double)))
118
119 myTitleTheme = defaultTheme {
120 fontName = "xft:sans-serif:size=10",
121 decoHeight = 24
122 }
123
124 createLayout name layout =
125 renamed [Replace name] $
126 layoutHints $
127 smartBorders $
128 layout
129
130 myFullLayout = createLayout "Full" $
131 noBorders $
132 Full
133
134 myTiledLayout = createLayout "Tall" $
135 avoidStruts $
136 Mag.magnifierOff $
137 Tall nMaster ratioIncrement masterRatio
138 where
139 nMaster = 1
140 ratioIncrement = 3/100
141 masterRatio = goldenRatio
142
143 myTabbedLayout = createLayout "Tab" $
144 avoidStruts $
145 tabbed shrinkText myTitleTheme
146
147 myThreeColLayout = createLayout "ThreeCol" $
148 avoidStruts $
149 Mag.magnifierOff $
150 ThreeCol numMaster resizeDelta masterRatio
151 where
152 resizeDelta = 3/100
153 masterRatio = 4/10
154 numMaster = 1
155
156 myMasterTabbedLayout = createLayout "MTab" $
157 avoidStruts $
158 Mag.magnifierOff $
159 mastered resizeDelta masterRatio $
160 tabbed shrinkText myTitleTheme
161 where
162 resizeDelta = 3/100
163 masterRatio = goldenRatio
164
165 myGimpLayout = createLayout "Gimp" $
166 avoidStruts $
167 withIM (1/6) (Role "gimp-toolbox") $
168 reflectHoriz $
169 withIM (1/6) (Role "gimp-dock") $
170 reflectHoriz $
171 tabbed shrinkText myTitleTheme
172
173
174 -- This was the easiest way I found to avoid a compile error when I have
175 -- an unused layout
176 referenceAllLayoutsToAvoidErrors =
177 myFullLayout |||
178 myTiledLayout |||
179 myTabbedLayout |||
180 myThreeColLayout |||
181 myMasterTabbedLayout |||
182 myGimpLayout
183
184
185 myLayout =
186 (
187 onWorkspace "1" (myTabbedLayout ||| myMasterTabbedLayout) $
188 onWorkspace "2" (myTabbedLayout ||| myMasterTabbedLayout) $
189 onWorkspace "9" (myFullLayout ||| myMasterTabbedLayout ||| myTabbedLayout ||| myTiledLayout ||| myGimpLayout) $
190 (myMasterTabbedLayout ||| myTabbedLayout ||| myTiledLayout)
191 )
192
193 main = do
194 xmonadDir <- getXMonadDir
195 xmobars <- mapM (\x -> spawnPipe ("xmobar -x " ++ (show x) ++ " " ++ xmonadDir ++ "/xmobar.hs")) [1, 2]
196 xmonad $ ewmh defaultConfig {
197 manageHook = myManageHook,
198 layoutHook = myLayout,
199 workspaces = myWorkspaces,
200 logHook = myLogHook xmobars,
201 startupHook = myStartupHook,
202 keys = myKeys,
203 handleEventHook = handleEventHook defaultConfig <+> fullscreenEventHook,
204 focusFollowsMouse = False
205 }
206