import XMonad import XMonad.Config.Desktop import XMonad.Actions.CycleWS import XMonad.Actions.NoBorders import XMonad.Actions.PhysicalScreens import XMonad.Actions.Warp import XMonad.Hooks.ManageDocks import XMonad.Hooks.ManageHelpers import XMonad.Hooks.SetWMName import XMonad.Layout.ResizableTile import qualified XMonad.StackSet as W import XMonad.Util.EZConfig import Control.Monad import Control.Monad.Trans import Data.Maybe import Data.Monoid import Data.Ratio((%)) import System.Exit --import ConfigurableBorders import DynamicPerScreenWorkspaces import EwmhDesktops import FullscreenManager import NoBorders import ProcessWorkspaces modm = mod4Mask main = xmonad $ ewmh dwConfig $ defaultConfig { modMask = modm , manageHook = myManageHook , layoutHook = desktopLayoutModifiers myLayoutHook , startupHook = myStartupHook , handleEventHook = myEventHook , logHook = ewmhDesktopsLogHook , focusedBorderColor = "#008000" , rescreenHook = dynamicRescreenHook dwConfig , borderWidth = 0 } `additionalKeysP` ( [ ("M-a", sendMessage MirrorShrink) , ("M-z", sendMessage MirrorExpand) , ("M-", prevWS) , ("M-", nextWS) , ("M-S-", shiftToPrev) , ("M-S-", shiftToNext) , ("M-S-b", withFocused toggleBorder >> refresh) , ("M-", viewOrWarp 0) , ("M-", viewOrWarp 1) , ("M-", viewOrWarp 2) , ("M-b", banishScreen LowerRight) , ("M-f", withFocused $ \w -> windows $ W.float w $ W.RationalRect 0 0 1 1) , ("M-p", spawnOnCurrent "/home/neoraider/bin/dmemu_run -b") , ("M-g", gets (W.currentTag . windowset) >>= regroupProcess) , ("M-S-q", io (exitWith ExitSuccess)) , ("C-M1-l", spawn "xscreensaver-command -lock") , ("M-`", spawn "xclip -o | qrencode -s 10 -o- | display -geometry +0+0") , ("", spawn "amixer -q sset Master 5%- unmute") , ("", spawn "amixer -q sset Master toggle") , ("", spawn "amixer -q sset Master 5%+ unmute") , ("M1-", kill) ] ++ [ ("M-" ++ show n, view dwConfig ws) | (ws, n) <- zip [0..] ([1..9]++[0])] ++ [ ("M-C-" ++ show n, viewOnCurrent dwConfig ws) | (ws, n) <- zip [0..] ([1..9]++[0])] ++ [ ("M-S-" ++ show n, create dwConfig ws >> shiftGroup (workspaceTag dwConfig ws) >> cleanup) | (ws, n) <- zip [0..] ([1..9]++[0])] ++ [ ("M-S-C-" ++ show n, create dwConfig ws >> shiftIgnoreGroup (workspaceTag dwConfig ws) >> cleanup) | (ws, n) <- zip [0..] ([1..9]++[0])] ) `additionalMouseBindings` [ ((modm, button4), \_ -> sendMessage Shrink) , ((modm, button5), \_ -> sendMessage Expand) , ((modm .|. shiftMask, button4), \_ -> sendMessage MirrorExpand) , ((modm .|. shiftMask, button5), \_ -> sendMessage MirrorShrink) ] dwConfig :: DynamicWorkspaceConfig dwConfig = DynamicWorkspaceConfig { defaultWorkspaceScreen = defWSScreen , workspaceTag = show . (+1) } defWSScreen :: WorkspaceScreens defWSScreen 1 _ = S 0 defWSScreen _ i | i `elem` [0..7] = S 0 defWSScreen _ i | i `elem` [8,9] = S 1 defWSScreen n i = S ((i-10) `mod` n) viewOrWarp :: Int -> X () viewOrWarp n = do wset <- gets windowset i <- getScreen $ P n whenJust i $ \s -> do ws <- screenWorkspace s whenJust ws $ \w -> windows . W.view $ w when (s == (W.screen . W.current $ wset)) $ warpToScreen s (1%2) (1%2) setFullscreenSupported :: X () setFullscreenSupported = withDisplay $ \dpy -> do r <- asks theRoot a <- getAtom "_NET_SUPPORTED" c <- getAtom "ATOM" f <- getAtom "_NET_WM_STATE_FULLSCREEN" io $ changeProperty32 dpy r a c propModeAppend [fromIntegral f] myStartupHook :: X () myStartupHook = do startupHook desktopConfig setWMName "LG3D" setFullscreenSupported isUtility :: Query Bool isUtility = isInProperty "_NET_WM_WINDOW_TYPE" "_NET_WM_WINDOW_TYPE_UTILITY" stackHook :: (Window -> W.Stack Window -> W.Stack Window) -> ManageHook stackHook f = ask >>= \w -> doF $ \s -> s { W.current = mapScreen w (W.current s) , W.visible = map (mapScreen w) (W.visible s) , W.hidden = map (mapWorkspace w) (W.hidden s) } where mapWorkspace w ws = ws { W.stack = fmap (f w) $ W.stack ws } mapScreen w scr = scr { W.workspace = mapWorkspace w (W.workspace scr) } moveDown1 :: ManageHook moveDown1 = stackHook down where down w (W.Stack c u (d:dx)) | c == w = W.Stack c (d:u) dx down _ stack = stack moveUp1 :: ManageHook moveUp1 = stackHook up where up w (W.Stack c (u:ux) d) | c == w = W.Stack c ux (u:d) up _ stack = stack myManageHook :: ManageHook myManageHook = composeAll [ isDialog --> doFloat , composeOne [ className =? "Guake.py" -?> doFloatMaybeFullscreen -- <+> doConfigBorderOff) --, className =? "Do" -?> (doFloat <+> doConfigBorderOff) , className =? "MPlayer" -?> doCenterFloat , className =? "mplayer2" -?> doCenterFloat , className =? "Gnome-session" -?> doIgnoreProcessWorkspace --, className =? "Gimp" -?> doFloat , className =? "jrummikub-JRummikub" -?> doFloat , className =? "Stjerm" -?> doFloatMaybeFullscreen , className =? "Display" -?> doFloat , className =? "Dwarf_Fortress" -?> doFloat , className =? "Wine" -?> doFloat , className =? "Pcsx2" -?> doFloat , stringProperty "WM_ICON_NAME" =? "ZZogl-pg" -?> doFloat , isFullscreen -?> doFullscreen ] , isUtility =? False --> doAutoShift , manageHook desktopConfig ] --myUnmanageHook :: ManageHook --myUnmanageHook = moveUp1 myLayoutHook = screenWorkspaceStorage $ processWorkspaceManager $ manageFullscreen {- $ smartBorders -} (Full ||| tiled ||| Mirror tiled) where -- default tiling algorithm partitions the screen into two panes tiled = ResizableTall nmaster delta ratio [] -- The default number of windows in the master pane nmaster = 1 -- Default proportion of screen occupied by master pane ratio = 3/5 -- Percent of screen to increment by when resizing panes delta = 3/100 myEventHook :: Event -> X All myEventHook ev = do handleForgetEmptyWindowGroups ev handleFullscreen ev handleEventHook defaultConfig ev