Guest User

xmonad.hs

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