Advertisement
Guest User

xmoand.hs

a guest
Jun 23rd, 2014
3,537
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.29 KB | None | 0 0
  1. -------------------------------------------------------------------------------------------
  2. -- File : ~/.xmonad/xmonad.hs --
  3. -- Author : Nnoell <nnoell3[at]gmail.com> --
  4. -- Desc : My XMonad config --
  5. --------------------------------------------------------------------------------------------
  6.  
  7. -- Options
  8. {-# LANGUAGE DeriveDataTypeable, NoMonomorphismRestriction, MultiParamTypeClasses, ImplicitParams #-}
  9. {-# OPTIONS_GHC -fcontext-stack=1024 #-}
  10.  
  11. -- Modules
  12. import XMonad
  13. import XMonad.Layout
  14. import XMonad.Layout.IM
  15. import XMonad.Layout.Gaps
  16. import XMonad.Layout.Named
  17. import XMonad.Layout.Tabbed
  18. import XMonad.Layout.OneBig
  19. import XMonad.Layout.Reflect
  20. import XMonad.Layout.MosaicAlt
  21. import XMonad.Layout.NoFrillsDecoration
  22. import XMonad.Layout.SimplestFloat
  23. import XMonad.Layout.NoBorders
  24. import XMonad.Layout.ResizableTile
  25. import XMonad.Layout.MultiToggle
  26. import XMonad.Layout.MultiToggle.Instances
  27. import XMonad.Layout.PerWorkspace
  28. import XMonad.Layout.Minimize
  29. import XMonad.Layout.Maximize
  30. import XMonad.Layout.ToggleLayouts
  31. import XMonad.Layout.MagicFocus
  32. import XMonad.Layout.WindowNavigation
  33. import XMonad.Layout.WindowSwitcherDecoration
  34. import XMonad.Layout.DraggingVisualizer
  35. import XMonad.Layout.LayoutBuilder
  36. import XMonad.Hooks.DynamicLog
  37. import XMonad.Hooks.DynamicHooks
  38. import XMonad.Hooks.ManageDocks
  39. import XMonad.Hooks.UrgencyHook
  40. import XMonad.Hooks.EwmhDesktops
  41. import XMonad.Hooks.SetWMName
  42. import XMonad.Hooks.ManageHelpers
  43. import XMonad.Prompt
  44. import XMonad.Prompt.Shell
  45. import XMonad.Prompt.XMonad
  46. import XMonad.Prompt.Man
  47. import XMonad.Util.Timer
  48. import XMonad.Util.Cursor
  49. import XMonad.Util.Loggers
  50. import XMonad.Util.Run
  51. import XMonad.Util.Scratchpad
  52. import XMonad.Util.NamedScratchpad
  53. import XMonad.Actions.CycleWS
  54. import XMonad.Actions.ShowText
  55. import XMonad.Actions.GridSelect
  56. import XMonad.Actions.MouseResize
  57. import XMonad.Actions.FloatKeys
  58. import Data.Monoid
  59. import Data.List
  60. import System.Exit
  61. import System.IO
  62. import Control.Concurrent
  63. import Graphics.X11.ExtraTypes.XF86
  64. import Graphics.X11.Xinerama
  65. import Control.Applicative
  66. import Control.Exception as E
  67. import qualified XMonad.StackSet as W
  68. import qualified Data.Map as M
  69. import qualified XMonad.Actions.FlexibleResize as Flex
  70. import qualified XMonad.Util.ExtensibleState as XS
  71.  
  72.  
  73. --------------------------------------------------------------------------------------------
  74. -- MAIN --
  75. --------------------------------------------------------------------------------------------
  76.  
  77. main :: IO ()
  78. main = do
  79. r <- getScreenRes ":0" 0 --display ":0", screen 0
  80. topLeftBar <- dzenSpawnPipe $ dzenTopLeftFlags r
  81. topRightBar <- dzenSpawnPipe $ dzenTopRightFlags r
  82. botLeftBar <- dzenSpawnPipe $ dzenBotLeftFlags r
  83. botRightBar <- dzenSpawnPipe $ dzenBotRightFlags r
  84. xmonad $ myUrgencyHook defaultConfig
  85. { terminal = "/usr/bin/xfce4-terminal" --default terminal
  86. , modMask = mod4Mask --default modMask
  87. , focusFollowsMouse = True --focus follow config
  88. , clickJustFocuses = True --focus click config
  89. , borderWidth = 1 --border width
  90. , normalBorderColor = colorBlackAlt --border color
  91. , focusedBorderColor = colorWhiteAlt2 --focused border color
  92. , workspaces = myWorkspaces --workspace names
  93. , startupHook = myStartupHook --autostart config
  94. , handleEventHook = myHandleEventHook --event config
  95. , layoutHook = myLayoutHook --layout config
  96. , manageHook = myManageHook --xprop config
  97. , logHook = --status bar config
  98. myTopLeftLogHook topLeftBar <+> --top left dzen
  99. myTopRightLogHook topRightBar <+> --top right dzen
  100. myBotLeftLogHook botLeftBar <+> --bottom left dzen
  101. myBotRightLogHook botRightBar <+> --bottom right dzen
  102. ewmhDesktopsLogHook >>
  103. setWMName "LG3D"
  104. , keys = myKeys --key bindings config
  105. , mouseBindings = myMouseBindings --mouse bindings config
  106. }
  107.  
  108.  
  109. --------------------------------------------------------------------------------------------
  110. -- LOOK AND FEEL CONFIG --
  111. --------------------------------------------------------------------------------------------
  112.  
  113. -- Colors, fonts and paths
  114. dzenFont = "-*-montecarlo-medium-r-normal-*-11-*-*-*-*-*-*-*"
  115. colorBlack = "#020202" --Background
  116. colorBlackAlt = "#1c1c1c" --Black Xdefaults
  117. colorGray = "#444444" --Gray
  118. colorGrayAlt = "#101010" --Gray dark
  119. colorGrayAlt2 = "#404040"
  120. colorGrayAlt3 = "#252525"
  121. colorWhite = "#a9a6af" --Foreground
  122. colorWhiteAlt = "#9d9d9d" --White dark
  123. colorWhiteAlt2 = "#b5b3b3"
  124. colorWhiteAlt3 = "#707070"
  125. colorMagenta = "#8e82a2"
  126. colorBlue = "#44aacc"
  127. colorBlueAlt = "#3955c4"
  128. colorRed = "#f7a16e"
  129. colorRedAlt = "#e0105f"
  130. colorGreen = "#66ff66"
  131. colorGreenAlt = "#558965"
  132. boxLeftIcon = "/home/likan/.xmonad/nnoell/icons/boxleft.xbm" --left icon of dzen boxes
  133. boxLeftIcon2 = "/home/likan/.xmonad/nnoell/icons/boxleft2.xbm" --left icon2 of dzen boxes
  134. boxRightIcon = "/home/likan/.xmonad/nnoell/icons/boxright.xbm" --right icon of dzen boxes
  135. xDefRes = 1366 --no longer used
  136. yDefRes = 768 --no longer used
  137. panelHeight = 16 --height of top and bottom panels
  138. boxHeight = 14 --height of dzen logger box
  139. topPanelSepPos = 950 --left-right alignment pos of top panel
  140. botPanelSepPos = 450 --left-right alignment pos of bottom panel
  141.  
  142. -- Title theme
  143. myTitleTheme :: Theme
  144. myTitleTheme = defaultTheme
  145. { fontName = dzenFont
  146. , inactiveBorderColor = colorGrayAlt2
  147. , inactiveColor = colorGrayAlt3
  148. , inactiveTextColor = colorWhiteAlt3
  149. , activeBorderColor = colorGrayAlt2
  150. , activeColor = colorGrayAlt2
  151. , activeTextColor = colorWhiteAlt2
  152. , urgentBorderColor = colorGray
  153. , urgentTextColor = colorGreen
  154. , decoHeight = 14
  155. }
  156.  
  157. -- Prompt theme
  158. myXPConfig :: XPConfig
  159. myXPConfig = defaultXPConfig
  160. { font = dzenFont
  161. , bgColor = colorBlack
  162. , fgColor = colorWhite
  163. , bgHLight = colorBlue
  164. , fgHLight = colorBlack
  165. , borderColor = colorGrayAlt
  166. , promptBorderWidth = 1
  167. , height = panelHeight
  168. , position = Top
  169. , historySize = 100
  170. , historyFilter = deleteConsecutive
  171. , autoComplete = Nothing
  172. }
  173.  
  174. -- GridSelect color scheme
  175. myColorizer :: Window -> Bool -> X (String, String)
  176. myColorizer = colorRangeFromClassName
  177. (0x00,0x00,0x00) --lowest inactive bg
  178. (0x1C,0x1C,0x1C) --highest inactive bg
  179. (0x44,0xAA,0xCC) --active bg
  180. (0xBB,0xBB,0xBB) --inactive fg
  181. (0x00,0x00,0x00) --active fg
  182.  
  183. -- GridSelect theme
  184. myGSConfig :: t -> GSConfig Window
  185. myGSConfig colorizer = (buildDefaultGSConfig myColorizer)
  186. { gs_cellheight = 50
  187. , gs_cellwidth = 200
  188. , gs_cellpadding = 10
  189. , gs_font = dzenFont
  190. }
  191.  
  192. -- Flash text config
  193. myTextConfig :: ShowTextConfig
  194. myTextConfig = STC
  195. { st_font = dzenFont
  196. , st_bg = colorBlack
  197. , st_fg = colorWhite
  198. }
  199.  
  200. -- Dzen logger box pretty printing themes
  201. gray2BoxPP :: BoxPP
  202. gray2BoxPP = BoxPP
  203. { bgColorBPP = colorBlack
  204. , fgColorBPP = colorGray
  205. , boxColorBPP = colorGrayAlt
  206. , leftIconBPP = boxLeftIcon2
  207. , rightIconBPP = boxRightIcon
  208. , boxHeightBPP = boxHeight
  209. }
  210.  
  211. blueBoxPP :: BoxPP
  212. blueBoxPP = BoxPP
  213. { bgColorBPP = colorBlack
  214. , fgColorBPP = colorBlue
  215. , boxColorBPP = colorGrayAlt
  216. , leftIconBPP = boxLeftIcon
  217. , rightIconBPP = boxRightIcon
  218. , boxHeightBPP = boxHeight
  219. }
  220.  
  221. blue2BoxPP :: BoxPP
  222. blue2BoxPP = BoxPP
  223. { bgColorBPP = colorBlack
  224. , fgColorBPP = colorBlue
  225. , boxColorBPP = colorGrayAlt
  226. , leftIconBPP = boxLeftIcon2
  227. , rightIconBPP = boxRightIcon
  228. , boxHeightBPP = boxHeight
  229. }
  230.  
  231. whiteBoxPP :: BoxPP
  232. whiteBoxPP = BoxPP
  233. { bgColorBPP = colorBlack
  234. , fgColorBPP = colorWhiteAlt
  235. , boxColorBPP = colorGrayAlt
  236. , leftIconBPP = boxLeftIcon
  237. , rightIconBPP = boxRightIcon
  238. , boxHeightBPP = boxHeight
  239. }
  240.  
  241. blackBoxPP :: BoxPP
  242. blackBoxPP = BoxPP
  243. { bgColorBPP = colorBlack
  244. , fgColorBPP = colorBlack
  245. , boxColorBPP = colorGrayAlt
  246. , leftIconBPP = boxLeftIcon
  247. , rightIconBPP = boxRightIcon
  248. , boxHeightBPP = boxHeight
  249. }
  250.  
  251. white2BBoxPP :: BoxPP
  252. white2BBoxPP = BoxPP
  253. { bgColorBPP = colorBlack
  254. , fgColorBPP = colorBlack
  255. , boxColorBPP = colorWhiteAlt
  256. , leftIconBPP = boxLeftIcon2
  257. , rightIconBPP = boxRightIcon
  258. , boxHeightBPP = boxHeight
  259. }
  260.  
  261. blue2BBoxPP :: BoxPP --current workspace
  262. blue2BBoxPP = BoxPP
  263. { bgColorBPP = colorBlack
  264. , fgColorBPP = colorBlack
  265. , boxColorBPP = colorBlue
  266. , leftIconBPP = boxLeftIcon2
  267. , rightIconBPP = boxRightIcon
  268. , boxHeightBPP = boxHeight
  269. }
  270.  
  271. green2BBoxPP :: BoxPP --urgent workspace
  272. green2BBoxPP = BoxPP
  273. { bgColorBPP = colorBlack
  274. , fgColorBPP = colorBlack
  275. , boxColorBPP = colorGreen
  276. , leftIconBPP = boxLeftIcon2
  277. , rightIconBPP = boxRightIcon
  278. , boxHeightBPP = boxHeight
  279. }
  280.  
  281. -- Dzen logger clickable areas
  282. calendarCA :: CA
  283. calendarCA = CA
  284. { leftClickCA = "/home/likan/.xmonad/nnoell/bin/dzencal.sh"
  285. , middleClickCA = "/home/likan/.xmonad/nnoell/bin/dzencal.sh"
  286. , rightClickCA = "/home/likan/.xmonad/nnoell/bin/dzencal.sh"
  287. , wheelUpCA = "/home/likan/.xmonad/nnoell/bin/dzencal.sh"
  288. , wheelDownCA = "/home/likan/.xmonad/nnoell/bin/dzencal.sh"
  289. }
  290.  
  291. layoutCA :: CA
  292. layoutCA = CA
  293. { leftClickCA = "/usr/bin/xdotool key super+space"
  294. , middleClickCA = "/usr/bin/xdotool key super+v"
  295. , rightClickCA = "/usr/bin/xdotool key super+shift+space"
  296. , wheelUpCA = "/usr/bin/xdotool key super+f"
  297. , wheelDownCA = "/usr/bin/xdotool key super+control+f"
  298. }
  299.  
  300. workspaceCA :: CA
  301. workspaceCA = CA
  302. { leftClickCA = "/usr/bin/xdotool key super+1"
  303. , middleClickCA = "/usr/bin/xdotool key super+g"
  304. , rightClickCA = "/usr/bin/xdotool key super+0"
  305. , wheelUpCA = "/usr/bin/xdotool key ctrl+alt+Right"
  306. , wheelDownCA = "/usr/bin/xdotool key ctrl+alt+Left"
  307. }
  308.  
  309. focusCA :: CA
  310. focusCA = CA
  311. { leftClickCA = "/usr/bin/xdotool key super+m"
  312. , middleClickCA = "/usr/bin/xdotool key super+c"
  313. , rightClickCA = "/usr/bin/xdotool key super+shift+m"
  314. , wheelUpCA = "/usr/bin/xdotool key super+shift+j"
  315. , wheelDownCA = "/usr/bin/xdotool key super+shift+k"
  316. }
  317.  
  318. -- Workspace index (do not change)
  319. myWorkspaces :: [WorkspaceId]
  320. myWorkspaces = map show $ [1..9] ++ [0]
  321.  
  322. -- Workspace names
  323. workspaceNames :: [WorkspaceId]
  324. workspaceNames =
  325. [ "Terminal"
  326. , "Network"
  327. , "Development"
  328. , "Graphics"
  329. , "Chatting"
  330. , "Video"
  331. , "Alternate1"
  332. , "Alternate2"
  333. , "Alternate3"
  334. , "Alternate4"
  335. ]
  336.  
  337. -- Layout names (must be one word /= to: Mirror, ReflectX, ReflectY, Switcher, Normal and Unique)
  338. myTileName = "Tiled"
  339. myMirrName = "MirrTld"
  340. myMosAName = "Mosaic"
  341. myOneBName = "OneBig"
  342. myCst1Name = "Default"
  343. myCst2Name = "MstrTab"
  344. myCst3Name = "Web"
  345. myChatName = "Chat"
  346. myFTabName = "Full"
  347. myFloaName = "Float"
  348.  
  349.  
  350. --------------------------------------------------------------------------------------------
  351. -- STARTUP HOOK CONFIG --
  352. --------------------------------------------------------------------------------------------
  353.  
  354. -- Startup Hook
  355. myStartupHook =
  356. (setDefaultCursor xC_left_ptr) <+>
  357. (spawn "/usr/bin/killall haskell-cpu-usage.out") <+>
  358. (liftIO $ threadDelay 1000000) <+> --needed so that xmonad can be launched on the fly without crashing
  359. (spawn "/home/nnoell/.xmonad/apps/haskell-cpu-usage.out 5") <+>
  360. (startTimer 1 >>= XS.put . TID)
  361.  
  362.  
  363. --------------------------------------------------------------------------------------------
  364. -- HANDLE EVENT HOOK CONFIG --
  365. --------------------------------------------------------------------------------------------
  366.  
  367. -- Wrapper for the Timer id, so it can be stored as custom mutable state
  368. data TidState = TID TimerId deriving Typeable
  369.  
  370. instance ExtensionClass TidState where
  371. initialValue = TID 0
  372.  
  373. -- Handle event hook
  374. myHandleEventHook =
  375. fullscreenEventHook <+> docksEventHook <+>
  376. clockEventHook <+> handleTimerEvent <+>
  377. notFocusFloat where
  378. clockEventHook e = do --thanks to DarthFennec
  379. (TID t) <- XS.get --get the recent Timer id
  380. handleTimer t e $ do --run the following if e matches the id
  381. startTimer 1 >>= XS.put . TID --restart the timer, store the new id
  382. ask >>= logHook . config --get the loghook and run it
  383. return Nothing --return required type
  384. return $ All True --return required type
  385. notFocusFloat = followOnlyIf (fmap not isFloat) where --Do not focusFollowMouse on Float layout
  386. isFloat = fmap (isSuffixOf myFloaName) $ gets (description . W.layout . W.workspace . W.current . windowset)
  387.  
  388.  
  389. --------------------------------------------------------------------------------------------
  390. -- LAYOUT CONFIG --
  391. --------------------------------------------------------------------------------------------
  392.  
  393. -- Tabbed transformer (W+f)
  394. data TABBED = TABBED deriving (Read, Show, Eq, Typeable)
  395. instance Transformer TABBED Window where
  396. transform TABBED x k = k myFTabU (\_ -> x)
  397.  
  398. -- Floated transformer (W+ctl+f)
  399. data FLOATED = FLOATED deriving (Read, Show, Eq, Typeable)
  400. instance Transformer FLOATED Window where
  401. transform FLOATED x k = k myFloaU (\_ -> x)
  402.  
  403. -- Unique Layouts
  404. myFTabU = smartBorders $ named ("Unique " ++ myFTabName) $ tabbedAlways shrinkText myTitleTheme
  405. myFloaU = named ("Unique " ++ myFloaName) $ mouseResize $ noFrillsDeco shrinkText myTitleTheme simplestFloat
  406.  
  407. -- Layout hook
  408. myLayoutHook =
  409. gaps [(U,panelHeight), (D,panelHeight)] $
  410. configurableNavigation noNavigateBorders $
  411. minimize $
  412. maximize $
  413. mkToggle (single TABBED) $
  414. mkToggle (single FLOATED) $
  415. mkToggle (single MIRROR) $
  416. mkToggle (single REFLECTX) $
  417. mkToggle (single REFLECTY) $
  418. onWorkspace (myWorkspaces !! 1) webLayouts $
  419. onWorkspace (myWorkspaces !! 2) codeLayouts $
  420. onWorkspace (myWorkspaces !! 4) chatLayouts $
  421. allLayouts where
  422. --per workspace layouts
  423. webLayouts = (myToggleL myCst3 myCst3Name) ||| (myToggleL myCst1 myCst1Name) --workspace 2 layouts
  424. codeLayouts = (myToggleL myCst2 myCst2Name) ||| (myToggleL myOneB myOneBName) ||| (myToggleL myTile myTileName) --workspace 3 layouts
  425. chatLayouts = myToggleL (withIM (0.2) (Title "Buddy List") myMosA) myChatName --workspace 5 layouts
  426. allLayouts = -- rest of workspaces layouts
  427. (myToggleL myCst1 myCst1Name) |||
  428. (myToggleL myCst2 myCst2Name) |||
  429. (myToggleL myTile myTileName) |||
  430. (myToggleL myOneB myOneBName) |||
  431. (myToggleL myMirr myMirrName) |||
  432. (myToggleL myMosA myMosAName) |||
  433. (myToggleL myCst3 myCst3Name)
  434. --layouts
  435. myTile = ResizableTall 1 0.03 0.5 [] --default xmonad layout
  436. myMirr = Mirror myTile --mirror default xmonad layout
  437. myMosA = MosaicAlt M.empty --default mosaicAlt layout
  438. myOneB = OneBig 0.75 0.65 --default OneBig layout
  439. myCst1 = (layoutN 2 (relBox 0 0 1 0.6) (Just $ relBox 0 0 1 1) $ myTile) $ (layoutAll (relBox 0 0.6 1 1) $ myTabb) --custom1 layout
  440. myCst2 = (layoutN 1 (relBox 0 0 0.5 1) (Just $ relBox 0 0 1 1) $ myTile) $ (layoutAll (relBox 0.5 0 1 1) $ myTabb) --custom2 layout
  441. myCst3 = (layoutN 1 (relBox 0 0 1 0.7) (Just $ relBox 0 0 1 1) $ myTabb) $ (layoutAll (relBox 0 0.7 1 1) $ myTabb) --custom3 layout
  442. myChat = withIM (0.20) (Title "Buddy List") myMosA --custom chat layout
  443. myTabb = tabbed shrinkText myTitleTheme --default tabbed layout
  444. --costom draggingVisualizer toggle
  445. myToggleL l n = smartBorders $ toggleLayouts (named ("Switcher " ++ n) $ switcher l) (named ("Normal " ++ n) l) where
  446. switcher l = windowSwitcherDecoration shrinkText myTitleTheme $ draggingVisualizer l
  447.  
  448.  
  449. --------------------------------------------------------------------------------------------
  450. -- MANAGE HOOK CONFIG --
  451. --------------------------------------------------------------------------------------------
  452.  
  453. -- Manage Hook
  454. myManageHook :: ManageHook
  455. myManageHook =
  456. manageDocks <+>
  457. (scratchpadManageHook $ W.RationalRect 0 0 1 (3/4)) <+>
  458. dynamicMasterHook <+>
  459. manageWindows
  460.  
  461. -- Manage Windows
  462. manageWindows :: ManageHook
  463. manageWindows = composeAll . concat $
  464. [ [ resource =? r --> doIgnore | r <- myIgnores ]
  465. , [ className =? c --> doShift (myWorkspaces !! 1) | c <- myWebS ]
  466. , [ className =? c --> doShift (myWorkspaces !! 2) | c <- myCodeS ]
  467. , [ className =? c --> doShift (myWorkspaces !! 3) | c <- myGfxS ]
  468. , [ className =? c --> doShift (myWorkspaces !! 4) | c <- myChatS ]
  469. , [ className =? c --> doShift (myWorkspaces !! 9) | c <- myAlt3S ]
  470. , [ className =? c --> doCenterFloat | c <- myFloatCC ]
  471. , [ name =? n --> doCenterFloat | n <- myFloatCN ]
  472. , [ name =? n --> doSideFloat NW | n <- myFloatSN ]
  473. , [ className =? c --> doF W.focusDown | c <- myFocusDC ]
  474. , [ currentWs =? (myWorkspaces !! 1) --> keepMaster "Chromium" ]
  475. , [ isFullscreen --> doFullFloat ]
  476. ] where
  477. name = stringProperty "WM_NAME"
  478. myIgnores = ["desktop", "desktop_window"]
  479. myWebS = ["Chromium", "Firefox", "Opera"]
  480. myCodeS = ["NetBeans IDE 7.3"]
  481. myChatS = ["Pidgin", "Xchat"]
  482. myGfxS = ["Gimp", "gimp", "GIMP"]
  483. myAlt3S = ["Amule", "Transmission-gtk"]
  484. myFloatCC = ["MPlayer", "mplayer2", "File-roller", "zsnes", "Gcalctool", "Exo-helper-1"
  485. , "Gksu", "Galculator", "Nvidia-settings", "XFontSel", "XCalc", "XClock"
  486. , "Ossxmix", "Xvidcap", "Main", "Wicd-client.py"]
  487. myFloatCN = ["Choose a file", "Open Image", "File Operation Progress", "Firefox Preferences"
  488. , "Preferences", "Search Engines", "Set up sync", "Passwords and Exceptions"
  489. , "Autofill Options", "Rename File", "Copying files", "Moving files"
  490. , "File Properties", "Replace", "Quit GIMP", "Change Foreground Color"
  491. , "Change Background Color", ""]
  492. myFloatSN = ["Event Tester"]
  493. myFocusDC = ["Event Tester", "Notify-osd"]
  494. keepMaster c = assertSlave <+> assertMaster where
  495. assertSlave = fmap (/= c) className --> doF W.swapDown
  496. assertMaster = className =? c --> doF W.swapMaster
  497.  
  498. --------------------------------------------------------------------------------------------
  499. -- DZEN STATUS BARS CONFIG --
  500. --------------------------------------------------------------------------------------------
  501.  
  502. -- urgencyHook
  503. myUrgencyHook :: LayoutClass l Window => XConfig l -> XConfig l
  504. myUrgencyHook = withUrgencyHook dzenUrgencyHook
  505. { duration = 2000000
  506. , args =
  507. [ "-x", "0"
  508. , "-y", "0"
  509. , "-h", show panelHeight
  510. , "-w", show topPanelSepPos
  511. , "-fn", dzenFont
  512. , "-bg", colorBlack
  513. , "-fg", colorGreen
  514. ]
  515. }
  516.  
  517. -- Dzen top left bar flags
  518. dzenTopLeftFlags :: Res -> DF
  519. dzenTopLeftFlags _ = DF
  520. { xPosDF = 0
  521. , yPosDF = 0
  522. , widthDF = topPanelSepPos
  523. , heightDF = panelHeight
  524. , alignementDF = "l"
  525. , fgColorDF = colorWhiteAlt
  526. , bgColorDF = colorBlack
  527. , fontDF = dzenFont
  528. , eventDF = "onstart=lower"
  529. , extrasDF = "-p"
  530. }
  531.  
  532. -- Top left bar logHook
  533. myTopLeftLogHook :: Handle -> X ()
  534. myTopLeftLogHook h = dynamicLogWithPP defaultPP
  535. { ppOutput = hPutStrLn h
  536. , ppOrder = \(_:_:_:x) -> x
  537. , ppSep = " "
  538. , ppExtras = [ myLayoutL, myWorkspaceL, myFocusL ]
  539. }
  540.  
  541. -- Dzen top right bar flags
  542. dzenTopRightFlags :: Res -> DF
  543. dzenTopRightFlags r = DF
  544. { xPosDF = topPanelSepPos
  545. , yPosDF = 0
  546. , widthDF = (xRes r) - topPanelSepPos
  547. , heightDF = panelHeight
  548. , alignementDF = "r"
  549. , fgColorDF = colorWhiteAlt
  550. , bgColorDF = colorBlack
  551. , fontDF = dzenFont
  552. , eventDF = "onstart=lower"
  553. , extrasDF = "-p"
  554. }
  555.  
  556. -- Top right bar logHook
  557. myTopRightLogHook :: Handle -> X ()
  558. myTopRightLogHook h = dynamicLogWithPP defaultPP
  559. { ppOutput = hPutStrLn h
  560. , ppOrder = \(_:_:_:x) -> x
  561. , ppSep = " "
  562. , ppExtras = [myUptimeL, myDateL ]
  563. }
  564.  
  565. -- Dzen bottom left bar flags
  566. dzenBotLeftFlags :: Res -> DF
  567. dzenBotLeftFlags r = DF
  568. { xPosDF = 0
  569. , yPosDF = (yRes r) - panelHeight
  570. , widthDF = botPanelSepPos
  571. , heightDF = panelHeight
  572. , alignementDF = "l"
  573. , fgColorDF = colorWhiteAlt
  574. , bgColorDF = colorBlack
  575. , fontDF = dzenFont
  576. , eventDF = "onstart=lower"
  577. , extrasDF = "-p"
  578. }
  579.  
  580. -- Bottom left bar logHook
  581. myBotLeftLogHook :: Handle -> X ()
  582. myBotLeftLogHook h = dynamicLogWithPP . namedScratchpadFilterOutWorkspacePP $ defaultPP
  583. { ppOutput = hPutStrLn h
  584. , ppOrder = \(ws:_:_:x) -> [ws] ++ x
  585. , ppSep = " "
  586. , ppWsSep = ""
  587. , ppCurrent = dzenBoxStyle blue2BBoxPP
  588. , ppUrgent = dzenBoxStyle green2BBoxPP . dzenClickWorkspace
  589. , ppVisible = dzenBoxStyle blackBoxPP . dzenClickWorkspace
  590. , ppHiddenNoWindows = dzenBoxStyle blackBoxPP . dzenClickWorkspace
  591. , ppHidden = dzenBoxStyle whiteBoxPP . dzenClickWorkspace
  592. , ppExtras = [ myResL, myBrightL ]
  593. } where
  594. dzenClickWorkspace ws = "^ca(1," ++ xdo "w;" ++ xdo index ++ ")" ++ "^ca(3," ++ xdo "w;" ++ xdo index ++ ")" ++ ws ++ "^ca()^ca()" where
  595. wsIdxToString Nothing = "1"
  596. wsIdxToString (Just n) = show $ mod (n+1) $ length myWorkspaces
  597. index = wsIdxToString (elemIndex ws myWorkspaces)
  598. xdo key = "/usr/bin/xdotool key super+" ++ key
  599.  
  600. -- Dzen bottom right bar flags
  601. dzenBotRightFlags :: Res -> DF
  602. dzenBotRightFlags r = DF
  603. { xPosDF = botPanelSepPos
  604. , yPosDF = (yRes r) - panelHeight
  605. , widthDF = (xRes r) - botPanelSepPos
  606. , heightDF = panelHeight
  607. , alignementDF = "r"
  608. , fgColorDF = colorBlue
  609. , bgColorDF = colorBlack
  610. , fontDF = dzenFont
  611. , eventDF = "onstart=lower"
  612. , extrasDF = "-p"
  613. }
  614.  
  615. -- Bottom right bar logHook
  616. myBotRightLogHook :: Handle -> X ()
  617. myBotRightLogHook h = dynamicLogWithPP defaultPP
  618. { ppOutput = hPutStrLn h
  619. , ppOrder = \(_:_:_:x) -> x
  620. , ppSep = " "
  621. , ppExtras = [ myCpuL, myMemL, myTempL, myWifiL, myBatL ]
  622. }
  623.  
  624.  
  625. --------------------------------------------------------------------------------------------
  626. -- LOGGERS CONFIG --
  627. --------------------------------------------------------------------------------------------
  628.  
  629. -- BotRight Loggers
  630. myBatL =
  631. (dzenBoxStyleL gray2BoxPP $ labelL "BATTERY") ++!
  632. (dzenBoxStyleL blueBoxPP $ batPercent 30 colorRed) ++!
  633. (dzenBoxStyleL whiteBoxPP batStatus)
  634. myWifiL =
  635. (dzenBoxStyleL gray2BoxPP $ labelL "WIFI") ++!
  636. (dzenBoxStyleL blueBoxPP wifiSignal)
  637. myTempL =
  638. (dzenBoxStyleL gray2BoxPP $ labelL "TEMP") ++!
  639. (dzenBoxStyleL blueBoxPP $ cpuTemp 2 70 colorRed) --2 because I have 2 thermal zones
  640. myMemL =
  641. (dzenBoxStyleL gray2BoxPP $ labelL "MEM") ++!
  642. (dzenBoxStyleL blueBoxPP $ memUsage [percMemUsage, totMBMemUsage])
  643. myCpuL =
  644. (dzenBoxStyleL gray2BoxPP $ labelL "CPU") ++!
  645. (dzenBoxStyleL blueBoxPP $ cpuUsage "/tmp/haskell-cpu-usage.txt" 70 colorRed)
  646.  
  647. -- BotLeft Loggers
  648. myResL =
  649. (dzenBoxStyleL blue2BoxPP $ labelL "RES") ++!
  650. (dzenBoxStyleL whiteBoxPP $ screenRes ":0" 0)
  651. myBrightL =
  652. (dzenBoxStyleL blue2BoxPP $ labelL "BRIGHT") ++!
  653. (dzenBoxStyleL whiteBoxPP $ brightPerc 15) --15 because brightness go from 0 to 15 in my case, usually must be 10
  654.  
  655. -- TopRight Loggers
  656. myDateL =
  657. (dzenBoxStyleL white2BBoxPP $ date "%A") ++!
  658. (dzenBoxStyleL whiteBoxPP $ date $ "%Y^fg(" ++ colorGray ++ ").^fg()%m^fg(" ++ colorGray ++ ").^fg()^fg(" ++ colorBlue ++ ")%d^fg()") ++!
  659. (dzenBoxStyleL whiteBoxPP $ date $ "%H^fg(" ++ colorGray ++ "):^fg()%M^fg(" ++ colorGray ++ "):^fg()^fg(" ++ colorGreen ++ ")%S^fg()") ++!
  660. (dzenClickStyleL calendarCA $ dzenBoxStyleL blueBoxPP $ labelL "CALENDAR")
  661. myUptimeL =
  662. (dzenBoxStyleL blue2BoxPP $ labelL "UPTIME") ++!
  663. (dzenBoxStyleL whiteBoxPP uptime)
  664.  
  665. -- TopLeft Loggers
  666. myFocusL =
  667. (dzenClickStyleL focusCA $ dzenBoxStyleL white2BBoxPP $ labelL "FOCUS") ++!
  668. (dzenBoxStyleL whiteBoxPP $ shortenL 100 logTitle)
  669. myLayoutL =
  670. (dzenClickStyleL layoutCA $ dzenBoxStyleL blue2BoxPP $ labelL "LAYOUT") ++!
  671. (dzenBoxStyleL whiteBoxPP $ onLogger (layoutText . removeWord . removeWord) logLayout) where
  672. removeWord xs = tail $ dropWhile (/= ' ') xs
  673. layoutText xs
  674. | isPrefixOf "Mirror" xs = layoutText $ removeWord xs ++ " ^fg(" ++ colorBlue ++ ")M^fg(" ++ colorGray ++ ")|^fg(" ++ colorWhiteAlt ++ ")"
  675. | isPrefixOf "ReflectY" xs = layoutText $ removeWord xs ++ " ^fg(" ++ colorBlue ++ ")Y^fg(" ++ colorGray ++ ")|^fg(" ++ colorWhiteAlt ++ ")"
  676. | isPrefixOf "ReflectX" xs = layoutText $ removeWord xs ++ " ^fg(" ++ colorBlue ++ ")X^fg(" ++ colorGray ++ ")|^fg(" ++ colorWhiteAlt ++ ")"
  677. | isPrefixOf "Switcher" xs = layoutText $ removeWord xs ++ " ^fg(" ++ colorRed ++ ")S^fg(" ++ colorGray ++ ")|^fg(" ++ colorWhiteAlt ++ ")"
  678. | isPrefixOf "Normal" xs = layoutText $ removeWord xs ++ " ^fg(" ++ colorGreen ++ ")N^fg(" ++ colorGray ++ ")|^fg(" ++ colorWhiteAlt ++ ")"
  679. | isPrefixOf "Unique" xs = layoutText $ removeWord xs ++ " ^fg(" ++ colorGreen ++ ")U^fg(" ++ colorGray ++ ")|^fg(" ++ colorWhiteAlt ++ ")"
  680. | otherwise = concat $ reverse $ words xs
  681. myWorkspaceL =
  682. (dzenClickStyleL workspaceCA $ dzenBoxStyleL blue2BoxPP $ labelL "WORKSPACE") ++!
  683. (dzenBoxStyleL whiteBoxPP $ onLogger namedWorkspaces logCurrent) where
  684. namedWorkspaces w
  685. | (elem w $ map show [0..9]) = "^fg(" ++ colorGreen ++ ")" ++ w ++ "^fg(" ++ colorGray ++ ")|^fg()" ++ workspaceNames !! (mod ((read w::Int) - 1) 10)
  686. | otherwise = "^fg(" ++ colorRed ++ ")x^fg(" ++ colorGray ++ ")|^fg()" ++ w
  687.  
  688.  
  689. --------------------------------------------------------------------------------------------
  690. -- BINDINGS CONFIG --
  691. --------------------------------------------------------------------------------------------
  692.  
  693. -- Key bindings
  694. myKeys :: XConfig Layout -> M.Map (KeyMask, KeySym) (X ())
  695. myKeys conf@(XConfig {XMonad.modMask = modMask}) = M.fromList $
  696. --Xmonad bindings
  697. [((modMask .|. shiftMask, xK_q), killAndExit) --Quit xmonad
  698. , ((modMask, xK_q), killAndRestart) --Restart xmonad
  699. , ((0, xK_Pause), killAndRestart)
  700. , ((mod1Mask, xK_F2), shellPrompt myXPConfig) --Launch Xmonad shell prompt
  701. , ((modMask, xK_F2), xmonadPrompt myXPConfig) --Launch Xmonad prompt
  702. , ((mod1Mask, xK_F3), manPrompt myXPConfig) --Launch man prompt
  703. , ((modMask, xK_g), goToSelected $ myGSConfig myColorizer) --Launch GridSelect
  704. , ((modMask, xK_masculine), scratchPad) --Scratchpad (0x0060 = grave key)
  705. , ((modMask, 0x0060), scratchPad)
  706. , ((modMask .|. shiftMask, xK_Return), spawn $ XMonad.terminal conf) --Launch default terminal
  707. --Window management bindings
  708. , ((modMask, xK_c), kill) --Close focused window
  709. , ((mod1Mask, xK_F4), kill)
  710. , ((modMask, xK_n), refresh) --Resize viewed windows to the correct size
  711. , ((modMask, xK_Tab), windows W.focusDown) --Move focus to the next window
  712. , ((modMask, xK_j), windows W.focusDown)
  713. , ((mod1Mask, xK_Tab), windows W.focusDown)
  714. , ((modMask, xK_k), windows W.focusUp) --Move focus to the previous window
  715. , ((modMask, xK_a), windows W.focusMaster) --Move focus to the master window
  716. , ((modMask .|. shiftMask, xK_a), windows W.swapMaster) --Swap the focused window and the master window
  717. , ((modMask .|. shiftMask, xK_j), windows W.swapDown) --Swap the focused window with the next window
  718. , ((modMask .|. shiftMask, xK_k), windows W.swapUp) --Swap the focused window with the previous window
  719. , ((modMask, xK_h), sendMessage Shrink) --Shrink the master area
  720. , ((modMask .|. shiftMask, xK_Left), sendMessage Shrink)
  721. , ((modMask, xK_l), sendMessage Expand) --Expand the master area
  722. , ((modMask .|. shiftMask, xK_Right), sendMessage Expand)
  723. , ((modMask .|. shiftMask, xK_h), sendMessage MirrorShrink) --MirrorShrink the master area
  724. , ((modMask .|. shiftMask, xK_Down), sendMessage MirrorShrink)
  725. , ((modMask .|. shiftMask, xK_l), sendMessage MirrorExpand) --MirrorExpand the master area
  726. , ((modMask .|. shiftMask, xK_Up), sendMessage MirrorExpand)
  727. , ((modMask, xK_t), withFocused $ windows . W.sink) --Push window back into tiling
  728. , ((modMask .|. shiftMask, xK_t), rectFloatFocused) --Push window into float
  729. , ((modMask, xK_m), withFocused minimizeWindow) --Minimize window
  730. , ((modMask, xK_b), withFocused (sendMessage . maximizeRestore)) --Maximize window
  731. , ((modMask .|. shiftMask, xK_m), sendMessage RestoreNextMinimizedWin) --Restore window
  732. , ((modMask .|. shiftMask, xK_f), fullFloatFocused) --Push window into full screen
  733. , ((modMask, xK_comma), sendMessage (IncMasterN 1)) --Increment the number of windows in the master area
  734. , ((modMask, xK_period), sendMessage (IncMasterN (-1))) --Deincrement the number of windows in the master area
  735. , ((modMask, xK_Right), sendMessage $ Go R) --Change focus to right
  736. , ((modMask, xK_Left ), sendMessage $ Go L) --Change focus to left
  737. , ((modMask, xK_Up ), sendMessage $ Go U) --Change focus to up
  738. , ((modMask, xK_Down ), sendMessage $ Go D) --Change focus to down
  739. , ((modMask .|. controlMask, xK_Right), sendMessage $ Swap R) --Swap focused window to right
  740. , ((modMask .|. controlMask, xK_Left ), sendMessage $ Swap L) --Swap focused window to left
  741. , ((modMask .|. controlMask, xK_Up ), sendMessage $ Swap U) --Swap focused window to up
  742. , ((modMask .|. controlMask, xK_Down ), sendMessage $ Swap D) --Swap focused window to down
  743. , ((modMask .|. mod1Mask, xK_Left), withFocused (keysMoveWindow (-30,0))) -- move floated window 10 pixels left
  744. , ((modMask .|. mod1Mask, xK_Right), withFocused (keysMoveWindow (30,0))) -- move floated window 10 pixels right
  745. , ((modMask .|. mod1Mask, xK_Up), withFocused (keysMoveWindow (0,-30))) -- move floated window 10 pixels up
  746. , ((modMask .|. mod1Mask, xK_Down), withFocused (keysMoveWindow (0,30))) -- move floated window 10 pixels down
  747. --Layout management bindings
  748. , ((modMask, xK_space), sendMessage NextLayout) --Rotate through the available layout algorithms
  749. , ((modMask, xK_v ), sendMessage ToggleLayout) --Toggle window titles (can click drag to move windows)
  750. , ((modMask .|. shiftMask, xK_space ), flashText myTextConfig 1 " Set to Default Layout " >> (setLayout $ XMonad.layoutHook conf)) --Reset layout to workspaces default
  751. , ((modMask, xK_f), sendMessage $ XMonad.Layout.MultiToggle.Toggle TABBED) --Push layout into tabbed
  752. , ((modMask .|. controlMask, xK_f), sendMessage $ XMonad.Layout.MultiToggle.Toggle FLOATED) --Push layout into float
  753. , ((modMask .|. shiftMask, xK_z), sendMessage $ XMonad.Layout.MultiToggle.Toggle MIRROR) --Push layout into mirror
  754. , ((modMask .|. shiftMask, xK_x), sendMessage $ XMonad.Layout.MultiToggle.Toggle REFLECTX) --Reflect layout by X
  755. , ((modMask .|. shiftMask, xK_y), sendMessage $ XMonad.Layout.MultiToggle.Toggle REFLECTY) --Reflect layout by Y
  756. --Gaps management bindings
  757. , ((modMask .|. controlMask, xK_t), sendMessage $ ToggleGaps ) --toogle the all gaps
  758. , ((0, xF86XK_Calculator), sendMessage $ ToggleGaps)
  759. , ((modMask .|. controlMask, xK_u), sendMessage $ ToggleGap U) --toogle the top gaps
  760. , ((modMask .|. controlMask, xK_d), sendMessage $ ToggleGap D) --toogle the bottom gaps
  761. --Scripts management bindings
  762. , ((modMask, xK_d), spawn "/usr/bin/killall dzen2 haskell-cpu-usage.out") --Kill dzen2
  763. , ((0, 0x1008ffa9), spawn "/home/nnoell/bin/touchpadtoggle.sh") --Toggle touchpad (xmodmap -pk | grep -i toggle)
  764. , ((0, xF86XK_AudioMute), spawn "/home/likan/.xmonad/nnoell/bin/voldzen.sh t -d") --Mute/unmute volume
  765. , ((0, xF86XK_AudioRaiseVolume), spawn "/home/likan/.xmonad/nnoell/bin/voldzen.sh + -d") --Raise volume
  766. , ((mod1Mask, xK_Up), spawn "/home/likan/.xmonad/nnoell/bin/voldzen.sh + -d")
  767. , ((0, xF86XK_AudioLowerVolume), spawn "/home/likan/.xmonad/nnoell/bin/voldzen.sh - -d") --Lower volume
  768. , ((mod1Mask, xK_Down), spawn "/home/likan/.xmonad/nnoell/bin/voldzen.sh - -d")
  769. , ((0, xF86XK_AudioNext), flashText myTextConfig 1 " Next Song " >> spawn "/usr/bin/ncmpcpp next") --Next song
  770. , ((mod1Mask, xK_Right), flashText myTextConfig 1 " Next Song " >> spawn "/usr/bin/ncmpcpp next")
  771. , ((0, xF86XK_AudioPrev), flashText myTextConfig 1 " Previous Song " >> spawn "/usr/bin/ncmpcpp prev") --Prev song
  772. , ((mod1Mask, xK_Left), flashText myTextConfig 1 " Previous Song " >> spawn "/usr/bin/ncmpcpp prev")
  773. , ((0, xF86XK_AudioPlay), flashText myTextConfig 1 " Song Toggled " >> spawn "/usr/bin/ncmpcpp toggle") --Toggle song
  774. , ((mod1Mask .|. controlMask, xK_Down), flashText myTextConfig 1 " Song Toggled " >> spawn "/usr/bin/ncmpcpp toggle")
  775. , ((0, xF86XK_AudioStop), flashText myTextConfig 1 " Song Stopped " >> spawn "/usr/bin/ncmpcpp stop") --Stop song
  776. , ((mod1Mask .|. controlMask, xK_Up), flashText myTextConfig 1 " Song Stopped " >> spawn "ncmpcpp stop")
  777. , ((0, xF86XK_MonBrightnessUp), spawn "/home/nnoell/bin/bridzen.sh") --Raise brightness
  778. , ((0, xF86XK_MonBrightnessDown), spawn "/home/nnoell/bin/bridzen.sh") --Lower brightness
  779. , ((0, xF86XK_ScreenSaver), spawn "/home/nnoell/bin/turnoffscreen.sh") --Lock screen
  780. , ((0, 0xff14), spawn "/home/nnoell/bin/turnoffscreen.sh")
  781. , ((0, xK_Print), spawn "/usr/bin/scrot '%Y-%m-%d_$wx$h.png'" >> flashText myTextConfig 1 " Screenshot Saved ") --Take a screenshot
  782. , ((modMask , xK_s), spawn "/home/nnoell/bin/turnoffscreen.sh") --Turn off screen
  783. --Workspaces management bindings
  784. , ((mod1Mask, xK_comma), flashText myTextConfig 1 " Toggled to Previous Workspace " >> toggleWS) --Toggle to the workspace displayed previously
  785. , ((mod1Mask, xK_masculine), flashText myTextConfig 1 " Switching with Workspace 1 " >> toggleOrView (myWorkspaces !! 0)) --If ws != 0 then move to workspace 0, else move to latest ws I was
  786. , ((mod1Mask .|. controlMask, xK_Left), flashText myTextConfig 1 " Moved to Previous Workspace " >> prevWS) --Move to previous Workspace
  787. , ((mod1Mask .|. controlMask, xK_Right), flashText myTextConfig 1 " Moved to Next Workspace " >> nextWS) --Move to next Workspace
  788. , ((modMask .|. shiftMask, xK_n), flashText myTextConfig 1 " Shifted to Next Workspace " >> shiftToNext) --Send client to next workspace
  789. , ((modMask .|. shiftMask, xK_p), flashText myTextConfig 1 " Shifted to Previous Workspace " >> shiftToPrev) --Send client to previous workspace
  790. , ((modMask, xK_p ), spawn "dmenu_run") --Running dmenu
  791. ] ++
  792. [ ((m .|. modMask, k), windows $ f i) --Switch to n workspaces and send client to n workspaces
  793. | (i, k) <- zip (XMonad.workspaces conf) ([xK_1 .. xK_9] ++ [xK_0])
  794. , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]
  795. ] ++
  796. [ ((m .|. modMask, key), screenWorkspace sc >>= flip whenJust (windows . f)) --Switch to n screens and send client to n screens
  797. | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]
  798. , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]
  799. ] where
  800. scratchPad = scratchpadSpawnActionCustom "/usr/bin/urxvtc -name scratchpad"
  801. fullFloatFocused = withFocused $ \f -> windows =<< appEndo `fmap` runQuery doFullFloat f
  802. rectFloatFocused = withFocused $ \f -> windows =<< appEndo `fmap` runQuery (doRectFloat $ W.RationalRect 0.05 0.05 0.9 0.9) f
  803. killAndExit =
  804. (spawn "/usr/bin/killall dzen2 haskell-cpu-usage.out") <+>
  805. io (exitWith ExitSuccess)
  806. killAndRestart =
  807. (spawn "/usr/bin/killall dzen2 haskell-cpu-usage.out") <+>
  808. (liftIO $ threadDelay 1000000) <+>
  809. (restart "xmonad" True)
  810.  
  811. -- Mouse bindings
  812. myMouseBindings :: XConfig Layout -> M.Map (KeyMask, Button) (Window -> X ())
  813. myMouseBindings (XConfig {XMonad.modMask = modMask}) = M.fromList $
  814. [ ((modMask, button1), (\w -> focus w >> mouseMoveWindow w >> windows W.shiftMaster)) --Set the window to floating mode and move by dragging
  815. , ((modMask, button2), (\w -> focus w >> windows W.shiftMaster)) --Raise the window to the top of the stack
  816. , ((modMask, button3), (\w -> focus w >> Flex.mouseResizeWindow w)) --Set the window to floating mode and resize by dragging
  817. , ((modMask, button4), (\_ -> prevWS)) --Switch to previous workspace
  818. , ((modMask, button5), (\_ -> nextWS)) --Switch to next workspace
  819. , (((modMask .|. shiftMask), button4), (\_ -> shiftToPrev)) --Send client to previous workspace
  820. , (((modMask .|. shiftMask), button5), (\_ -> shiftToNext)) --Send client to next workspace
  821. ]
  822.  
  823.  
  824. --------------------------------------------------------------------------------------------
  825. -- DZEN UTILS --
  826. --------------------------------------------------------------------------------------------
  827.  
  828. -- Dzen flags
  829. data DF = DF
  830. { xPosDF :: Int
  831. , yPosDF :: Int
  832. , widthDF :: Int
  833. , heightDF :: Int
  834. , alignementDF :: String
  835. , fgColorDF :: String
  836. , bgColorDF :: String
  837. , fontDF :: String
  838. , eventDF :: String
  839. , extrasDF :: String
  840. }
  841.  
  842. -- Dzen box pretty config
  843. data BoxPP = BoxPP
  844. { bgColorBPP :: String
  845. , fgColorBPP :: String
  846. , boxColorBPP :: String
  847. , leftIconBPP :: String
  848. , rightIconBPP :: String
  849. , boxHeightBPP :: Int
  850. }
  851.  
  852. -- Dzen clickable area config
  853. data CA = CA
  854. { leftClickCA :: String
  855. , middleClickCA :: String
  856. , rightClickCA :: String
  857. , wheelUpCA :: String
  858. , wheelDownCA :: String
  859. }
  860.  
  861. -- Create a dzen string with its flags
  862. dzenFlagsToStr :: DF -> String
  863. dzenFlagsToStr df =
  864. " -x '" ++ (show $ xPosDF df) ++
  865. "' -y '" ++ (show $ yPosDF df) ++
  866. "' -w '" ++ (show $ widthDF df) ++
  867. "' -h '" ++ (show $ heightDF df) ++
  868. "' -ta '" ++ alignementDF df ++
  869. "' -fg '" ++ fgColorDF df ++
  870. "' -bg '" ++ bgColorDF df ++
  871. "' -fn '" ++ fontDF df ++
  872. "' -e '" ++ eventDF df ++
  873. "' " ++ extrasDF df
  874.  
  875. -- Uses dzen format to draw a "box" arround a given text
  876. dzenBoxStyle :: BoxPP -> String -> String
  877. dzenBoxStyle bpp t =
  878. "^fg(" ++ (boxColorBPP bpp) ++
  879. ")^i(" ++ (leftIconBPP bpp) ++
  880. ")^ib(1)^r(1920x" ++ (show $ boxHeightBPP bpp) ++
  881. ")^p(-1920)^fg(" ++ (fgColorBPP bpp) ++
  882. ")" ++ t ++
  883. "^fg(" ++ (boxColorBPP bpp) ++
  884. ")^i(" ++ (rightIconBPP bpp) ++
  885. ")^fg(" ++ (bgColorBPP bpp) ++
  886. ")^r(1920x" ++ (show $ boxHeightBPP bpp) ++
  887. ")^p(-1920)^fg()^ib(0)"
  888.  
  889. -- Uses dzen format to make dzen text clickable
  890. dzenClickStyle :: CA -> String -> String
  891. dzenClickStyle ca t = "^ca(1," ++ leftClickCA ca ++
  892. ")^ca(2," ++ middleClickCA ca ++
  893. ")^ca(3," ++ rightClickCA ca ++
  894. ")^ca(4," ++ wheelUpCA ca ++
  895. ")^ca(5," ++ wheelDownCA ca ++
  896. ")" ++ t ++
  897. "^ca()^ca()^ca()^ca()^ca()"
  898.  
  899. -- Launch dzen through the system shell and return a Handle to its standard input
  900. dzenSpawnPipe df = spawnPipe $ "dzen2" ++ dzenFlagsToStr df
  901.  
  902. -- Logger version of dzenBoxStyle
  903. dzenBoxStyleL :: BoxPP -> Logger -> Logger
  904. dzenBoxStyleL bpp l = (fmap . fmap) (dzenBoxStyle bpp) l
  905.  
  906. -- Logger version of dzenClickStyle
  907. dzenClickStyleL :: CA -> Logger -> Logger
  908. dzenClickStyleL ca l = (fmap . fmap) (dzenClickStyle ca) l
  909.  
  910.  
  911. --------------------------------------------------------------------------------------------
  912. -- HARDCODED LOGGERS (you may need to amend them so that they work on your computer) --
  913. --------------------------------------------------------------------------------------------
  914.  
  915. -- Concat two Loggers
  916. (++!) :: Logger -> Logger -> Logger
  917. l1 ++! l2 = (liftA2 . liftA2) (++) l1 l2
  918.  
  919. -- Label
  920. labelL :: String -> Logger
  921. labelL = return . return
  922.  
  923. -- Init version for Logger
  924. initL :: Logger -> Logger
  925. initL = (fmap . fmap) initNotNull
  926.  
  927. -- Concat a list of loggers
  928. concatL :: [Logger] -> Logger
  929. concatL [] = return $ return ""
  930. concatL (x:xs) = x ++! concatL xs
  931.  
  932. -- Concat a list of loggers with spaces between them
  933. concatWithSpaceL :: [Logger] -> Logger
  934. concatWithSpaceL [] = return $ return ""
  935. concatWithSpaceL (x:xs) = x ++! (labelL " ") ++! concatWithSpaceL xs
  936.  
  937. initNotNull :: String -> String
  938. initNotNull [] = "0\n"
  939. initNotNull xs = init xs
  940.  
  941. tailNotNull :: [String] -> [String]
  942. tailNotNull [] = ["0\n"]
  943. tailNotNull xs = tail xs
  944.  
  945. -- Convert the content of a file into a Logger
  946. fileToLogger :: (String -> String) -> String -> FilePath -> Logger
  947. fileToLogger f e p = do
  948. let readWithE f1 e1 p1 = E.catch (do
  949. contents <- readFile p1
  950. return $ f1 (initNotNull contents) ) ((\_ -> return e1) :: E.SomeException -> IO String)
  951. str <- liftIO $ readWithE f e p
  952. return $ return str
  953.  
  954. -- Battery percent
  955. batPercent :: Int -> String -> Logger
  956. batPercent v c = fileToLogger format "N/A" "/sys/class/power_supply/BAT1/capacity" where
  957. format x = if ((read x::Int) <= v) then "^fg(" ++ c ++ ")" ++ x ++ "%^fg()" else (x ++ "%")
  958.  
  959. -- Battery status
  960. batStatus :: Logger
  961. batStatus = fileToLogger format "AC Conection" "/sys/class/power_supply/BAT1/status" where
  962. format x = if (x == "Unknown") then "Connected" else x
  963.  
  964. -- Brightness percenn
  965. brightPerc :: Int -> Logger
  966. brightPerc p = fileToLogger format "0" "/sys/class/backlight/acpi_video0/actual_brightness" where
  967. format x = (show $ (read x::Int) ) ++ "%"
  968.  
  969. -- wifi signal
  970. wifiSignal :: Logger
  971. wifiSignal = fileToLogger format "N/A" "/proc/net/wireless" where
  972. format x = if (length $ lines x) >= 3 then (initNotNull ((words ((lines x) !! 2)) !! 2) ++ "%") else "Off"
  973.  
  974. -- CPU temperature
  975. cpuTemp :: Int -> Int -> String -> Logger
  976. cpuTemp n v c = initL $ concatWithSpaceL $ map (fileToLogger divc "0") pathtemps where
  977. pathtemps = map (++"/thermal_zone/temp") $ map ("/sys/bus/acpi/devices/LNXTHERM:0"++) $ take n $ map show [0..]
  978. divc x = crit $ div (read x::Int) 1000
  979. crit x = if (x >= v) then "^fg(" ++ c ++ ")" ++ show x ++ "°^fg()" else (show x ++ "°")
  980.  
  981. -- Memory usage
  982. memUsage :: [(String -> String)] -> Logger
  983. memUsage xs = initL $ concatWithSpaceL $ map funct xs where
  984. funct x = fileToLogger x "N/A" "/proc/meminfo"
  985.  
  986. _memUsed x = (_memValues x !! 0) - (_memValues x !! 1)
  987. _memPerc x = div (_memUsed x * 100) (_memValues x !! 0)
  988. _memValues x = map (getValues x) $ take 4 [0..] where
  989. getValues x n = read (words (lines x !! n) !! 1)::Int
  990.  
  991. freeBMemUsage x = (show $ _memValues x !! 1) ++ "B"
  992. freeMBMemUsage x = (show $ div (_memValues x !! 1) 1024) ++ "MB"
  993. totBMemUsage = (++"B") . show . _memUsed
  994. totMBMemUsage = (++"MB") . show . (`div` 1024) . _memUsed
  995. percMemUsage = (++"%") . show . _memPerc
  996.  
  997. -- CPU Usage: this is an ugly hack that depends on "haskell-cpu-usage" app (See my github repo to get the app)
  998. cpuUsage :: String -> Int -> String -> Logger
  999. cpuUsage path v c = fileToLogger format "0" path where
  1000. format x = if (null x) then "N/A" else initNotNull $ concat $ map (++" ") $ map crit $ tailNotNull $ words $ x
  1001. crit x = if ((read x::Int) >= v) then "^fg(" ++ c ++ ")" ++ x ++ "%^fg()" else (x ++ "%")
  1002.  
  1003. -- Uptime
  1004. uptime :: Logger
  1005. uptime = fileToLogger format "0" "/proc/uptime" where
  1006. u x = read (takeWhile (/='.') x)::Integer
  1007. h x = div (u x) 3600
  1008. hr x = mod (u x) 3600
  1009. m x = div (hr x) 60
  1010. s x = mod (hr x) 60
  1011. format x = (show $ h x) ++ "h " ++ (show $ m x) ++ "m " ++ (show $ s x) ++ "s"
  1012.  
  1013. -- Gets the current resolution given a display and a screen
  1014. getScreenRes :: String -> Int -> IO Res
  1015. getScreenRes d n = do
  1016. dpy <- openDisplay d
  1017. r <- liftIO $ getScreenInfo dpy
  1018. closeDisplay dpy
  1019. return $ Res
  1020. { xRes = fromIntegral $ rect_width $ r !! n
  1021. , yRes = fromIntegral $ rect_height $ r !! n
  1022. }
  1023.  
  1024. -- Screen Resolution
  1025. data Res = Res
  1026. { xRes :: Int
  1027. , yRes :: Int
  1028. }
  1029.  
  1030. -- Resolution logger
  1031. screenRes :: String -> Int -> Logger
  1032. screenRes d n = do
  1033. res <- liftIO $ getScreenRes d n
  1034. return $ return $ (show $ xRes res) ++ "x" ++ (show $ yRes res)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement