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
|
x
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
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
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
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.
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