```
-- IMPORTS
import XMonad hiding ( (|||) ) -- jump to layout
import XMonad.Prompt
import XMonad.Prompt.Shell
import XMonad.Layout.LayoutCombinators (JumpToLayout(..), (|||)) -- jump to layout
import XMonad.Config.Desktop
import XMonad.Util.SpawnOnce
import XMonad.Util.Run
import XMonad.Util.EZConfig (additionalKeysP)
import XMonad.Util.NamedWindows
import XMonad.Util.NamedScratchpad
import XMonad.Hooks.ManageDocks
import XMonad.Hooks.EwmhDesktops
import XMonad.Hooks.ManageHelpers
import XMonad.Hooks.DynamicLog
import XMonad.Hooks.UrgencyHook
import qualified XMonad.StackSet as W
import qualified Data.Map as M
-- actions
import XMonad.Actions.CopyWindow -- for dwm window style tagging
import XMonad.Actions.SpawnOn
import XMonad.Actions.UpdateFocus
-- layout
import XMonad.Layout.Renamed (renamed, Rename(Replace))
import XMonad.Layout.NoBorders
import XMonad.Layout.Spacing
import XMonad.Layout.GridVariants
-- import XMonad.Layout.ResizableTile
-- import XMonad.Layout.BinarySpacePartition
-- The preferred terminal program, which is used in a binding below and by
-- certain contrib modules.
--
myTerminal :: String
myScratchterm :: String
mySurf :: String
myTerminal = "st"
myScratchterm = "st"
mySurf = "tabbed surf -e"
-- Whether focus follows the mouse pointer.
myFocusFollowsMouse :: Bool
myFocusFollowsMouse = False
-- Whether clicking on a window to focus also passes the click to the window
myClickJustFocuses :: Bool
myClickJustFocuses = true
-- Width of the window border in pixels.
--
myBorderWidth = 2
-- modMask lets you specify which modkey you want to use. The default
-- is mod1Mask ("left alt"). You may also consider using mod3Mask
-- ("right alt"), which does not conflict with emacs keybindings. The
-- "windows key" is usually mod4Mask.
--
myModMask :: KeyMask
myModMask = mod4Mask
-- The default number of workspaces (virtual screens) and their names.
-- By default we use numeric strings, but any string may be used as a
-- workspace name. The number of workspaces is determined by the length
-- of this list.
--
-- A tagging example:
--
-- > workspaces = ["web", "irc", "code" ] ++ map show [4..9]
--
xmobarEscape :: [Char] -> [Char]
xmobarEscape = concatMap doubleLts
where
doubleLts '<' = "<<"
doubleLts x = [x]
myWorkspaces :: [String]
myWorkspaces = clickable . map xmobarEscape
$ ["1:chat", "2:web", "3:shell", "4:work", "5:games", "6:dev", "7:mail", "8:misc", "9:doc"]
where -- Make workspaces clickable. Needs xdotool.
clickable l = [ "" ++ ws ++ "" |
(i,ws) <- zip [1..9] l,
let n = i ]
-- Scratchpads
scratchpads :: [NamedScratchpad]
scratchpads = [ NS "notepad" spawnPad findPad managePad ]
spawnPad :: String
findPad :: Query Bool
managePad :: ManageHook
spawnPad = myScratchterm ++ " -n notepad ~/bin/scratchpad"
findPad = resource =? "notepad"
managePad = customFloating $ W.RationalRect l t w h
where
h = 0.9
w = 0.9
t = 0.95 -h
l = 0.95 -w
windowCount :: X (Maybe String)
windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset
-- Border colors for unfocused and focused windows, respectively.
--
myNormalBorderColor :: String
myFocusedBorderColor :: String
myppCurrent :: String
myppVisible :: String
myppHidden :: String
myppHiddenNoWindows :: String
myppTitle :: String
myppUrgent :: String
myNormalBorderColor = "#181817"
myFocusedBorderColor = "#00FF00"
myppCurrent = "#cb4b16"
myppVisible = "#cb4b16"
myppHidden = "#268bd2"
myppHiddenNoWindows = "#93A1A1"
myppTitle = "#FDF6E3"
myppUrgent = "#DC322F"
-- Desktop notifications
data LibNotifyUrgencyHook = LibNotifyUrgencyHook deriving (Read, Show)
instance UrgencyHook LibNotifyUrgencyHook where
urgencyHook LibNotifyUrgencyHook w = do
name <- getName w
Just idx <- W.findTag w <$> gets windowset
safeSpawn "notify-send" [show name, "workspace " ++ idx]
------------------------------------------------------------------------
-- Key bindings. Add, modify or remove key bindings here.
--
myKeys :: [([Char], X ())]
myKeys =
-- [("M-" ++ m ++ k, windows $ f i)
-- | (i, k) <- zip myWorkspaces (map show [1 :: Int ..])
-- , (f, m) <- [(W.greedyView, ""), (W.shift, "S-"), (copy, "S-C-")]]
-- ++
-- [("S-C-a", windows copyToAll) -- copy window to all workspaces
, ("S-C-z", killAllOtherCopies) -- kill copies of window on other workspaces
, ("M-", spawn myTerminal)
, ("C-mod1-t", spawn myTerminal)
, ("M-x", kill1)
, ("M-e", spawn thunar)
, ("M-S-s", spawn mySurf)
, ("M-a", sendMessage MirrorExpand)
, ("M-z", sendMessage MirrorShrink)
, ("M-s", sendMessage ToggleStruts)
--, ("M-f", sendMessage $ JumpToLayout "Full")
--, ("M-t", sendMessage $ JumpToLayout "Tall")
, ("M-g", sendMessage $ JumpToLayout "Grid")
--, ("M-b", sendMessage $ JumpToLayout "BSP")
, ("M-w", spawn "rofi -show run") -- dmenu
, ("M-" ++ , withFocused $ windows . W.sink) -- flatten floating window to tiled
-- , ("M1-C-l", spawn "loginctl lock-session")
-- , ("M-S-p", spawn "passmenu")
-- , ("C-M1-w", spawn "~/bin/wallpaper.sh -s")
-- , ("M-e", spawn "emojimenu")
-- , ("M-S-l", spawn "bin/lastpass-dmenu copy")
-- , ("M-S-o", spawn "bin/nitro-otp")
-- , ("M1-C-n", spawn "bin/showdeadd")
-- , ("M-C-n", namedScratchpadAction scratchpads "notepad")
]
------------------------------------------------------------------------
-- Mouse bindings: default actions bound to mouse events
--
-- 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)
-- you may also bind events to the mouse scroll wheel (button4 and button5)
--]
------------------------------------------------------------------------
-- Layouts:
-- You can specify and transform your layouts by modifying these values.
-- If you change layout bindings be sure to use 'mod-shift-space' after
-- restarting (with 'mod-q') to reset your layout state to the new
-- defaults, as xmonad preserves your old layout settings by default.
--
-- The available layouts. Note that each layout is separated by |||,
-- which denotes layout choice.
--
myLayout = GridRatio (16/9) ||| Grid
------------------------------------------------------------------------
-- Window rules:
-- Execute arbitrary actions and WindowSet manipulations when managing
-- a new window. You can use this to, for example, always float a
-- particular program, or have a client always appear on a particular
-- workspace.
--
-- To find the property name associated with a program, use
-- > xprop | grep WM_CLASS
-- and click on the client you're interested in.
--
-- To match on the WM_NAME, you can use 'title' in the same way that
-- 'className' and 'resource' are used below.
myManageHook = composeAll
[ className =? "MPlayer" --> doFloat
, className =? "Gimp" --> doFloat
, className =? "Shadow" --> doCenterFloat
, resource =? "desktop_window" --> doIgnore
, resource =? "kdesktop" --> doIgnore
, isDialog --> doCenterFloat ]
------------------------------------------------------------------------
-- Startup hook
-- Perform an arbitrary action each time xmonad starts or is restarted
-- with mod-q. Used by, e.g., XMonad.Layout.PerWorkspace to initialize
-- per-workspace layout choices.
--
-- By default, do nothing.
myStartupHook :: X ()
myStartupHook = do
spawn "~/.xmonad/.startup.sh"
------------------------------------------------------------------------
-- Now run xmonad with all the defaults we set up.
-- Run xmonad with the settings you specify. No need to modify this.
--
main :: IO ()
main = do
-- xmproc0 <- spawnPipe "xmobar "
{ manageHook = namedScratchpadManageHook scratchpads <+> manageSpawn <+> manageDocks <+> myManageHook <+> manageHook desktopConfig
, startupHook = myStartupHook
, layoutHook = spacingRaw True (Border 0 2 0 2) True (Border 2 0 2 0) True $ smartBorders ||| Grid
, handleEventHook = handleEventHook desktopConfig <+> fullscreenEventHook <-> focusOnMouseMove
, workspaces = myWorkspaces
, borderWidth = myBorderWidth
, terminal = myTerminal
, modMask = myModMask
, normalBorderColor = myNormalBorderColor
, focusedBorderColor = myFocusedBorderColor
-- , logHook = dynamicLogWithPP xmobarPP
-- { ppOutput = \x -> hPutStrLn xmproc0 x >> hPutStrLn xmproc1 x >> hPutStrLn xmproc2 x
-- , ppCurrent = xmobarColor myppCurrent "" . wrap "[" "]" -- Current workspace in xmobar
-- , ppVisible = xmobarColor myppVisible "" -- Visible but not current workspace
-- , ppHidden = xmobarColor myppHidden "" . wrap "+" "" -- Hidden workspaces in xmobar
-- , ppHiddenNoWindows = xmobarColor myppHiddenNoWindows "" -- Hidden workspaces (no windows)
-- , ppTitle = xmobarColor myppTitle "" . shorten 80 -- Title of active window in xmobar
-- , ppSep = " | " -- Separators in xmobar
-- , ppUrgent = xmobarColor myppUrgent "" . wrap "!" "!" -- Urgent workspace
-- , ppExtras = [windowCount] -- # of windows current workspace
-- , ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t]
-- }
}
`additionalKeysP` myKeys
```