Advertisement
Guest User

xmonad.hs

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