From 6a6dc927416c5c488aa73d3ee13f6640ed3b617e Mon Sep 17 00:00:00 2001 From: Alexander Sulfrian Date: Thu, 3 Jul 2014 00:43:19 +0200 Subject: initial commit --- xmonad.hs | 456 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 456 insertions(+) create mode 100644 xmonad.hs (limited to 'xmonad.hs') diff --git a/xmonad.hs b/xmonad.hs new file mode 100644 index 0000000..8865171 --- /dev/null +++ b/xmonad.hs @@ -0,0 +1,456 @@ +import System.IO +import System.Directory +import Data.Ratio ((%)) +import Data.List +import qualified Data.Map as M + +import XMonad +import XMonad.Core +import XMonad.Config +import XMonad.ManageHook +import qualified XMonad.StackSet as W +import qualified XMonad.Prompt as P + +import XMonad.Layout.DecorationMadness +import XMonad.Layout.Grid +import XMonad.Layout.IM +import XMonad.Layout.MosaicAlt +import XMonad.Layout.Named +import XMonad.Layout.NoBorders +import XMonad.Layout.PerWorkspace +import XMonad.Layout.Reflect +import XMonad.Layout.Tabbed +import XMonad.Layout.ThreeColumns +import XMonad.Layout.TrackFloating +import qualified XMonad.Layout.Magnifier as Mag + +import XMonad.Actions.CopyWindow +import XMonad.Actions.CycleWS +import XMonad.Actions.DynamicWorkspaces +import XMonad.Actions.FindEmptyWorkspace +import XMonad.Actions.FloatSnap +import XMonad.Actions.GridSelect +import XMonad.Actions.SinkAll +import XMonad.Actions.UpdateFocus +import qualified XMonad.Actions.FlexibleManipulate as Flex + +import XMonad.Hooks.DynamicLog +import XMonad.Hooks.EwmhDesktops +import XMonad.Hooks.ManageDocks +import XMonad.Hooks.ManageHelpers +import XMonad.Hooks.ServerMode +import XMonad.Hooks.SetWMName +import XMonad.Hooks.UrgencyHook +import XMonad.Hooks.XPropManage + +import XMonad.Prompt.AppLauncher +import XMonad.Prompt.Man +import XMonad.Prompt.Shell +import XMonad.Prompt.Ssh +import XMonad.Prompt.XMonad + +import XMonad.Util.NamedScratchpad + +-- taffybar +import System.Taffybar.Hooks.PagerHints (pagerHints) + +-- --replace handling +import XMonad.Util.Replace (replace) +import Control.Monad (when) +import System.Environment (getArgs) + +-- custom modules +import HistoryGrid +import EZConfig +import Pass + +font :: String +font = "-*-terminus-medium-r-normal-*-12-*-*-*-*-*-*-*" + +term :: String +term = "urxvt" + +browser :: String +browser = "viewurl-opera.sh" + +myWorkspaces :: [String] +myWorkspaces = ["1:web", "2:mail" ,"3:irc", "4:im", "5:code"] ++ map show [6 .. 9 :: Int] ++ ["0", "video", "music"] + +modM = mod4Mask -- mod1Mask = Alt, mod2Mask = , mod3Mask= , mod4Mask = Win, mod5Mask = AltGr + +myDzenUrgencyConfig = DzenUrgencyHook + { args = ["-bg", "red", "-fg", "black", "-fn", font, + "-w", "480", "-ta", "c", "-x", "480"] + , duration = seconds 5 + } + +main = do + args <- getArgs + when ("--replace" `elem` args) replace + + dzenStatusDir <- getAppUserDataDirectory "xmonad" + dzenStatusFile <- openFile (dzenStatusDir ++ "/dzenStatus") WriteMode + xmonad + -- Do _not_ use "ewhm" here, this would add the ewhm hooks to the + -- end of your custom hooks (esp. the startup hook) and this would + -- overwrite the setWMName "LG3D" and some Java apps will not work. + $ pagerHints + $ withUrgencyHook myDzenUrgencyConfig + $ myConfig dzenStatusFile + +myConfig statusFile = defaultConfig + { modMask = modM + , terminal = term + , borderWidth = 1 + , normalBorderColor = "#545454" + , focusedBorderColor = "#A00000" + , logHook = myLogHook statusFile + , manageHook = myManageHook + , keys = \c -> mkKeymap c $ myKeys c + , mouseBindings = \c -> M.union (M.fromList $ myMouse c) $ mouseBindings defaultConfig c + , layoutHook = myLayout + , workspaces = myWorkspaces + , handleEventHook = myEventHook + , startupHook = myStartupHook + } + +-- +-- Prompts +-- + +data MyShell = MyShell +instance XPrompt MyShell where + showXPrompt MyShell = "Run: " +myShellPrompt :: XPConfig -> X () +myShellPrompt c = do + cmds <- io getCommands + mkXPrompt MyShell c (getShellCompl cmds) spawn + +-- +-- Scratchpads +-- + +scratchpads = + [ NS "hotot" "hotot" (className =? "Hotot") + (customFloating $ W.RationalRect 0.01 0.01 0.4 0.98) + , NS "log" "urxvt -name logtail -e logtail" (appName =? "logtail") + (customFloating $ W.RationalRect 0.03 0.03 0.94 0.6) + ] + +hiddenWS :: X (WindowSpace -> Bool) +hiddenWS = do hs <- gets (map W.tag . W.hidden . windowset) + return (\w -> W.tag w `elem` hs) + +notNspWS :: X (WindowSpace -> Bool) +notNspWS = return $ ("NSP" /=) . W.tag + +notNspHiddenWS :: X (WindowSpace -> Bool) +notNspHiddenWS = do nn <- notNspWS + hi <- hiddenWS + return (\w -> hi w && nn w) + + +-- +-- Themes +-- +myPP statusFile = namedScratchpadFilterOutWorkspacePP $ defaultPP + { ppCurrent = wrap "^fg(#FF0000) " " " + , ppVisible = wrap "^fg(#0000FF) " " " + , ppHiddenNoWindows = \(_)->"" + , ppUrgent = wrap "^bg(#FFFF00)^fg(#FF0000) " " " + , ppHidden = pad + , ppWsSep = "^fg(#888)^bg(#000):" + , ppSep = "^fg(#888)^bg(#000):" + , ppLayout = wrap "^fg(#fff)" "^fg(#888)" . pad . (\x -> transformLayout x) + , ppTitle = ("^fg(#FF0000) " ++) . dzenEscape + , ppOrder = \(ws:l:t:[]) -> ["^fg(#888)^bg(#000)" ++ ws,l,t] + , ppOutput = dzenWriteStatus statusFile + } + where + dzenWriteStatus file status = do + hPutStrLn file status + hFlush file + -- helper for better Layoutnames + transformLayout x = foldl1 (++) + $ layoutTransform + $ magnifierTransform + $ [] : words x + magnifierTransform (prefix:magnifier:status:xs) + | magnifier == "Magnifier" && status == "(off)" = (prefix ++ "+"):xs + | magnifier == "Magnifier" = (prefix ++ "*"):status:xs + | otherwise = ((prefix ++ unwords [magnifier, status]):xs) + layoutTransform (prefix:l) + | unwords l == "ThreeCol" = [prefix, "|||"] + | unwords l == "Tabbed" = [prefix, "[ ]"] + | unwords l == "Mirror Tall" = [prefix, "=|="] + | unwords l == "Tall" = [prefix, "[]="] + | otherwise = prefix:l + +alexTheme :: Theme +alexTheme = defaultTheme + { inactiveBorderColor = "#545454" + , activeBorderColor = "#6E0000" + , activeColor = "#6E0000" + , inactiveColor = "#424242" + , inactiveTextColor = "#ffffff" + , activeTextColor = "#ffffff" + , fontName = font + , decoHeight = 15 + } + +historyGridConfig = defaultGSConfig + { gs_cellheight = 50 + , gs_cellwidth = 300 + , gs_navigate = navNSearch + , gs_font = "xft:Droid Sans Mono Slashed-8" + } + +-- +-- Hooks +-- +myLogHook statusFile = do + ewmhDesktopsLogHook + dynamicLogWithPP $ myPP statusFile + +myEventHook = do + ewmhDesktopsEventHook + serverModeEventHook + focusOnMouseMove + docksEventHook + +myStartupHook = do + ewmhDesktopsStartup + adjustEventInput + setWMName "LG3D" + +myManageHook = + namedScratchpadManageHook scratchpads + <+> xPropManageHook xPropMatches + <+> manageDocks + <+> (isDialog + --> doCenterFloat) + + <+> (appName =? "hexcalc" --> + (doRectFloat $ W.RationalRect 0.75 0.505 0.2 0.395)) + <+> (appName =? "xcalc" --> + (doRectFloat $ W.RationalRect 0.75 0.1 0.2 0.395)) + <+> (appName =? "wpa_gui" --> + (doRectFloat $ W.RationalRect 0.01 0.01 0.4 0.25)) + <+> (className =? "Vncviewer" --> + doCenterFloat) + + -- (yt) flash fullscreen mode + <+> (className =? "Operapluginwrapper-native" --> + doFullFloat) + <+> (className =? "Exe" --> + doFullFloat) + + -- xcalendar + <+> (appName =? "dayEditor" --> + (doRectFloat $ W.RationalRect 0.5 0.02 0.33 0.3)) + <+> (appName =? "xcalendar" --> + (doRectFloat $ W.RationalRect 0.83 0.02 0.15 0.3)) + + -- emacs compose mail + <+> (appName =? "wanderlust-draft" --> + (doRectFloat $ W.RationalRect 0.1 0.1 0.8 0.8)) + + <+> (className =? "Gxmessage" --> + doCenterFloat) + +xPropMatches :: [XPropMatch] +xPropMatches = + [ ([ (xprop, any (app `op`))], pmP (W.shift target)) | (xprop, op, app, target) <- myShifts] ++ + [ ([ (xprop, any (app ==))], pmX (float)) | (xprop, app) <- myFloats] + where + myFloats = + [ (wM_CLASS, "vlc") + , (wM_CLASS, "Xmessage") + , (wM_CLASS, "XVkbd") + , (wM_CLASS, "Xdialog") + , (wM_CLASS, "Pinentry") + , (wM_CLASS, "Pinentry-gtk-2") + , (wM_CLASS, "Tiemu") + , (wM_CLASS, "ultrastardx") + , (wM_CLASS, "Ediff") + , (wM_CLASS, "xtensoftphone") + , (wM_CLASS, "Pqiv") + , (wM_CLASS, "XNots") + , (wM_CLASS, "TeamViewer.exe") + , (wM_CLASS, "AmsnWebcam") + , (wM_NAME, "glxgears") + , (wM_NAME, "Passphrase Required") + , (wM_NAME, "Mark all as read") + , (wM_NAME, "Xplanet 1.2.0") + , (wM_NAME, "Eclipse") + ] + + myShifts = + [ (wM_CLASS, (==), "Opera", "1:web") + , (wM_CLASS, (==), "Chrome", "1:web") + , (wM_CLASS, (==), "Chromium-browser", "1:web") + , (wM_CLASS, (==), "Firefox-bin", "1:web") + + , (wM_CLASS, (==), "Claws-mail", "2:mail") + , (wM_CLASS, (==), "Mitter", "2:mail") + , (wM_CLASS, (==), "wanderlust", "2:mail") + , (wM_NAME, (==), "newsbeuter", "2:mail") + + , (wM_CLASS, (==), "Hexchat", "3:irc") + + -- tkabber roater + , (wM_CLASS, (==), "Tkabber", "4:im") + -- tkabber single messages + , (wM_CLASS, (==), "headlines", "4:im") + , (wM_CLASS, isPrefixOf, "chat_##xmpp##1_zedatconferencejabberfuberlinde", "4:im") + , (wM_CLASS, isPrefixOf, "chat_##xmpp##1_mailanimuxdeSyslogBot", "4:im") + + , (wM_CLASS, (==), "emacs", "5:code") + + , (wM_CLASS, (==), "MPlayer", "video") + , (wM_CLASS, (==), "Amarokapp", "music") + ] + +-- +-- Keys +-- +myKeys c = + -- this line is critical to reload config - DON'T REMOVE + [ ("M-q", broadcastMessage ReleaseResources >> restart "xmonad" True) + + , ("M-S-", spawn term) + , ("M-", openLastHistoryGrid historyGridConfig 30) + + -- kill current, kill all + , ("M-S-c", kill1) + , ("M-C-c", kill) + + -- sticky + , ("M-S-v", windows copyToAll) + , ("M-C-v", killAllOtherCopies) + + , ("M-", sendMessage NextLayout) + , ("M-S-", setLayout $ XMonad.layoutHook c) + + , ("M-", windows W.focusDown) + , ("M-S-", windows W.focusUp) + , ("M-j", windows W.focusDown) + , ("M-k", windows W.focusUp) + + , ("M-S-j", windows W.swapDown) + , ("M-S-k", windows W.swapUp) + + , ("M-m", selectWorkspace P.defaultXPConfig) + , ("M-S-m", withWorkspace P.defaultXPConfig (windows . W.shift)) + , ("M-S-", removeWorkspace) + + , ("M-h", sendMessage Shrink) + , ("M-l", sendMessage Expand) + + -- sink / sinkAll + , ("M-t", withFocused $ windows . W.sink) + , ("M-S-t", sinkAll) + + , ("M-z", namedScratchpadAction scratchpads "hotot") + , ("M5-l", namedScratchpadAction scratchpads "log") + + , ("M-,", sendMessage (IncMasterN 1)) + , ("M-.", sendMessage (IncMasterN (-1))) + + , ("M-b", sendMessage ToggleStruts) + + , ("M-i", spawn "xprop | gxmessage -file -") + + , ("M-", moveTo Prev $ WSIs notNspHiddenWS) + , ("M-", moveTo Next $ WSIs notNspHiddenWS) + + , ("M-d", spawn "fbsetroot -solid black") + , ("M-f", spawn "fbsetroot -l") + + , ("M-^", viewEmptyWorkspace) + , ("M-S-^", tagToEmptyWorkspace) + + , ("M-p", myShellPrompt P.defaultXPConfig) + , ("M-e", launchApp P.defaultXPConfig "emacsclient" >> (windows (W.greedyView "5:code"))) + + , ("M-o M-k", passPrompt P.defaultXPConfig) + , ("M-o M-S-k", passGeneratePrompt P.defaultXPConfig) + , ("M-o M-m", manPrompt P.defaultXPConfig) + , ("M-o M-b", safePrompt browser P.defaultXPConfig) + , ("M-o M-s", sshPrompt P.defaultXPConfig) + , ("M-o M-x", xmonadPrompt P.defaultXPConfig) + + , ("M-g", goToSelected defaultGSConfig) + , ("M-S-g", bringSelected defaultGSConfig) + + , ("M-", focusUrgent) + + , ("M-+", sendMessage Mag.MagnifyMore) + , ("M-S-+", sendMessage Mag.MagnifyLess) + , ("M-#", sendMessage Mag.Toggle) + + -- multimedia keys + , ("", spawn "amixer -c0 -- set Master playback 2dB-") + , ("", spawn "amixer -c0 -- set Master playback 2dB+") + , ("", spawn "amixer -q -c0 set Master toggle") + + -- Screenshot + , ("", spawn "scrot '%Y-%m-%d_%s_$wx$h.png' -e 'mv $f ~/images/screenshot/; pqiv ~/images/screenshot/$n'") + + ] + ++ + + -- switch to / move / copy to workspace + [ + (m ++ k, windows $ f i) + | (i, k) <- zip myWorkspaces $ [[k] | k <- "1234567890"] ++ ["", ""], + (m, f) <- [("M-", W.view), ("M-S-", W.shift), ("M-C-", copy)] + ] + ++ + + [ + (m ++ k, screenWorkspace s >>= flip whenJust (windows . f)) + | (k, s) <- [("a", 0), ("s", 1)], + (m, f) <- [("M-", W.view), ("M-S-", W.shift), ("M-C-", copy)] + ] + +myMouse c = + [ ((modM, button1), + (\w -> focus w >> mouseMoveWindow w >> snapMagicMove (Just 50) (Just 50) w)) + + , ((modM .|. shiftMask, button1), + (\w -> focus w >> mouseMoveWindow w >> snapMagicMouseResize 0.8 (Just 50) (Just 50) w)) + + , ((modM, button3), + (\w -> focus w >> Flex.mouseWindow Flex.resize w)) + ] + +-- +-- Layout +-- +myLayout = + avoidStruts + $ smartBorders + $ Mag.magnifierOff + $ trackFloating + + $ onWorkspace "2:mail" layoutsTabbed + $ onWorkspace "4:im" (imgrid ||| imtab ||| immosaic) + $ onWorkspace "5:code" layoutsTabbed + $ onWorkspace "video" (noBorders tabbed) + $ onWorkspace "gimp" gimp + $ layouts + where + layouts = tiled ||| Mirror tiled ||| ThreeColMid 1 (3/100) (1/2) ||| tabbed + layoutsTabbed = tabbed ||| tiled ||| Mirror tiled ||| ThreeColMid 1 (3/100) (1/2) + tiled = Tall 1 (3/100) (1/2) + gimp = named "gimp" + $ withIM (0.11) (Role "gimp-toolbox") + $ reflectHoriz + $ withIM (0.15) (Role "gimp-dock") (trackFloating tabbed) + tabbed = named "Tabbed" + $ tabbedBottom shrinkText alexTheme + imbase a = withIM (1%7) (Or (ClassName "Tkabber") (Role "roster")) a + imgrid = imbase Grid + imtab = imbase tabbed + immosaic = imbase $ MosaicAlt M.empty -- cgit v1.2.3