Advertisement
Guest User

xmonad.hs

a guest
Jul 16th, 2010
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Haskell 16.98 KB | None | 0 0
  1. --
  2. -- ~/.xmonad/xmonad.hs
  3. -- original by pbrisbin
  4. --
  5. -- 18 june 2010 (a few new actions)
  6.  
  7. -- Imports {{{
  8. import XMonad hiding ( (|||) )
  9.  
  10. import XMonad.Actions.CycleWS (toggleWS)
  11. import XMonad.Actions.FindEmptyWorkspace
  12. import XMonad.Actions.WithAll (killAll)
  13. import XMonad.Actions.UpdatePointer
  14. import XMonad.Actions.GridSelect
  15.  
  16. import XMonad.Hooks.DynamicLog
  17. import XMonad.Hooks.EwmhDesktops (ewmh)
  18. import XMonad.Hooks.ManageHelpers
  19. import XMonad.Hooks.ManageDocks
  20. import XMonad.Hooks.UrgencyHook
  21. import XMonad.Hooks.SetWMName
  22.  
  23. import XMonad.Layout.IM
  24. import XMonad.Layout.LayoutCombinators (JumpToLayout)
  25. import XMonad.Layout.LayoutHints (layoutHintsWithPlacement)
  26. import XMonad.Layout.LayoutCombinators
  27. import XMonad.Layout.NoBorders
  28. import XMonad.Layout.PerWorkspace (onWorkspace)
  29. import XMonad.Layout.ResizableTile
  30. import XMonad.Layout.Maximize
  31. import XMonad.Layout.Minimize
  32.  
  33. import XMonad.Util.EZConfig (additionalKeysP)
  34. import XMonad.Util.Loggers (maildirNew,logCmd,dzenColorL,wrapL,shortenL)
  35. import XMonad.Util.NamedScratchpad
  36. import XMonad.Util.Run (spawnPipe)
  37. import XMonad.Util.WindowProperties (getProp32s)
  38. import XMonad.Util.WorkspaceCompare (getSortByXineramaRule)
  39.  
  40. import Data.List
  41. import Data.Monoid
  42. import Data.Ratio
  43.  
  44. import System.IO
  45.  
  46. import qualified Data.Map        as M
  47. import qualified XMonad.StackSet as W
  48.  
  49. -- }}}
  50.  
  51. -- Main {{{
  52. main = do
  53.   d <- spawnPipe myLeftBar
  54.   spawnList myStartupApps
  55.  
  56.   -- ewmh just makes wmctrl work
  57.   xmonad $ ewmh $ withUrgencyHook myUrgencyHook $ defaultConfig
  58.     { startupHook        = setWMName "LG3D"
  59.     , modMask            = mod4Mask
  60.     , terminal           = myTerminal
  61.     , workspaces         = myWorkspaces
  62.     , borderWidth        = myBorderWidth
  63.     , normalBorderColor  = myNormalBorderColor
  64.     , focusedBorderColor = myFocusedBorderColor
  65.     , layoutHook         = myLayout
  66.     , manageHook         = myManageHook
  67.     , logHook            = myLogHook d
  68.     } `additionalKeysP` myKeys
  69.  
  70.     where
  71.  
  72.       spawnList :: [String] -> IO ()
  73.       spawnList = mapM_ spawn
  74.  
  75.       -- apps to start along with xmonad
  76.       myStartupApps = [myRightBar,"conky","qutim",myWicd]
  77.  
  78. -- }}}
  79.  
  80. -- Theme {{{
  81. myFont       = "Verdana-8"       -- xft-enabled dzen required (aur/dzen2-svn)
  82. conkyFile    = "~/.dzen_conkyrc" -- populates right status bar via conky -c | dzen2
  83.  
  84. colorBG      = "#303030"         -- background
  85. colorFG      = "#606060"         -- foreground
  86. colorFG2     = "#909090"         -- foreground w/ emphasis
  87. colorFG3     = "#c4df90"         -- foreground w/ strong emphasis
  88. colorUrg     = "#cc896d"         -- urgent, peach
  89. colorUrg2    = "#c4df90"         -- urgent, lime
  90.  
  91. barHeight    = 17
  92. monitorWidth = 1920         -- two statusbars will span this width
  93. leftBarWidth = 800              -- right bar will span difference
  94.  
  95. -- }}}
  96.  
  97. -- Options {{{
  98. --
  99. -- if you change workspace names, be sure to update them throughout
  100. --
  101. myTerminal           = "urxvtc"
  102. myWorkspaces         = ["1-main","2-web","3-chat"] ++ map show [4..9]
  103. myNormalBorderColor  = colorFG
  104. myFocusedBorderColor = colorUrg
  105. myBorderWidth        = 1
  106.  
  107.  
  108. -- }}}
  109.  
  110. -- Layouts {{{
  111. --
  112. -- see http://pbrisbin.com:8080/pages/im-layout.html
  113. --
  114. myLayout = avoidStruts $ onWorkspace "3-chat" imLayout $ maximize $ minimize $ standardLayouts
  115.  
  116.   where
  117.  
  118.     standardLayouts = tiled ||| Mirror tiled ||| full
  119.  
  120.     -- im roster on left tenth, standardLayouts in other nine tenths
  121.     imLayout        = withIM (1/10) imProp standardLayouts
  122.  
  123.     -- WMROLE = "roster" is Gajim.py's buddy list
  124.     imProp          = Role "roster"
  125.  
  126.     tiled           = hinted $ ResizableTall nmaster delta ratio []
  127.     full            = hinted $ noBorders Full
  128.  
  129.     -- like hintedTile but for any layout l
  130.     hinted l        = layoutHintsWithPlacement (0,0) l
  131.  
  132.     nmaster         = 1
  133.     delta           = 3/100
  134.     ratio           = toRational $ 2/(1 + sqrt 5 :: Double) -- golden ratio
  135.  
  136.  
  137. -- }}}
  138.  
  139. -- ManageHook {{{
  140. myManageHook = (composeAll . concat $
  141.   [ [resource  =? r                 --> doIgnore         |  r    <- myIgnores] -- ignore desktop
  142.   , [className =? c                 --> doShift "2-web"  |  c    <- myWebs   ] -- move webs to web
  143.   , [title     =? t                 --> doShift "3-chat" |  t    <- myChats  ] -- move chats to chat
  144.   , [className =? c                 --> doShift "3-chat" | (c,_) <- myIMs    ] -- move chats to chat
  145.   , [className =? c <&&> role /=? r --> doFloat          | (c,r) <- myIMs    ] -- float all ims but roster
  146.   , [className =? c                 --> doFloat          |  c    <- myFloats ] -- float my floats
  147.   , [className =? c                 --> doCenterFloat    |  c    <- myCFloats] -- float my floats
  148.   , [name      =? n                 --> doFloat          |  n    <- myNames  ] -- float my names
  149.   , [name      =? n                 --> doCenterFloat    |  n    <- myCNames ] -- float my names
  150.   , [isFullscreen                   --> myDoFullFloat                        ]
  151.   ]) <+> manageTypes <+> manageDocks <+> manageScratchPads
  152.  
  153.   where
  154.  
  155.     role      = stringProperty "WM_WINDOW_ROLE"
  156.     name      = stringProperty "WM_NAME"
  157.  
  158.     -- [ ("class1","role1"), ("class2","role2"), ... ]
  159.     myIMs     = [("Qutim","roster")]
  160.  
  161.     -- titles
  162.     myChats   = ["irssi","mutt"]
  163.  
  164.     -- classnames
  165.     myFloats  = ["MPlayer","Smplayer","Zenity","Comix","VirtualBox","rdesktop"]
  166.     myCFloats = ["Xmessage","Save As...","XFontSel"]
  167.  
  168.     myWebs    = ["Firefox"]     ++ -- firefox
  169.                 ["Chromium"]               -- chrom(e|ium)
  170.  
  171.     -- resources
  172.     myIgnores = ["desktop","desktop_window"]
  173.  
  174.     -- names
  175.     myNames   = ["Chromium Options"]
  176.     myCNames  = ["bashrun"]
  177.  
  178.     -- a trick for fullscreen but stil allow focusing of other WSs
  179.     myDoFullFloat = doF W.focusDown <+> doFullFloat
  180.  
  181.     -- modified version of manageDocks
  182.     manageTypes = checkType --> doCenterFloat
  183.  
  184.       where
  185.  
  186.         checkType :: Query Bool
  187.         checkType = ask >>= \w -> liftX $ do
  188.           m   <- getAtom    "_NET_WM_WINDOW_TYPE_MENU"
  189.           d   <- getAtom    "_NET_WM_WINDOW_TYPE_DIALOG"
  190.           u   <- getAtom    "_NET_WM_WINDOW_TYPE_UTILITY"
  191.           mbr <- getProp32s "_NET_WM_WINDOW_TYPE" w
  192.  
  193.           case mbr of
  194.             Just [r] -> return $ elem (fromIntegral r) [m,d,u]
  195.             _        -> return False
  196.  
  197.     -- manage all my scratchpads based on the rules listed in the datatypes
  198.     manageScratchPads = namedScratchpadManageHook myScratchPads
  199.  
  200. -- }}}
  201.  
  202. -- ScratchPads {{{
  203.  
  204. myScratchPads = [ NS "mixer"    spawnMixer findMixer manageMixer
  205.                 , NS "terminal" spawnTerm  findTerm  manageTerm
  206.                 ]
  207.  
  208.   where
  209.  
  210.     spawnMixer  = myTerminal ++ " -e alsamixer"
  211.     findMixer   = className =? "alsamixer"
  212.     manageMixer = customFloating $ W.RationalRect l t w h
  213.  
  214.       where
  215.  
  216.         h = 0.6       -- height, 60%
  217.         w = 0.6       -- width, 60%
  218.         t = (1 - h)/2 -- centered top/bottom
  219.         l = (1 - w)/2 -- centered left/right
  220.  
  221.     spawnTerm  = myTerminal ++ " -name scratchpad"
  222.     findTerm   = resource  =? "scratchpad"
  223.     manageTerm = customFloating $ W.RationalRect l t w h
  224.  
  225.       where
  226.  
  227.         h = 0.1       -- height, 10%
  228.         w = 1         -- width, 100%
  229.         t = 1 - h     -- bottom edge
  230.         l = (1 - w)/2 -- centered left/right
  231.  
  232.  
  233. -- }}}
  234.  
  235. -- Status Bars {{{
  236. --
  237. -- see http://pbrisbin.com:8080/pages/xmonad_status.html
  238. --
  239. makeDzen :: Int -> Int -> Int -> Int -> String -> String
  240. makeDzen x y w h a = "dzen2 -p" ++
  241.                      " -ta "    ++ a       ++
  242.                      " -x "     ++ show x  ++
  243.                      " -y "     ++ show y  ++
  244.                      " -w "     ++ show w  ++
  245.                      " -h "     ++ show h  ++
  246.                      " -fn '"   ++ myFont  ++ "'" ++
  247.                      " -fg '"   ++ colorFG ++ "'" ++
  248.                      " -bg '"   ++ colorBG ++ "' -e 'onstart=lower'"
  249.  
  250. -- define the bars
  251. myLeftBar  = makeDzen 0 0 leftBarWidth barHeight "l"
  252. myRightBar = "conky -c " ++ conkyFile ++ " | " ++ makeDzen leftBarWidth 0 (monitorWidth - leftBarWidth) barHeight "r"
  253.  
  254. -- kill instances of wicd-client and start a new one
  255. myWicd        = "for pid in `pgrep wicd-client`; do kill -9 $pid; done && " ++
  256.                 "wicd-client"
  257.  
  258. -- }}}
  259.  
  260. -- LogHook {{{
  261. myLogHook :: Handle -> X ()
  262. myLogHook h = (dynamicLogWithPP $ defaultPP
  263.   { ppCurrent         = dzenFG colorUrg2 . pad
  264.   , ppVisible         = dzenFG colorFG2  . pad
  265.   , ppUrgent          = dzenFG colorUrg  . pad . dzenStrip
  266.   , ppLayout          = dzenFG colorFG2  . myRename
  267.   , ppHidden          = dzenFG colorFG2  . noScratchPad
  268.   , ppHiddenNoWindows = namedOnly
  269.   , ppTitle           = shorten 100
  270.   , ppSort            = getSortByXineramaRule
  271.  
  272.   -- uzbl generates too many events, these are slow
  273.   --, ppExtras          = [myMail, myUpdates, myTorrents]
  274.   , ppExtras          = [myMail]
  275.  
  276.   , ppSep             = "    "
  277.   , ppWsSep           = ""
  278.   , ppOutput          = hPutStrLn h
  279.   }) >> updatePointer (Relative 0.95 0.95) >> setWMName "LG3D"
  280.  
  281.  
  282.   where
  283.  
  284.     -- thanks byorgey (this filters out NSP too)
  285.     namedOnly ws = if any (`elem` ws) ['a'..'z'] then pad ws else ""
  286.  
  287.     -- my own filter out scratchpad function
  288.     noScratchPad ws = if ws == "NSP" then "" else pad ws
  289.  
  290.     -- L needed for loggers
  291.     dzenFG  c = dzenColor  c ""
  292.     dzenFGL c = dzenColorL c ""
  293.  
  294.     -- custom loggers
  295.     myMail     = wrapL "Mail: " ""  . dzenFGL colorFG2 $ maildirNew "/home/yadda/Mail/GMail/INBOX"
  296.     --myUpdates  = logCmd "$HOME/.bin/logger-updates"
  297.     --myTorrents = logCmd "$HOME/.bin/logger-torrents"
  298.  
  299.     myRename = (\x -> case x of
  300.                "Hinted ResizableTall"          -> "/ /-/"
  301.                "Mirror Hinted ResizableTall"   -> "/-,-/"
  302.                "Hinted Tabbed Bottom Simplest" -> "/.../"
  303.                "Hinted TwoPane"                -> "/ / /"
  304.                "Hinted Full"                   -> "/  /"
  305.                _                               -> x
  306.                ) . stripIM
  307.  
  308.     stripIM s = if "IM " `isPrefixOf` s then drop (length "IM ") s else s
  309.  
  310. -- }}}
  311.  
  312. -- My SpawnHook {{{
  313. --
  314. -- spawn an arbitrary command on urgent
  315. --
  316. data MySpawnHook = MySpawnHook String deriving (Read, Show)
  317.  
  318. instance UrgencyHook MySpawnHook where
  319.   urgencyHook (MySpawnHook s) w = spawn $ s
  320.  
  321. -- 'ding!'
  322. myUrgencyHook = MySpawnHook ""
  323.  
  324. -- }}}
  325.  
  326. -- Key Bindings {{{
  327. --
  328. -- only those which override/change defaults
  329. --
  330. -- see http://pbrisbin.com:8080/pages/scripts.html
  331. --
  332. myKeys = [ ("M4-p"                   , spawn "launcher"        ) -- dmenu app launcher
  333.          , ("M4-r"                   , spawn "bashrun"         ) -- gmrun replacement
  334.          , ("M4-C-c"                 , kill                    ) -- kill the focused window
  335.  
  336.          -- opening apps with Win
  337.          , ("M4-e"                  , spawn "nautilus --no-desktop") -- bring me a nautilus
  338.          , ("M4-g"                  , spawn "gedit"           ) -- start gedit
  339.          , ("M4-x"                  , spawn "urxvtc"          ) -- bring me a full urxvtc
  340.          , ("M4-u"                  , scratchTerm             ) -- bring me a term
  341.          , ("M4-S-m"                , scratchMixer            ) -- bring me a mixer
  342.          , ("M4-m"                  , spawn myMail            ) -- open mail client
  343.          , ("M4-b"                  , spawn myBrowser         ) -- open web client
  344.          , ("M4-c"                  , spawn myIRC             ) -- open/attach IRC client in screen
  345.          , ("M4-S-t"                , spawn myTorrents        ) -- open/attach rtorrent in screen
  346.          , ("M4-l"                  , spawn myLock            ) -- W-l to lock screen
  347.          , ("M4-S-h"                , spawn myHtop            ) -- htop
  348.  
  349.          -- some custom hotkeys
  350.          , ("M4-a"                   , spawn "msearch all"     ) -- search current playlist via dmenu
  351.          , ("M4-C-g"                 , spawn "goodsong"        ) -- note current song as 'good'
  352.          , ("M4-S-g"                 , spawn "goodsong -p"     ) -- play a random 'good' song
  353.          , ("<Print>"                , spawn "scrot"           ) -- take a screenshot
  354.  
  355.          -- extended workspace navigations
  356.          , ("M4-`"                   , toggleWS                ) -- switch to the most recently viewed ws
  357.          , ("M4-<Backspace>"         , focusUrgent             ) -- focus most recently urgent window
  358.          , ("M4-S-<Backspace>"       , clearUrgents            ) -- make urgents go away
  359.          , ("M4-0"                   , viewEmptyWorkspace      ) -- go to next empty workspace
  360.          , ("M4-S-0"                 , tagToEmptyWorkspace     ) -- targ window to empty workspace and view it
  361.  
  362.          -- extended window movements
  363.          , ("M4-o"                   , sendMessage MirrorShrink) -- shink slave panes vertically
  364.          , ("M4-i"                   , sendMessage MirrorExpand) -- expand slave panes vertically
  365.          , ("M4-f"                   , jumpToFull              ) -- jump to full layout
  366.          , ("M4-C-m"                 , withFocused (sendMessage . maximizeRestore)      ) -- "maximalize" window
  367.          , ("M4-C-n"                 , withFocused (\f -> sendMessage (MinimizeWin f))  ) -- "minimize" window
  368.          , ("M4-n"                   , sendMessage RestoreNextMinimizedWin) -- restore "minimized" windows on this workspace
  369.          , ("M4-S-x"                 , sendMessage ToggleStruts) -- makes dzen bars go away
  370.  
  371.  
  372.          -- non-standard navigation
  373.          , ("M4-C-h"                 , sendMessage Shrink      ) -- shrink master (was M-h)
  374.          , ("M4-C-l"                 , sendMessage Expand      ) -- expand master (was M-l)
  375.  
  376.          -- mpd and oss volume
  377.          , ("<XF86AudioRewind>"     , spawn "mpc seek -00:00:05"    ) -- rewind 5 sec
  378.          , ("<XF86AudioForward>"    , spawn "mpc seek +00:00:05"    ) -- forward 5 sec
  379.          , ("<XF86AudioPlay>"       , spawn "mpc toggle"            ) -- play/pause mplayer
  380.          , ("<XF86AudioStop>"       , spawn "mpc stop"        ) -- stop mpd
  381.          , ("<XF86AudioPrev>"       , spawn "mpc prev"        ) -- prev song
  382.          , ("<XF86AudioNext>"       , spawn "mpc next"        ) -- next song
  383.          , ("<XF86AudioMute>"       , spawn "amixer sset Master toggle"       ) -- toggle mute
  384.          , ("<XF86AudioLowerVolume>", spawn "amixer -c 0 set Master 5dB-"     ) -- volume down
  385.          , ("<XF86AudioRaiseVolume>", spawn "amixer -c 0 set Master 5dB+"     ) -- volume up
  386.  
  387.          -- Mod+ to control MPlayer
  388.          , ("M4-<XF86AudioPlay>"     , mPlay "pause"           ) -- play/pause mplayer
  389.          , ("M4-<XF86AudioStop>"     , mPlay "stop"            ) -- stop mplayer
  390.          , ("M4-<XF86AudioPrev>"     , mPlay "seek -10"        ) -- seek back 10s
  391.          , ("M4-<XF86AudioNext>"     , mPlay "seek 10"         ) -- seek forward 10s
  392.  
  393.          -- kill, reconfigure, exit commands
  394.          , ("M4-w"                   , killAll                 ) -- close all windows on this ws
  395.          , ("M4-q"                   , spawn myRestart         ) -- restart xmonad
  396.          , ("M4-S-q"                 , spawn "leave"           ) -- logout/shutdow/restart menu
  397.  
  398.          , ("M4-s"                   , spawnSelected defaultGSConfig myApps)
  399.          , ("M4-S-s"                 , goToSelected defaultGSConfig )
  400.          ]
  401.  
  402.          where
  403.  
  404.            myApps        = ["ario","gimp","jD","gedit","tbird","iview","mp3tag","mirc","eclipse","OOo Writer","boinc","texmaker","smplayer"]
  405.  
  406.            focusScreen n = screenWorkspace n >>= flip whenJust (windows . W.view)
  407.  
  408.            jumpToFull    = sendMessage $ JumpToLayout "Hinted Full"
  409.  
  410.            scratchTerm   = namedScratchpadAction myScratchPads "terminal"
  411.            scratchMixer  = namedScratchpadAction myScratchPads "mixer"
  412.  
  413.            -- my apps
  414.            myMail        = myTerminal ++ " -e mutt"
  415.            myHtop        = myTerminal ++ " -e htop"
  416.            myBrowser     = "firefox"
  417.            myLock        = "slock"
  418.            myEject       = "eject -T /dev/sr0"
  419.  
  420.            myIRC         = myScreen "irssi"
  421.            myTorrents    = myScreen "rtorrent"
  422.  
  423.            -- see http://pbrisbin.com:8080/pages/screen_tricks.html
  424.            myScreen s    = myTerminal ++ " -title "                    ++ s
  425.                                    ++ " -e bash -cl \"SCREEN_CONF=" ++ s
  426.                                    ++ " screen -S "                 ++ s
  427.                                    ++ " -R -D "                     ++ s
  428.                                    ++ "\""
  429.  
  430.            -- see http://pbrisbin.com:8080/pages/mplayer-control.html
  431.            mPlay s       = spawn $ "echo " ++ s ++ " > $HOME/.mplayer_fifo"
  432.  
  433.            -- kill all conky/dzen2 before executing default restart command
  434.            myRestart     = "for pid in `pgrep conky`; do kill -9 $pid; done && " ++
  435.                            "for pid in `pgrep dzen2`; do kill -9 $pid; done && " ++
  436.                            "xmonad --recompile && xmonad --restart"
  437.  
  438. -- }}}
  439.  
  440. -- vim:foldmethod=marker foldmarker={{{,}}}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement