guest@dotshare [~/groups/wms/xmonad] $ ls XMonad-2015/ | cat

XMonad 2015 (scrot)

monad Aug 20, 2015 (wms/xmonad)

xmonad.hs(raw, dl)

SCROT

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
-- xmonad core
import XMonad hiding ( (|||) )

-- hooks
import XMonad.Hooks.SetWMName                    -- EWMH
import XMonad.Hooks.EwmhDesktops                 -- EWMH
import XMonad.Hooks.ManageDocks                  -- avoidStruts
import XMonad.Hooks.DynamicLog                   -- dynamicLogWithPP

-- layouts
import XMonad.Layout.PerWorkspace (onWorkspace)  -- diff. tag diff. layout
import XMonad.Layout.LayoutCombinators           -- ||, managehooks
import XMonad.Layout.Grid                        -- grid layout
import XMonad.Layout.Spacing                     -- spacing
import XMonad.Layout.ResizableTile               -- ResizableTall
import XMonad.Layout.SimpleFloat                 -- simpleFloat, floating layout

-- utils
import XMonad.Util.Run (spawnPipe)               -- does what is says
import XMonad.Util.Cursor                        -- setDefaultCursor

-- my lib/modules.hs
import Config
import Windows
import Bindings
import Workspaces

-- XMonad
main = do
    panel <- spawnPipe dzenCMD
    xmonad $ defaultConfig { terminal  = myTerm,          -- terminal client
        focusFollowsMouse  = True,                        -- focus follows the mouse pointer
        clickJustFocuses   = False,                       -- Whether clicking on a window to focus also passes the click to the window
        borderWidth        = 1,                           -- Width of the window border in pixels.
        modMask            = mod1Mask,                    -- left alt to do all the heavy work
        workspaces         = myTags,                      -- number of tags/workspaces
        normalBorderColor  = brown,                       -- unfocused border colour
        focusedBorderColor = blue,                        -- focused border colour

        -- key bindings
        keys               = myKeys,
        mouseBindings      = myMouseBindings,

        -- hooks, layouts
        layoutHook         = myLayout,
        manageHook         = manageDocks <+> myManageHook <+> dropdownTerminal <+> manageHook defaultConfig,
        handleEventHook    = mempty,
        logHook            = dynamicLogWithPP $ myPP panel,
        startupHook        = setDefaultCursor xC_left_ptr <+>  ewmhDesktopsStartup >> setWMName "Xmonad"
    }


-- layouts
myLayout =
    avoidStrutsOn [U] -- avoid statusbar overlapping
        $ onWorkspace tag1 floaT
        $ onWorkspace tag2 tiled
        $ standardLayouts
    where
        standardLayouts = tiled ||| mtiled ||| Grid ||| floaT
        floaT   = simpleFloat
        tiled1  = Tall nmaster delta ratio
        mtiled  = Mirror tiled1
        tiled   = spacing 5  $ ResizableTall nmaster delta ratio []
        nmaster = 1       -- The default number of windows in the master pane
        ratio   = 1/2     -- Default proportion of screen occupied by master pane
        delta   = 3/100   -- Percent of screen to increment by when resizing panes

CLICK TO VIEW

x

lib_Workspaces.hs(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
module Workspaces where

import XMonad.Hooks.DynamicLog       -- hooks (PP*, dzenColor)
import XMonad.Util.Run (hPutStrLn)   -- utils, does what is says
import Config                        -- my module

-- iconify the current layout
myPP h = defaultPP
    { ppCurrent         = wrapDzenBlue
    , ppVisible         = wrapDzenBlue
    , ppHidden          = wrapHiddenTerm
    , ppHiddenNoWindows = wrapHiddenTerm
    , ppUrgent          = wrapDzenWhite
    , ppSep             = " "
    , ppWsSep           = lightgrayfg ++ " | "
    , ppTitle           = dzenColor (darkgray) "" -- hide window title with darker colour
    , ppLayout          = wrapDzenBrown .
    (\x -> case x of
        "Tall"                       -> wrapBitmap "tile.xbm"
        "Mirror Tall"                -> wrapBitmap "nbstack.xbm"
        "Grid"                       -> wrapBitmap "grid.xbm"
        "Spacing 5 ResizableTall"    -> wrapBitmap "tile.xbm"
        "Simple Float"               -> wrapBitmap "float.xbm"
        _ -> x
    )
    , ppOutput = hPutStrLn h
    }
    where
        wrapBitmap bitmap = lightgrayfg ++ "| " ++ bluefg ++ icondir ++ "ws/" ++ bitmap ++ ")"
        wrapDzenWhite     = dzenColor (white) (brown)
        wrapDzenBrown     = dzenColor (brown) ""
        wrapDzenBlue      = dzenColor (blue) (darkgray)
        wrapHiddenTerm    = wrapDzenBrown . hideDropdownTerm
        hideDropdownTerm ws = if ws == "NSP" then "" else ws

-- tags/workspaces
tag1   = "web"
tag2   = "dev"
tag3   = "misc"
myTags = [tag1, tag2, tag3]
 

x

lib_Windows.hs(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
module Windows where

import XMonad hiding ( (|||) )         -- xmonad core
import qualified XMonad.StackSet as W  -- xmonad core
import XMonad.Hooks.ManageHelpers      -- hooks (doCenterFloat)
import XMonad.Util.Scratchpad          -- scratchpadManageHook
import Workspaces                      -- my module
import Config                          -- my module

-- window rules
myManageHook = composeAll . concat $
    [ [isDialog        --> doCenterFloat'                ]    -- Dont hide the dialogues behind their parent
    , [className  =? c --> doFloat       | c <- myJFloats]    -- Just float
    , [className  =? c --> doCenterFloat' | c <- myCFloats]   -- Center float
    , [title      =? t --> doFloat       | t <- myTFloats]
    , [resource   =? r --> doFloat       | r <- myRFloats]
    , [resource   =? i --> doIgnore      | i <- myIgnores]
    , [(className =? x <||> title =? x <||> resource =? x) --> doShift tag1 | x <- my1Shifts]        -- send the given program to this tag
    , [(className =? x <||> title =? x <||> resource =? x) --> doShiftAndGo tag3 | x <- my3Shifts]  -- send the given program to this tag
    ]
    where
        doMaster  = doF W.shiftMaster -- new floating windows goes on top
        doCenterFloat' = doCenterFloat <+> doMaster
        doShiftAndGo ws = doF (W.greedyView ws) <+> doShift ws
        myJFloats = ["Tor Browser"]
        myCFloats = ["Vlc", "Thunar", "Wine", "Qbittorrent", "Sxiv"] -- press alt+t to switch the floating layout with other
        myTFloats = []
        myRFloats = []
        myIgnores = ["xmobar","dzen","dzen2","desktop_window","kdesktop"]
        my1Shifts = ["Tor Browser"]
        my3Shifts = ["Qbittorrent", "Wine", "Gimp-2.8", "Gimp"]

-- mimic G/Quake
dropdownTerminal = scratchpadManageHook(W.RationalRect l t w h)
    where
        h = 0.4       -- terminal height 40%
        w = 0.5       -- terminal width 50%
        t = 0.015     -- distance from top edge 1.5%
        l = 0.25      -- distance from left edge 25%
 

x

lib_Bindings.hs(raw, dl)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
module Bindings where

import System.Exit                     -- haskell modules
import qualified Data.Map as M         -- haskell modules
import XMonad                          -- xmonad core
import qualified XMonad.StackSet as W  -- xmonad core
import XMonad.Actions.FloatKeys        -- actions (keyResizeWindow)
import XMonad.Actions.FloatSnap        -- actions (snapMove)
import XMonad.Prompt                   -- prompt actions
import XMonad.Prompt.Shell             -- prompt actions
import Config                          -- my module
import XMonad.Util.Scratchpad          -- scratchpadSpawnActionTerminal

-- key bindings
myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $
    [
    -- launch dmenu
      ((modm,               xK_p     ), shellPrompt mXPConfig)
    -- close focused window
    , ((modm,               xK_c     ), kill)
     -- Rotate through the available layout algorithms
    , ((modm,               xK_space ), sendMessage NextLayout)
    --  Reset the layouts on the current workspace to default
    , ((modm .|. shiftMask, xK_space ), setLayout $ XMonad.layoutHook conf)
    -- Resize viewed windows to the correct size
    , ((modm,               xK_n     ), refresh)
    -- Move focus to the next window
    , ((modm,               xK_Tab   ), windows W.focusDown)
    -- Move focus to the next window
    , ((modm,               xK_j     ), windows W.focusDown)
    -- Move focus to the previous window
    , ((modm,               xK_k     ), windows W.focusUp  )
    -- Move focus to the master window
    , ((modm,               xK_m     ), windows W.focusMaster  )
    -- Swap the focused window and the master window
    , ((modm,               xK_Return), windows W.swapMaster)
    -- Swap the focused window with the next window
    , ((modm .|. shiftMask, xK_j     ), windows W.swapDown  )
    -- Swap the focused window with the previous window
    , ((modm .|. shiftMask, xK_k     ), windows W.swapUp    )
    -- Shrink the master area
    , ((modm,               xK_h     ), sendMessage Shrink)
    -- Expand the master area
    , ((modm,               xK_l     ), sendMessage Expand)
    -- Push all windows in the current workspace/tag back into tiling (press alt+t and cycle between different layouts to see it in action. It's also useful for floating layout where other windows are stealing focus
    , ((modm,               xK_t     ), gets (M.keys . W.floating . windowset) >>= mapM_ (windows . W.sink))
    -- Increment the number of windows in the master area
    , ((modm              , xK_comma ), sendMessage (IncMasterN 1))
    -- Deincrement the number of windows in the master area
    , ((modm              , xK_period), sendMessage (IncMasterN (-1)))
    -- Quit xmonad
    , ((modm .|. shiftMask, xK_q     ), io (exitWith ExitSuccess))
    -- Restart xmonad
    , ((modm              , xK_q     ), spawn "xmonad --recompile; xmonad --restart")




    -- User defined actions

    -- move window to the right, left, up, down
    , ((modm,                 xK_KP_Left   ), withFocused $ snapMove L Nothing)
    , ((modm,                 xK_KP_Right  ), withFocused $ snapMove R Nothing)
    , ((modm,                 xK_KP_Up     ), withFocused $ snapMove U Nothing)
    , ((modm,                 xK_KP_Down   ), withFocused $ snapMove D Nothing)
    , ((modm,                 xK_KP_End    ), withFocused (keysMoveWindowTo (1355,1075) (0,1))) -- position my (floating) terminal window in the bottom right corner (browser to the left, terminal to the right)

    , ((modm,   xK_Left   ), withFocused (keysMoveWindow (-50,0)))
    , ((modm,   xK_Right  ), withFocused (keysMoveWindow (50,0)))
    , ((modm,   xK_Up     ), withFocused (keysMoveWindow (0,-50)))
    , ((modm,   xK_Down   ), withFocused (keysMoveWindow (0,50)))



    -- dynamic window resizing, no matter what layout is used
    , ((modm .|. shiftMask,   xK_Left   ), withFocused (keysResizeWindow (-50,0) (0,0)))
    , ((modm .|. shiftMask,   xK_Right  ), withFocused (keysResizeWindow (50,0) (0,0)))
    , ((modm .|. shiftMask,   xK_Up     ), withFocused (keysResizeWindow (0,-50) (0,0)))
    , ((modm .|. shiftMask,   xK_Down   ), withFocused (keysResizeWindow (0,50) (0,0)))



    -- User defined commands

    , ((mod4Mask          , xK_x        ), spawn "urxvtc")
    , ((mod4Mask          , xK_z        ), scratchpadSpawnActionTerminal myTerm)
    , ((mod4Mask          , xK_t        ), spawn "thunar")
    , ((mod4Mask          , xK_s        ), spawn "tor-browser-en --dir=/tmp")
    , ((mod4Mask          , xK_q        ), spawn "qbittorrent")
    , ((modm              , xK_Print    ), spawn "scrot")

    ]
    ++

    --
    -- mod-[1..9], Switch to workspace N
    -- mod-shift-[1..9], Move client to workspace N
    --
    [((m .|. modm, k), windows $ f i)
        | (i, k) <- zip (XMonad.workspaces conf) [xK_1 .. xK_9]
        , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)]]
    ++

    --
    -- mod-{w,e,r}, Switch to physical/Xinerama screens 1, 2, or 3
    -- mod-shift-{w,e,r}, Move client to screen 1, 2, or 3
    --
    [((m .|. modm, key), screenWorkspace sc >>= flip whenJust (windows . f))
        | (key, sc) <- zip [xK_w, xK_e, xK_r] [0..]
        , (f, m) <- [(W.view, 0), (W.shift, shiftMask)]]

-- Mouse bindings
myMouseBindings (XConfig {XMonad.modMask = modm}) = M.fromList $
    -- mod-button1, Set the window to floating mode and move by dragging
    [ ((modm, button1), (\w -> focus w >> mouseMoveWindow w
                                       >> windows W.shiftMaster))
    -- mod-button2, Raise the window to the top of the stack
    , ((modm, button2), (\w -> focus w >> windows W.shiftMaster))
    -- mod-button3, Set the window to floating mode and resize by dragging
    , ((modm, button3), (\w -> focus w >> mouseResizeWindow w
                                       >> windows W.shiftMaster))
    ]
 

x

lib_Config.hs(raw, dl)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module Config where

-- xmonad core, prompt actions
import XMonad
import XMonad.Prompt

-- default colours
brown         = "#333333"
white         = "#ffffff"
blue          = "#306eff"
bluefg        = "^fg("++ blue ++")"
darkgray      = "#222222"
darkbrown     = "#111111"
lightgray     = "#333333"
lightgrayfg   = "^fg("++ lightgray ++")"

-- dmenu configuration
mXPConfig = defaultXPConfig
    { font                  = "xft:Terminus:size=10:antialias=true"
    , bgColor               = darkbrown
    , fgColor               = blue
    , bgHLight              = blue
    , fgHLight              = darkbrown
    , promptBorderWidth     = 0
    , position              = Bottom
    , height                = 22
    , historyFilter         = deleteConsecutive
    , historySize           = 50
    , completionKey         = xK_Tab
    }

-- icons path, dzen command to be executed, terminal
icondir = "^i(/home/frost/.xmonad/icons/"
dzenCMD = "dzen2 -ta l -x 0 -y 0 -w 220 -fn -*-fixed-medium-r-*-*-12-*-*-*-*-*-iso8859-* -fg "++ white ++" -bg "++ brown ++""
myTerm  = "urxvtc"
 

x

Notes

The statusbar is written by me - https://github.com/wifiextender/dwm-bar, it works in dwm and XMonad. Basic programming knowledge is required if you decide to tweak it. The icons are XBM, use your favourite search engine to find them. There are plenty of github repositories that contain them. This is my first week as XMonad user, came from dwm.

Comments

monad said about 9 years ago

Forgot to mention that the G/Quake drop down like terminal is executed and hidden by meta+z

monad said about 9 years ago

All *.hs files except xmonad.hs goes to $HOME/.xmonad/lib/ , not sure why they was renamed to lib_blah.hs instead lib/blah.hs