-- -*- haskell -*- import Monad (liftM) import XMonad import XMonad.Core import System.Exit import qualified XMonad.StackSet as W import qualified Data.Map as M import XMonad.Layout.Tabbed import XMonad.Layout.ResizableTile import XMonad.Layout.Grid import XMonad.Layout.Magnifier import XMonad.Layout.TabBarDecoration import XMonad.Hooks.DynamicLog ( PP(..), dynamicLogWithPP, dzenColor, wrap, defaultPP ) import XMonad.Actions.CycleWS import XMonad.Hooks.ManageDocks import XMonad.Hooks.EwmhDesktops import XMonad.Actions.DwmPromote import XMonad.Actions.UpdatePointer import XMonad.Hooks.UrgencyHook import XMonad.Util.Run (spawnPipe) import System.IO import XMonad.Prompt import XMonad.Prompt.Shell more generic search prompts than those in XMonad.Prompt.Search import XMonad.Util.WorkspaceCompare import XMonad.Util.EZConfig import Graphics.X11.ExtraTypes.XF86(xF86XK_AudioLowerVolume, xF86XK_AudioMute, xF86XK_AudioNext, xF86XK_AudioPlay, xF86XK_AudioPrev, xF86XK_AudioRaiseVolume, xF86XK_AudioStop, xF86XK_Forward, xF86XK_Back) import XMonad.Actions.Warp import Data.Ratio myStatusbarCmd = "run-dzen2" myTerminal = "urxvtc" myScreenLock = "xlock +nolock" myBorderWidth = 0 myModMask = mod4Mask myNumlockMask = mod2Mask myWorkspaces = ["1:web", "2:bk" ,"3:ssh", "4:dev", "5:sh", "6:maths", "7:games", "8:multimedia", "9:tmp", "10:logs"] myNormalBorderColor = "#111" myFocusedBorderColor = "cadetblue3" myKeys = \conf -> mkKeymap conf $ [ ("C-S-", spawn $ myScreenLock) , ("M-C-", spawn $ "xkill") , ("M-", sendMessage NextLayout) , ("M-S-", setLayout $ XMonad.layoutHook conf) , ("M-n", refresh) , ("M-S-c", kill) , ("M-", windows W.focusDown) , ("M-j", windows W.focusDown) , ("M-S-", windows W.focusUp) , ("M-k", windows W.focusUp) , ("M-m", windows W.focusMaster) , ("M-S-k", windows W.swapDown) , ("M-S-j", windows W.swapUp) , ("M-b", sendMessage ToggleStruts) , ("M-h", sendMessage Shrink) , ("M-l", sendMessage Expand) , ("M-t", withFocused $ windows . W.sink) , ("M-,", sendMessage (IncMasterN 1)) , ("M-.", sendMessage (IncMasterN (-1))) , ("M-S-q", io (exitWith ExitSuccess)) , ("M-q", restart "xmonad" True) , ("M-p", shellPrompt oxyXPConfig) , ("M-o", shellPrompt oxyXPConfig) , ("M-S-", shiftToNext >> nextWS) , ("M-S-", shiftToPrev >> prevWS) , ("M-", nextScreen) , ("M-S-", shiftNextScreen >> nextScreen) , ("M-", prevNonEmptyWS) , ("M-C-k", prevNonEmptyWS) , ("M-", nextNonEmptyWS) , ("M-C-j", nextNonEmptyWS) , ("M-s", swapNextScreen) , ("M-", swapNextScreen) , ("M-a", sendMessage MirrorShrink) , ("M-y", sendMessage MirrorExpand) , ("M-", dwmpromote) , ("M-x c", kill) , ("M-u M-x M-x", swapNextScreen) , ("M-x a", spawn "cgoban") , ("M-x b", spawn "urxvtc -g 80x24+172+149 -pe tabbed") , ("M-x d", spawn "urxvtc -e sh -c 'screen -x'") , ("M-x e", spawn "urxvtc -name Emacs -g 272x83+0-0 -e sh -c 'TERM=xterm-color emacsclient -nw'") sh -c 'TERM=xterm-color nimred-emacsclient'") , ("M-x f", spawn "urxvtc -name firefox -g 96x11+626+494 -e firefox3") , ("M-x g", spawn "gcalculator") , ("M-x h", spawn "xboard -boardSize Middling -fcp crafty -clockMode False") , ("M-x l", spawn "urxvtc -name slrn -g 252x78+64+48 -e sh -c 'slrn'") -e sh -c 'TERM=xterm-color emacs -daemon -g 272x83+0-0'") , ("M-x m", spawn "urxvtc -name Mutt -g 252x78+64+48 -e sh -c 'env TERM=xterm-color mutt -y'") , ("M-x n", spawn "urxvtc -name ncmpc -g 150x35-56-40 -e sh -c 'TERM=xterm-color ncmpc'") -e opera -nomail -noraise -geometry 1244x670+326+128") , ("M-x o", spawn "urxvtc -name opera -g 96x11+644+320 -e opera -nomail -noraise -geometry 1109x574+386+116") , ("M-x p", spawn "opera -newpage `xclip -o | xargs echo`") , ("M-x r", spawn "urxvtc -name radiobrowser -g 99x80+39-26 -e sh -c 'screen -xRD -c ~/.screenrc4tvradio'") , ("M-x s", spawn "fltk-sudoku -g 480x505+928+107") -e sh -c 'screen -xRD -c ~/.screenrc4tv'") , ("M-x v", spawn "urxvtc -name vim -g 252x78+64+48 -e sh -c 'TERM=xterm-color vim'") , ("M-x w", spawn "urxvtc -g 245x72-91-88 -C") , ("M-x x", spawn $ XMonad.terminal conf) , ("M-x M-o", spawn "urxvtc -g 80x24+780+448 -e soffice -nologo") , ("M-x M-f", spawn "urxvtc -g 226x30+331+116 -e finch") , ("M1-x p", spawn "emacsclient --eval '(emms-play-playlist (expand-file-name \"~/.emacs.d/emms/All.m3u\"))'") , ("M1-x r", spawn "emacsclient --eval '(emms-random)'") , ("C-", spawn "emacsclient --eval '(emms-seek-forward)'") , ("C-", spawn "emacsclient --eval '(emms-seek-backward)'") , ("S-", spawn "xclip -o | xargs echo | wgetpaste -X > /dev/console") , ("S-", spawn "xclip -o | xargs echo | xargs -o wgetpaste -X -c > /dev/console") , ("C-M1-r", spawn "sudo /sbin/fastboot") , ("C-M1-p", spawn "sudo /sbin/fasthalt -p") , ("C-M1-M-e", spawn "eject /dev/rcd0d") , ("C-M1-M-p", spawn "sudo /sbin/shutdown -p now") , ("C-M1-M-r", spawn "sudo /sbin/shutdown -r now") , ("C-M1-M-w", spawn "random-wallpaper") , ("M-<", spawn $ myScreenLock) , ("M1-", spawn $ XMonad.terminal conf) , ("M-w", sendMessage MagnifyMore) , ("M-e", sendMessage MagnifyLess) , ("C-<", warpToWindow (1%10) (1%10)) -- Move pointer to currently focused window ] ++ [ (m ++ i, windows $ f j) | (i, j) <- zip (map show [1..9]) (XMonad.workspaces conf) , (m, f) <- [("M-", W.view), ("M-S-", W.shift)] ] where nextNonEmptyWS = moveTo Next (WSIs (liftM (not .) isVisible)) prevNonEmptyWS = moveTo Prev (WSIs (liftM (not .) isVisible)) isVisible :: X (WindowSpace -> Bool) isVisible = do vs <- gets (map (W.tag . W.workspace) . W.visible . windowset) return (\w -> (W.tag w) `elem` vs) multimediaKeys = [ ((0 , xF86XK_AudioMute), spawn "aumute") , ((0 , xF86XK_AudioLowerVolume), spawn "aumix -v-5") , ((0 , xF86XK_AudioRaiseVolume), spawn "aumix -v+5 ") , ((0 , xF86XK_AudioPlay), spawn "emacsclient --eval '(emms-pause)'") , ((0 , xF86XK_AudioStop), spawn "emacsclient --eval '(emms-stop)'") , ((0 , xF86XK_AudioPrev), spawn "emacsclient --eval '(emms-previous)'") , ((0 , xF86XK_AudioNext), spawn "emacsclient --eval '(emms-next)'") ] -- Config for Prompt oxyXPConfig :: XPConfig oxyXPConfig = defaultXPConfig { font = "xft:Consolas-12" , bgColor = "Aquamarine3" , fgColor = "black" , fgHLight = "black" , bgHLight = "darkslategray4" , borderColor = "black" , promptBorderWidth = 1 , position = Top , height = 24 , defaultText = [] } myMouseBindings (XConfig {XMonad.modMask = modMask}) = M.fromList $ [ ((modMask, button1), (\w -> focus w >> mouseMoveWindow w)) , ((modMask, button2), (\w -> focus w >> windows W.swapMaster)) , ((modMask, button3), (\w -> focus w >> mouseResizeWindow w)) , ((modMask, button4), (\_ -> windows W.focusUp)) , ((modMask, button5), (\_ -> windows W.focusDown)) , ((controlMask .|. modMask, button5), nextNonEmptyWS) , ((controlMask .|. modMask, button4), prevNonEmptyWS) ] where nextNonEmptyWS = \_ -> moveTo Next (WSIs (liftM (not .) isVisible)) prevNonEmptyWS = \_ -> moveTo Prev (WSIs (liftM (not .) isVisible)) myLayout = avoidStrutsOn[U] $ tabs ||| tiled ||| Mirror tiled ||| magnify Grid where tiled = ResizableTall nmaster delta ratio [] nmaster = 1 ratio = 8 % 13 delta = 3 % 100 tabs = tabbed shrinkText oxyDarkTheme magnify = magnifiercz (13%10) -- Configuration for Tabbed oxyTheme :: Theme oxyTheme = defaultTheme { inactiveBorderColor = "#000" , activeBorderColor = myFocusedBorderColor , activeColor = "aquamarine3" , inactiveColor = "DarkSlateGray4" , inactiveTextColor = "#222" , activeTextColor = "#222" , fontName = "xft:Consolas-10:bold" , decoHeight = 18 , urgentColor = "#000" , urgentTextColor = "#63b8ff" } oxyDarkTheme :: Theme oxyDarkTheme = defaultTheme { inactiveBorderColor = "#777" , activeBorderColor = myFocusedBorderColor , activeColor = "#000" , inactiveColor = "#444" , inactiveTextColor = "aquamarine4" , activeTextColor = "aquamarine1" , fontName = "xft:Dejavu Sans Mono-8" , decoHeight = 15 , urgentColor = "#000" , urgentTextColor = "#63b8ff" } -- A manageHook to float everything by default and unfloat a few windows myManageHook :: ManageHook myManageHook = composeAll [ appName =? "urxvt" --> unfloat , appName =? "Console" --> unfloat , appName =? "Emacs" --> unfloat , appName =? "slrn" --> unfloat , appName =? "Mutt" --> unfloat , appName =? "sshinfo" --> unfloat , appName =? "sshfr" --> unfloat , appName =? "sshnet" --> unfloat , className =? "Minefield" --> doF (W.shift "1:web") , appName =? "firefox" --> doF (W.shift "1:web") , className =? "Firefox" --> doF (W.shift "1:web") , className =? "Opera" --> doF (W.shift "1:web") , className =? "opera" --> doF (W.shift "1:web") , appName =? "opera" --> doF (W.shift "1:web") , appName =? "sshinfo" --> doF (W.shift "3:ssh") , appName =? "sshfr" --> doF (W.shift "3:ssh") , appName =? "sshnet" --> doF (W.shift "3:ssh") , appName =? "scilex" --> doF (W.shift "6:maths") , appName =? "Xscilab" --> doF (W.shift "6:maths") , className =? "CGoban Control" --> doF (W.shift "7:games") , className =? "Basicwin" --> doF (W.shift "7:games") , className =? "xboard" --> doF (W.shift "7:games") , className =? "XBoard" --> doF (W.shift "7:games") , className =? "Sudoku" --> doF (W.shift "7:games") , className =? "Fltk" --> doF (W.shift "7:games") , appName =? "tvbrowser" --> doF (W.shift "8:multimedia") , appName =? "radiobrowser" --> doF (W.shift "8:multimedia") , appName =? "ncmpc" --> doF (W.shift "8:multimedia") , className =? "MPlayer" --> doF (W.shift "8:multimedia") , className =? "VLC" --> doF (W.shift "8:multimedia") , className =? "vlc" --> doF (W.shift "8:multimedia") , appName =? "VLC" --> doF (W.shift "8:multimedia") , appName =? "vlc" --> doF (W.shift "8:multimedia") , appName =? "Mutt" --> doF (W.shift "9:tmp") , appName =? "slrn" --> doF (W.shift "9:tmp") , appName =? "Xpdf" --> doF (W.shift "9:tmp") , appName =? "Console" --> doF (W.shift "10:logs") ] <+> doFloat <+> manageDocks where unfloat = ask >>= doF . W.sink -- Status bars and logging myLogHook h = do ewmhDesktopsLogHook dynamicLogWithPP $ oxyPP h updatePointer (Relative (1/20) (1/20)) -- dynamiclog pretty printer for dzen -- oxyPP :: Handle -> PP oxyPP h = defaultPP { ppCurrent = wrap "^fg(#000000)^bg(#a6c292)^p(2)^i(/home/nimred/.icons/has_win.xbm)" "^p(2)^fg()^bg()" , ppSep = " ^fg(grey60)^r(3x3)^fg() " , ppWsSep = "" , ppVisible = wrap "^bg(grey30)^fg(grey75)^p(2)" "^p(2)^fg()^bg()" , ppLayout = dzenColor "#80AA83" "" . (\x -> case x of "Mirror ResizableTall" -> "MTiled" "ResizableTall" -> "Tiled" "Tabbed Bottom Simplest" -> "Tabbed" "Tabbed Simplest" -> "Tabbed" _ -> x ) , ppTitle = dzenColor "white" "" . wrap "< " " >" , ppOutput = hPutStrLn h } myFocusFollowsMouse :: Bool myFocusFollowsMouse = True ------------------------------------------------------------------------ -- Now run xmonad with all the defaults we set up. main = do pipe <- spawnPipe myStatusbarCmd xmonad $ withUrgencyHook NoUrgencyHook $ defaults pipe defaults pipe = defaultConfig { -- simple stuff terminal = myTerminal, focusFollowsMouse = myFocusFollowsMouse, borderWidth = myBorderWidth, modMask = myModMask, numlockMask = myNumlockMask, workspaces = myWorkspaces, normalBorderColor = myNormalBorderColor, focusedBorderColor = myFocusedBorderColor, -- key bindings keys = myKeys, mouseBindings = myMouseBindings, -- hooks, layouts layoutHook = myLayout, manageHook = myManageHook, logHook = myLogHook pipe } `additionalKeys` multimediaKeys