-
Notifications
You must be signed in to change notification settings - Fork 0
/
xmonad.hs
401 lines (354 loc) · 15.1 KB
/
xmonad.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
--
-- xmonad example config file for xmonad-0.9
--
-- A template showing all available configuration hooks,
-- and how to override the defaults in your own xmonad.hs conf file.
--
-- Normally, you'd only override those defaults you care about.
--
-- NOTE: Those updating from earlier xmonad versions, who use
-- EwmhDesktops, safeSpawn, WindowGo, or the simple-status-bar
-- setup functions (dzen, xmobar) probably need to change
-- xmonad.hs, please see the notes below, or the following
-- link for more details:
--
-- http://www.haskell.org/haskellwiki/Xmonad/Notable_changes_since_0.8
--
import Data.Monoid
import Data.Tuple
import Data.Ratio ((%))
import qualified Data.Map as M
import System.Exit
import System.IO
import System.Posix.Unistd
import XMonad
import qualified XMonad.StackSet as W
import XMonad.Actions.Volume
import XMonad.Actions.SpawnOn
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.SetWMName
import XMonad.Hooks.UrgencyHook
import XMonad.Hooks.EwmhDesktops
import XMonad.Util.Run(spawnPipe)
import XMonad.Layout.ResizableTile
import XMonad.Layout.PerWorkspace
import XMonad.Layout.NoBorders
import XMonad.Layout.Tabbed
import XMonad.Layout.Grid
import XMonad.Layout.IM
import XMonad.Actions.TopicSpace
import XMonad.Prompt
import XMonad.Prompt.Workspace
host = fmap nodeName getSystemID
scriptBin = "~/.xmonad/bin/"
myBrowser = scriptBin ++ "browser.sh"
myTerminal = "terminator" --probably must name this myTerminal
myEmail = "thunderbird"
myCalendar = scriptBin ++ "calendar.sh"
myTasks = scriptBin ++ "tasks.sh"
javaOracle = "export PATH=/usr/lib/jvm/java-7-oracle/jre/bin/java/:$PATH;"
javaOpen = "export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin/:$PATH;"
pyCharm = scriptBin ++ "pycharm.sh"
eclipse = javaOpen ++ "eclipse"
leksah = "leksah"
dmenuExec = "exe=`dmenu_path | dmenu` && eval \"exec $exe\""
dmenuWhite = "exe=`cat " ++ scriptBin ++ "dmenu_whitelist|dmenu` && eval \"exec $exe\""
-- Whether focus follows the mouse pointer.
myFocusFollowsMouse :: Bool
myFocusFollowsMouse = True
-- Width of the window border in pixels.
--
myBorderWidth = 1
-- modMask lets you specify which modkey you want to use. The default
-- is mod1Mask ("left alt"). You may also consider using mod3Mask
-- ("right alt"), which does not conflict with emacs keybindings. The
-- "windows key" is usually mod4Mask.
--
myModMask = mod4Mask
spawnShell :: X ()
spawnShell = currentTopicDir myTopicConfig >>= spawnShellIn
spawnShellIn :: Dir -> X ()
spawnShellIn dir = spawn $ "urxvt '(cd ''" ++ dir ++ "'' && " ++ myTerminal ++ " )'"
-- The list of all topics/workspaces of your xmonad configuration.
-- The order is important, new topics must be inserted
-- at the end of the list if you want hot-restarting
-- to work.
data TI = TI
{ topic :: Topic
, keySym :: KeySym
, fn :: X()
}
tiT :: TI -> Topic
tiT (TI topic _ _) = topic
tiK :: TI -> KeySym
tiK (TI _ keySym _) = keySym
tiF :: TI -> X()
tiF (TI _ _ fn) = fn
topics :: [TI]
topics =
-- Main list
[ TI "home" xK_F1 $ return ()
, TI "media" xK_m $ return () -- TODO bring up media list somehow
, TI "talk" xK_t $ spawnHere "pidgin"
, TI "email" xK_e $ spawnHere myEmail
, TI "calendar" xK_c $ spawnHere myCalendar
, TI "tasks" xK_q $ spawnHere myTasks
, TI "journal" xK_j $ spawnHere "gedit ~/journal/`date +'%y-%m-%d'`"
, TI "internet" xK_i $ spawnHere myBrowser
, TI "gaming" xK_g $ return () -- TODO bring up game list somehow
, TI "eclipse1" xK_1 $ spawnHere eclipse
, TI "pycharm3" xK_3 $ spawnHere pyCharm
, TI "leksah5" xK_5 $ spawnHere leksah
, TI "documentation" xK_d $ spawnHere myBrowser
-- Secondary list
, TI "eclipse2" xK_2 $ spawnHere eclipse
, TI "pycharm4" xK_4 $ spawnHere pyCharm
, TI "leksah6" xK_6 $ spawnHere leksah
, TI "terminator" xK_F2 $ return ()
, TI "misc3" xK_F3 $ return ()
, TI "misc4" xK_F4 $ return ()
, TI "misc5" xK_F5 $ return ()
, TI "misc6" xK_F6 $ return ()
, TI "misc7" xK_F7 $ return ()
, TI "misc8" xK_F8 $ return ()
, TI "misc9" xK_F9 $ return ()
, TI "misc10" xK_F10 $ return ()
, TI "misc11" xK_F11 $ return ()
, TI "misc12" xK_F12 $ return ()
, TI "spare0" xK_0 $ return ()
-- Put hot-added workspaces after here. Organize later.
]
myTopics = map tiT topics
myTopicKeys = map tiK topics
myTopicFns = zip myTopics (map tiF topics)
myTopicConfig :: TopicConfig
myTopicConfig = defaultTopicConfig
{ topicDirs = M.fromList []
, defaultTopicAction = const $ spawnShell >*> 3
, defaultTopic = "home"
, topicActions = M.fromList myTopicFns
}
-- Border colors for unfocused and focused windows, respectively.
--
myNormalBorderColor = "#dddddd"
myFocusedBorderColor = "#ff0000"
-- Keys
noModMask = 0
altMaskLeft = mod1Mask
altMaskRight = mod3Mask
audioRaiseVolume :: KeySym
audioRaiseVolume = 0x1008FF13
audioLowerVolume :: KeySym
audioLowerVolume = 0x1008FF11
audioMute :: KeySym
audioMute = 0x1008FF12
audioPrev :: KeySym
audioPrev = 0x1008FF16
audioNext :: KeySym
audioNext = 0x1008FF17
audioPlay :: KeySym
audioPlay = 0x1008FF14
calculator :: KeySym
calculator = 0x1008FF1D
------------------------------------------------------------------------
-- Key bindings. Add, modify or remove key bindings here.
--
myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $
[
-- Media
((noModMask, audioLowerVolume), lowerVolume 4 >> return ())
, ((noModMask, audioRaiseVolume), raiseVolume 4 >> return ())
, ((noModMask, audioMute ), spawn $ scriptBin ++ "mute.rb")
, ((noModMask, audioPrev ), spawn $ scriptBin ++ "prev.sh")
, ((noModMask, audioNext ), spawn $ scriptBin ++ "next.sh")
, ((noModMask, audioPlay ), spawn $ scriptBin ++ "play.sh")
-- Window launching
, ((noModMask, calculator), spawnHere $ myTerminal ++ " -e python")
-- terminal
, ((modm .|. shiftMask, xK_Return ), spawnHere $ XMonad.terminal conf)
-- browser
, ((modm, xK_KP_Subtract), spawnHere myBrowser)
-- Launch dmenu w/ whitelist
, ((modm, xK_grave ), spawn dmenuWhite)
-- Launch dmenu w/o whitelist
, ((modm .|. altMaskLeft, xK_grave ), spawn dmenuExec)
, ((modm .|. altMaskRight, xK_grave ), spawn dmenuExec)
-- Layout
-- Rotate through the available layout algorithms
, ((modm, xK_space ), sendMessage NextLayout)
-- Reset the layouts on the current workspace to default
, ((modm .|. altMaskLeft, xK_space ), setLayout $ XMonad.layoutHook conf)
, ((modm .|. altMaskRight, xK_space ), setLayout $ XMonad.layoutHook conf)
-- Shrink the master area horizontally
, ((modm, xK_Down ), sendMessage Shrink)
-- Expand the master area horizontally
, ((modm, xK_Up ), sendMessage Expand)
-- Shrink the master area vertically
, ((modm .|. shiftMask, xK_Down ), sendMessage MirrorShrink)
-- Expand the master area vertically
, ((modm .|. shiftMask, xK_Up ), sendMessage MirrorExpand)
-- Push window back into tiling
, ((modm .|. shiftMask, xK_grave ), withFocused $ windows . W.sink)
-- Increment the number of windows in the master area
, ((modm , xK_comma ), sendMessage (IncMasterN 1))
-- Deincrement the number of windows in the master area
, ((modm , xK_period ), sendMessage (IncMasterN (-1)))
-- Window
-- close focused window
, ((modm, xK_backslash ), kill)
-- Move focus to the next window
, ((modm, xK_Tab ), windows W.focusDown)
-- Move focus to the previous window
, ((modm .|. shiftMask, xK_Tab ), windows W.focusUp)
-- Move focus to the master window
, ((modm .|. altMaskLeft, xK_Tab ), windows W.focusMaster)
, ((modm .|. altMaskRight, xK_Tab ), windows W.focusMaster)
-- Swap the focused window and the master window
, ((modm, xK_Return ), windows W.swapMaster)
-- Swap the focused window with the next window
, ((modm , xK_bracketright), windows W.swapDown)
-- Swap the focused window with the previous window
, ((modm, xK_bracketleft ), windows W.swapUp)
-- Goto workspace
, ((modm, xK_KP_0 ), workspacePrompt defaultXPConfig (switchTopic myTopicConfig))
, ((modm, xK_KP_Insert ), workspacePrompt defaultXPConfig (switchTopic myTopicConfig))
-- Shift to workspace
, ((modm .|. shiftMask, xK_KP_0 ), workspacePrompt defaultXPConfig $ windows . W.shift)
, ((modm .|. shiftMask, xK_KP_Insert ), workspacePrompt defaultXPConfig $ windows . W.shift)
-- XMonad
-- Quit xmonad
, ((modm .|. shiftMask, xK_Escape), io (exitWith ExitSuccess))
-- Restart xmonad
, ((modm .|. altMaskLeft, xK_Return), spawn "xmonad --recompile; xmonad --restart")
, ((modm .|. altMaskRight, xK_Return), spawn "xmonad --recompile; xmonad --restart")
-- Lock screen
, ((modm, xK_Escape), spawn "gnome-screensaver-command -l")
-- Machine
-- Shutdown
--, ((modm .|. altMaskLeft, xK_Escape), spawn "gksu shutdown -h now")
--, ((modm .|. altMaskRight, xK_Escape), spawn "gksu shutdown -h now")
-- Restart
--, ((modm .|. controlMask, xK_Escape), spawn "sudo shutdown -r now")
]
++
--
-- mod-topicKey, Switch to workspace
-- mod-shift-topicKey, Move client to workspace
--
[((m .|. modm, k), windows $ f i)
| (i, k) <- zip (XMonad.workspaces conf) myTopicKeys
, (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]
++
--
-- mod-{keypad1,keypad2,keypad3}, Switch to physical/Xinerama screens 1, 2, or 3
-- mod-shift-{keypad1,keypad3,keypad3}, Move client to screen 1, 2, or 3
--
[((m .|. modm, key), screenWorkspace sc >>= flip whenJust (windows . f))
| (key, sc) <- zip [xK_KP_1, xK_KP_2, xK_KP_3] [0..]
, (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]
------------------------------------------------------------------------
-- Mouse bindings: default actions bound to mouse events
--
myMouseBindings (XConfig {XMonad.modMask = modm}) = M.fromList $
[
-- Left Mouse Button - raise the window to the top of the stack
((modm, button1), (\w -> focus w >> windows W.shiftMaster))
-- Right Mouse Button - set the window to floating mode and move by dragging
, ((modm, button3), (\w -> focus w >> mouseMoveWindow w
>> windows W.shiftMaster))
-- Right Mouse Button + Shift - set the window to floating mode and resize by dragging
, ((modm .|. shiftMask, button3), (\w -> focus w >> mouseResizeWindow w
>> windows W.shiftMaster))
]
------------------------------------------------------------------------
-- Layouts:
-- You can specify and transform your layouts by modifying these values.
-- If you change layout bindings be sure to use 'mod-shift-space' after
-- restarting (with 'mod-q') to reset your layout state to the new
-- defaults, as xmonad preserves your old layout settings by default.
--
singletonWorkspaces = ["media", "gaming"]
talkWorkspaces = ["talk"]
myLayout = onWorkspaces singletonWorkspaces singletonLayout
$ onWorkspaces talkWorkspaces talkLayout
$ regularLayouts
regularLayouts = avoidStruts $ Grid ||| Full
singletonLayout = avoidStruts $ noBorders $ simpleTabbed ||| Full
talkLayout = avoidStruts $ withIM (1%7) (Role "buddy_list") Grid ||| Full
------------------------------------------------------------------------
-- Window rules:
-- Execute arbitrary actions and WindowSet manipulations when managing
-- a new window. You can use this to, for example, always float a
-- particular program, or have a client always appear on a particular
-- workspace.
--
-- To find the property name associated with a program, use
-- > xprop | grep WM_CLASS
-- and click on the client you're interested in.
--
-- To match on the WM_NAME, you can use 'title' in the same way that
-- 'className' and 'resource' are used below.
--
myManageHook = composeAll
[ className =? "MPlayer" --> doFloat
, className =? "Gimp" --> doFloat
, className =? "Pidgin" --> doShift "talk"
, className =? "Pithos" --> doShift "media"
, className =? "Thunderbird" --> doShift "email"
, resource =? "desktop_window" --> doIgnore
, resource =? "kdesktop" --> doIgnore
, isFullscreen --> doFullFloat
]
------------------------------------------------------------------------
-- Event handling
-- Defines a custom handler function for X Events. The function should
-- return (All True) if the default handler is to be run afterwards. To
-- combine event hooks use mappend or mconcat from Data.Monoid.
--
-- * NOTE: EwmhDesktops users should use the 'ewmh' function from
-- XMonad.Hooks.EwmhDesktops to modify their defaultConfig as a whole.
-- It will add EWMH event handling to your custom event hooks by
-- combining them with ewmhDesktopsEventHook.
--
myEventHook = mempty
------------------------------------------------------------------------
-- Status bars and logging
-- Perform an arbitrary action on each internal state change or X event.
-- See the 'XMonad.Hooks.DynamicLog' extension for examples.
--myLogHook = return ()
------------------------------------------------------------------------
-- Startup hook
-- Perform an arbitrary action each time xmonad starts or is restarted
-- with mod-q. Used by, e.g., XMonad.Layout.PerWorkspace to initialize
-- per-workspace layout choices.
myStartupHook =
-- Fixes java display issue
setWMName "LG3D"
------------------------------------------------------------------------
-- Now run xmonad with all the defaults we set up.
-- Run xmonad with the settings you specify. No need to modify this.
--
main = do
checkTopicConfig myTopics myTopicConfig
xmproc <- spawnPipe "xmobar"
xmonad $ ewmh $ withUrgencyHook NoUrgencyHook $ defaultConfig {
-- simple stuff
terminal = myTerminal
, focusFollowsMouse = myFocusFollowsMouse
, borderWidth = myBorderWidth
, modMask = myModMask
, workspaces = myTopics
, normalBorderColor = myNormalBorderColor
, focusedBorderColor = myFocusedBorderColor
-- key bindings
, keys = myKeys
, mouseBindings = myMouseBindings
-- hooks, layouts
, layoutHook = myLayout
, manageHook = manageSpawn <+> myManageHook
, handleEventHook = myEventHook
, logHook = dynamicLogWithPP $ xmobarPP { ppOutput = hPutStrLn xmproc }
, startupHook = myStartupHook
}