summaryrefslogtreecommitdiff
path: root/.config/xmonad
diff options
context:
space:
mode:
Diffstat (limited to '.config/xmonad')
-rw-r--r--.config/xmonad/xmonad.hs722
1 files changed, 722 insertions, 0 deletions
diff --git a/.config/xmonad/xmonad.hs b/.config/xmonad/xmonad.hs
new file mode 100644
index 0000000..9112951
--- /dev/null
+++ b/.config/xmonad/xmonad.hs
@@ -0,0 +1,722 @@
+ -- Base
+import XMonad
+import System.Directory
+import System.IO (hClose, hPutStr, hPutStrLn)
+import System.Exit (exitSuccess)
+import qualified XMonad.StackSet as W
+
+ -- Actions
+import XMonad.Actions.CopyWindow (kill1)
+import XMonad.Actions.CycleWS (Direction1D(..), moveTo, shiftTo, WSType(..), nextScreen, prevScreen)
+import XMonad.Actions.GridSelect
+import XMonad.Actions.MouseResize
+import XMonad.Actions.Promote
+import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown)
+import XMonad.Actions.WindowGo (runOrRaise)
+import XMonad.Actions.WithAll (sinkAll, killAll)
+import qualified XMonad.Actions.Search as S
+
+ -- Data
+import Data.Char (isSpace, toUpper)
+import Data.Maybe (fromJust)
+import Data.Monoid
+import Data.Maybe (isJust)
+import Data.Tree
+import qualified Data.Map as M
+
+ -- Hooks
+import XMonad.Hooks.DynamicLog (dynamicLogWithPP, wrap, xmobarPP, xmobarColor, shorten, PP(..))
+import XMonad.Hooks.EwmhDesktops -- for some fullscreen events, also for xcomposite in obs.
+import XMonad.Hooks.ManageDocks (avoidStruts, docks, manageDocks, ToggleStruts(..))
+import XMonad.Hooks.ManageHelpers (isFullscreen, doFullFloat, doCenterFloat)
+import XMonad.Hooks.ServerMode
+import XMonad.Hooks.SetWMName
+import XMonad.Hooks.StatusBar
+import XMonad.Hooks.StatusBar.PP
+import XMonad.Hooks.WindowSwallowing
+import XMonad.Hooks.WorkspaceHistory
+
+ -- Layouts
+import XMonad.Layout.Accordion
+import XMonad.Layout.GridVariants (Grid(Grid))
+import XMonad.Layout.SimplestFloat
+import XMonad.Layout.Spiral
+import XMonad.Layout.ResizableTile
+import XMonad.Layout.Tabbed
+import XMonad.Layout.ThreeColumns
+
+ -- Layouts modifiers
+import XMonad.Layout.LayoutModifier
+import XMonad.Layout.LimitWindows (limitWindows, increaseLimit, decreaseLimit)
+import XMonad.Layout.MultiToggle (mkToggle, single, EOT(EOT), (??))
+import XMonad.Layout.MultiToggle.Instances (StdTransformers(NBFULL, MIRROR, NOBORDERS))
+import XMonad.Layout.NoBorders
+import XMonad.Layout.Renamed
+import XMonad.Layout.ShowWName
+import XMonad.Layout.Simplest
+import XMonad.Layout.Spacing
+import XMonad.Layout.SubLayouts
+import XMonad.Layout.WindowArranger (windowArrange, WindowArrangerMsg(..))
+import XMonad.Layout.WindowNavigation
+import qualified XMonad.Layout.ToggleLayouts as T (toggleLayouts, ToggleLayout(Toggle))
+import qualified XMonad.Layout.MultiToggle as MT (Toggle(..))
+
+ -- Utilities
+import XMonad.Util.Dmenu
+import XMonad.Util.EZConfig (additionalKeysP, mkNamedKeymap)
+import XMonad.Util.NamedActions
+import XMonad.Util.NamedScratchpad
+import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe)
+import XMonad.Util.SpawnOnce
+
+ -- ColorScheme module (SET ONLY ONE!)
+ -- Possible choice are:
+ -- DoomOne
+ -- Dracula
+ -- GruvboxDark
+ -- MonokaiPro
+ -- Nord
+ -- OceanicNext
+ -- Palenight
+ -- SolarizedDark
+ -- SolarizedLight
+ -- TomorrowNight
+import Colors.DoomOne
+
+myFont :: String
+myFont = "xft:SauceCodePro Nerd Font Mono:regular:size=9:antialias=true:hinting=true"
+
+myModMask :: KeyMask
+myModMask = mod4Mask -- Sets modkey to super/windows key
+
+myTerminal :: String
+myTerminal = "alacritty" -- Sets default terminal
+
+myBrowser :: String
+myBrowser = "qutebrowser " -- Sets qutebrowser as browser
+
+myEmacs :: String
+myEmacs = "emacsclient -c -a 'emacs' " -- Makes emacs keybindings easier to type
+
+myEditor :: String
+myEditor = "emacsclient -c -a 'emacs' " -- Sets emacs as editor
+-- myEditor = myTerminal ++ " -e vim " -- Sets vim as editor
+
+myBorderWidth :: Dimension
+myBorderWidth = 2 -- Sets border width for windows
+
+myNormColor :: String -- Border color of normal windows
+myNormColor = colorBack -- This variable is imported from Colors.THEME
+
+myFocusColor :: String -- Border color of focused windows
+myFocusColor = color15 -- This variable is imported from Colors.THEME
+
+mySoundPlayer :: String
+mySoundPlayer = "ffplay -nodisp -autoexit " -- The program that will play system sounds
+
+windowCount :: X (Maybe String)
+windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset
+
+myStartupHook :: X ()
+myStartupHook = do
+ spawnOnce (mySoundPlayer ++ startupSound)
+ spawn "killall conky" -- kill current conky on each restart
+ spawn "killall trayer" -- kill current trayer on each restart
+
+ spawnOnce "lxsession"
+ spawnOnce "picom"
+ spawnOnce "nm-applet"
+ spawnOnce "volumeicon"
+ spawn "/usr/bin/emacs --daemon" -- emacs daemon for the emacsclient
+
+ spawn ("sleep 2 && conky -c $HOME/.config/conky/xmonad/" ++ colorScheme ++ "-01.conkyrc")
+ spawn ("sleep 2 && trayer --edge top --align right --widthtype request --padding 6 --SetDockType true --SetPartialStrut true --expand true --monitor 1 --transparent true --alpha 0 " ++ colorTrayer ++ " --height 22")
+
+ spawnOnce "xargs xwallpaper --stretch < ~/.cache/wall"
+ -- spawnOnce "~/.fehbg &" -- set last saved feh wallpaper
+ -- spawnOnce "feh --randomize --bg-fill /usr/share/backgrounds/dtos-backgrounds/*" -- feh set random wallpaper
+ -- spawnOnce "nitrogen --restore &" -- if you prefer nitrogen to feh
+ setWMName "LG3D"
+
+myNavigation :: TwoD a (Maybe a)
+myNavigation = makeXEventhandler $ shadowWithKeymap navKeyMap navDefaultHandler
+ where navKeyMap = M.fromList [
+ ((0,xK_Escape), cancel)
+ ,((0,xK_Return), select)
+ ,((0,xK_slash) , substringSearch myNavigation)
+ ,((0,xK_Left) , move (-1,0) >> myNavigation)
+ ,((0,xK_h) , move (-1,0) >> myNavigation)
+ ,((0,xK_Right) , move (1,0) >> myNavigation)
+ ,((0,xK_l) , move (1,0) >> myNavigation)
+ ,((0,xK_Down) , move (0,1) >> myNavigation)
+ ,((0,xK_j) , move (0,1) >> myNavigation)
+ ,((0,xK_Up) , move (0,-1) >> myNavigation)
+ ,((0,xK_k) , move (0,-1) >> myNavigation)
+ ,((0,xK_y) , move (-1,-1) >> myNavigation)
+ ,((0,xK_i) , move (1,-1) >> myNavigation)
+ ,((0,xK_n) , move (-1,1) >> myNavigation)
+ ,((0,xK_m) , move (1,-1) >> myNavigation)
+ ,((0,xK_space) , setPos (0,0) >> myNavigation)
+ ]
+ navDefaultHandler = const myNavigation
+
+myColorizer :: Window -> Bool -> X (String, String)
+myColorizer = colorRangeFromClassName
+ (0x28,0x2c,0x34) -- lowest inactive bg
+ (0x28,0x2c,0x34) -- highest inactive bg
+ (0xc7,0x92,0xea) -- active bg
+ (0xc0,0xa7,0x9a) -- inactive fg
+ (0x28,0x2c,0x34) -- active fg
+
+-- gridSelect menu layout
+mygridConfig :: p -> GSConfig Window
+mygridConfig colorizer = (buildDefaultGSConfig myColorizer)
+ { gs_cellheight = 40
+ , gs_cellwidth = 200
+ , gs_cellpadding = 6
+ , gs_navigate = myNavigation
+ , gs_originFractX = 0.5
+ , gs_originFractY = 0.5
+ , gs_font = myFont
+ }
+
+spawnSelected' :: [(String, String)] -> X ()
+spawnSelected' lst = gridselect conf lst >>= flip whenJust spawn
+ where conf = def
+ { gs_cellheight = 40
+ , gs_cellwidth = 180
+ , gs_cellpadding = 6
+ , gs_originFractX = 0.5
+ , gs_originFractY = 0.5
+ , gs_font = myFont
+ }
+
+runSelectedAction' :: GSConfig (X ()) -> [(String, X ())] -> X ()
+runSelectedAction' conf actions = do
+ selectedActionM <- gridselect conf actions
+ case selectedActionM of
+ Just selectedAction -> selectedAction
+ Nothing -> return ()
+
+-- gsCategories =
+-- [ ("Games", spawnSelected' gsGames)
+-- --, ("Education", spawnSelected' gsEducation)
+-- , ("Internet", spawnSelected' gsInternet)
+-- , ("Multimedia", spawnSelected' gsMultimedia)
+-- , ("Office", spawnSelected' gsOffice)
+-- , ("Settings", spawnSelected' gsSettings)
+-- , ("System", spawnSelected' gsSystem)
+-- , ("Utilities", spawnSelected' gsUtilities)
+-- ]
+
+gsCategories =
+ [ ("Games", "xdotool key super+alt+1")
+ , ("Education", "xdotool key super+alt+2")
+ , ("Internet", "xdotool key super+alt+3")
+ , ("Multimedia", "xdotool key super+alt+4")
+ , ("Office", "xdotool key super+alt+5")
+ , ("Settings", "xdotool key super+alt+6")
+ , ("System", "xdotool key super+alt+7")
+ , ("Utilities", "xdotool key super+alt+8")
+ ]
+
+gsGames =
+ [ ("0 A.D.", "0ad")
+ , ("Battle For Wesnoth", "wesnoth")
+ , ("OpenArena", "openarena")
+ , ("Sauerbraten", "sauerbraten")
+ , ("Steam", "steam")
+ , ("Unvanquished", "unvanquished")
+ , ("Xonotic", "xonotic-glx")
+ ]
+
+gsEducation =
+ [ ("GCompris", "gcompris-qt")
+ , ("Kstars", "kstars")
+ , ("Minuet", "minuet")
+ , ("Scratch", "scratch")
+ ]
+
+gsInternet =
+ [ ("Brave", "brave")
+ , ("Discord", "discord")
+ , ("Element", "element-desktop")
+ , ("Firefox", "firefox")
+ , ("LBRY App", "lbry")
+ , ("Mailspring", "mailspring")
+ , ("Nextcloud", "nextcloud")
+ , ("Qutebrowser", "qutebrowser")
+ , ("Transmission", "transmission-gtk")
+ , ("Zoom", "zoom")
+ ]
+
+gsMultimedia =
+ [ ("Audacity", "audacity")
+ , ("Blender", "blender")
+ , ("Deadbeef", "deadbeef")
+ , ("Kdenlive", "kdenlive")
+ , ("OBS Studio", "obs")
+ , ("VLC", "vlc")
+ ]
+
+gsOffice =
+ [ ("Document Viewer", "evince")
+ , ("LibreOffice", "libreoffice")
+ , ("LO Base", "lobase")
+ , ("LO Calc", "localc")
+ , ("LO Draw", "lodraw")
+ , ("LO Impress", "loimpress")
+ , ("LO Math", "lomath")
+ , ("LO Writer", "lowriter")
+ ]
+
+gsSettings =
+ [ ("ARandR", "arandr")
+ , ("ArchLinux Tweak Tool", "archlinux-tweak-tool")
+ , ("Customize Look and Feel", "lxappearance")
+ , ("Firewall Configuration", "sudo gufw")
+ ]
+
+gsSystem =
+ [ ("Alacritty", "alacritty")
+ , ("Bash", (myTerminal ++ " -e bash"))
+ , ("Htop", (myTerminal ++ " -e htop"))
+ , ("Fish", (myTerminal ++ " -e fish"))
+ , ("PCManFM", "pcmanfm")
+ , ("VirtualBox", "virtualbox")
+ , ("Virt-Manager", "virt-manager")
+ , ("Zsh", (myTerminal ++ " -e zsh"))
+ ]
+
+gsUtilities =
+ [ ("Emacs", "emacs")
+ , ("Emacsclient", "emacsclient -c -a 'emacs'")
+ , ("Nitrogen", "nitrogen")
+ , ("Vim", (myTerminal ++ " -e vim"))
+ ]
+
+myScratchPads :: [NamedScratchpad]
+myScratchPads = [ NS "terminal" spawnTerm findTerm manageTerm
+ , NS "mocp" spawnMocp findMocp manageMocp
+ , NS "calculator" spawnCalc findCalc manageCalc
+ ]
+ where
+ spawnTerm = myTerminal ++ " -t scratchpad"
+ findTerm = title =? "scratchpad"
+ manageTerm = customFloating $ W.RationalRect l t w h
+ where
+ h = 0.9
+ w = 0.9
+ t = 0.95 -h
+ l = 0.95 -w
+ spawnMocp = myTerminal ++ " -t mocp -e mocp"
+ findMocp = title =? "mocp"
+ manageMocp = customFloating $ W.RationalRect l t w h
+ where
+ h = 0.9
+ w = 0.9
+ t = 0.95 -h
+ l = 0.95 -w
+ spawnCalc = "qalculate-gtk"
+ findCalc = className =? "Qalculate-gtk"
+ manageCalc = customFloating $ W.RationalRect l t w h
+ where
+ h = 0.5
+ w = 0.4
+ t = 0.75 -h
+ l = 0.70 -w
+
+--Makes setting the spacingRaw simpler to write. The spacingRaw module adds a configurable amount of space around windows.
+mySpacing :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
+mySpacing i = spacingRaw False (Border i i i i) True (Border i i i i) True
+
+-- Below is a variation of the above except no borders are applied
+-- if fewer than two windows. So a single window has no gaps.
+mySpacing' :: Integer -> l a -> XMonad.Layout.LayoutModifier.ModifiedLayout Spacing l a
+mySpacing' i = spacingRaw True (Border i i i i) True (Border i i i i) True
+
+-- Defining a bunch of layouts, many that I don't use.
+-- limitWindows n sets maximum number of windows displayed for layout.
+-- mySpacing n sets the gap size around the windows.
+tall = renamed [Replace "tall"]
+ $ limitWindows 5
+ $ smartBorders
+ $ windowNavigation
+ $ addTabs shrinkText myTabTheme
+ $ subLayout [] (smartBorders Simplest)
+ $ mySpacing 8
+ $ ResizableTall 1 (3/100) (1/2) []
+monocle = renamed [Replace "monocle"]
+ $ smartBorders
+ $ windowNavigation
+ $ addTabs shrinkText myTabTheme
+ $ subLayout [] (smartBorders Simplest)
+ $ Full
+floats = renamed [Replace "floats"]
+ $ smartBorders
+ $ simplestFloat
+grid = renamed [Replace "grid"]
+ $ limitWindows 9
+ $ smartBorders
+ $ windowNavigation
+ $ addTabs shrinkText myTabTheme
+ $ subLayout [] (smartBorders Simplest)
+ $ mySpacing 8
+ $ mkToggle (single MIRROR)
+ $ Grid (16/10)
+spirals = renamed [Replace "spirals"]
+ $ limitWindows 9
+ $ smartBorders
+ $ windowNavigation
+ $ addTabs shrinkText myTabTheme
+ $ subLayout [] (smartBorders Simplest)
+ $ mySpacing' 8
+ $ spiral (6/7)
+threeCol = renamed [Replace "threeCol"]
+ $ limitWindows 7
+ $ smartBorders
+ $ windowNavigation
+ $ addTabs shrinkText myTabTheme
+ $ subLayout [] (smartBorders Simplest)
+ $ ThreeCol 1 (3/100) (1/2)
+threeRow = renamed [Replace "threeRow"]
+ $ limitWindows 7
+ $ smartBorders
+ $ windowNavigation
+ $ addTabs shrinkText myTabTheme
+ $ subLayout [] (smartBorders Simplest)
+ -- Mirror takes a layout and rotates it by 90 degrees.
+ -- So we are applying Mirror to the ThreeCol layout.
+ $ Mirror
+ $ ThreeCol 1 (3/100) (1/2)
+tabs = renamed [Replace "tabs"]
+ -- I cannot add spacing to this layout because it will
+ -- add spacing between window and tabs which looks bad.
+ $ tabbed shrinkText myTabTheme
+tallAccordion = renamed [Replace "tallAccordion"]
+ $ Accordion
+wideAccordion = renamed [Replace "wideAccordion"]
+ $ Mirror Accordion
+
+-- setting colors for tabs layout and tabs sublayout.
+myTabTheme = def { fontName = myFont
+ , activeColor = color15
+ , inactiveColor = color08
+ , activeBorderColor = color15
+ , inactiveBorderColor = colorBack
+ , activeTextColor = colorBack
+ , inactiveTextColor = color16
+ }
+
+-- Theme for showWName which prints current workspace when you change workspaces.
+myShowWNameTheme :: SWNConfig
+myShowWNameTheme = def
+ { swn_font = "xft:Ubuntu:bold:size=60"
+ , swn_fade = 1.0
+ , swn_bgcolor = "#1c1f24"
+ , swn_color = "#ffffff"
+ }
+
+-- The layout hook
+myLayoutHook = avoidStruts
+ $ mouseResize
+ $ windowArrange
+ $ T.toggleLayouts floats
+ $ mkToggle (NBFULL ?? NOBORDERS ?? EOT) myDefaultLayout
+ where
+ myDefaultLayout = withBorder myBorderWidth tall
+ ||| noBorders monocle
+ ||| floats
+ ||| noBorders tabs
+ ||| grid
+ ||| spirals
+ ||| threeCol
+ ||| threeRow
+ ||| tallAccordion
+ ||| wideAccordion
+
+-- myWorkspaces = [" 1 ", " 2 ", " 3 ", " 4 ", " 5 ", " 6 ", " 7 ", " 8 ", " 9 "]
+myWorkspaces = [" DEV ", " WWW ", " SYS ", " ANKI ", " VBOX ", " CHAT ", "MUSIC", " vid ", " gfx "]
+myWorkspaceIndices = M.fromList $ zipWith (,) myWorkspaces [1..] -- (,) == \x y -> (x,y)
+
+clickable ws = "<action=xdotool key super+"++show i++">"++ws++"</action>"
+ where i = fromJust $ M.lookup ws myWorkspaceIndices
+
+myManageHook :: XMonad.Query (Data.Monoid.Endo WindowSet)
+myManageHook = composeAll
+ -- 'doFloat' forces a window to float. Useful for dialog boxes and such.
+ -- using 'doShift ( myWorkspaces !! 7)' sends program to workspace 8!
+ -- I'm doing it this way because otherwise I would have to write out the full
+ -- name of my workspaces and the names would be very long if using clickable workspaces.
+ [ className =? "confirm" --> doFloat
+ , className =? "file_progress" --> doFloat
+ , className =? "dialog" --> doFloat
+ , className =? "download" --> doFloat
+ , className =? "error" --> doFloat
+ , className =? "Gimp" --> doFloat
+ , className =? "notification" --> doFloat
+ , className =? "pinentry-gtk-2" --> doFloat
+ , className =? "splash" --> doFloat
+ , className =? "toolbar" --> doFloat
+ , className =? "Yad" --> doCenterFloat
+ , title =? "Oracle VM VirtualBox Manager" --> doFloat
+ , title =? "Mozilla Firefox" --> doShift ( myWorkspaces !! 1 )
+ , className =? "Brave-browser" --> doShift ( myWorkspaces !! 1 )
+ , className =? "mpv" --> doShift ( myWorkspaces !! 7 )
+ , className =? "Gimp" --> doShift ( myWorkspaces !! 8 )
+ , className =? "VirtualBox Manager" --> doShift ( myWorkspaces !! 4 )
+ , (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog
+ , isFullscreen --> doFullFloat
+ ] <+> namedScratchpadManageHook myScratchPads
+
+soundDir = "/opt/dtos-sounds/" -- The directory that has the sound files
+
+startupSound = soundDir ++ "startup-01.mp3"
+shutdownSound = soundDir ++ "shutdown-01.mp3"
+dmenuSound = soundDir ++ "menu-01.mp3"
+
+subtitle' :: String -> ((KeyMask, KeySym), NamedAction)
+subtitle' x = ((0,0), NamedAction $ map toUpper
+ $ sep ++ "\n-- " ++ x ++ " --\n" ++ sep)
+ where
+ sep = replicate (6 + length x) '-'
+
+showKeybindings :: [((KeyMask, KeySym), NamedAction)] -> NamedAction
+showKeybindings x = addName "Show Keybindings" $ io $ do
+ h <- spawnPipe $ "yad --text-info --fontname=\"SauceCodePro Nerd Font Mono 12\" --fore=#46d9ff back=#282c36 --center --geometry=1200x800 --title \"XMonad keybindings\""
+ --hPutStr h (unlines $ showKm x) -- showKM adds ">>" before subtitles
+ hPutStr h (unlines $ showKmSimple x) -- showKmSimple doesn't add ">>" to subtitles
+ hClose h
+ return ()
+
+myKeys :: XConfig l0 -> [((KeyMask, KeySym), NamedAction)]
+myKeys c =
+ --(subtitle "Custom Keys":) $ mkNamedKeymap c $
+ let subKeys str ks = subtitle' str : mkNamedKeymap c ks in
+ subKeys "Xmonad Essentials"
+ [ ("M-C-r", addName "Recompile XMonad" $ spawn "xmonad --recompile")
+ , ("M-S-r", addName "Restart XMonad" $ spawn "xmonad --restart")
+ , ("M-S-q", addName "Quit XMonad" $ sequence_ [spawn (mySoundPlayer ++ shutdownSound), io exitSuccess])
+ , ("M-S-c", addName "Kill focused window" $ kill1)
+ , ("M-S-a", addName "Kill all windows on WS" $ killAll)
+ , ("M-S-<Return>", addName "Run prompt" $ sequence_ [spawn (mySoundPlayer ++ dmenuSound), spawn "~/.local/bin/dm-run"])
+ , ("M-/", addName "DTOS Help" $ spawn "~/.local/bin/dtos-help")
+ , ("M-S-m", addName "Restart XMonad" $ spawn "spotify")]
+ ^++^ subKeys "Switch to workspace"
+ [ ("M-1", addName "Switch to workspace 1" $ (windows $ W.greedyView $ myWorkspaces !! 0))
+ , ("M-2", addName "Switch to workspace 2" $ (windows $ W.greedyView $ myWorkspaces !! 1))
+ , ("M-3", addName "Switch to workspace 3" $ (windows $ W.greedyView $ myWorkspaces !! 2))
+ , ("M-4", addName "Switch to workspace 4" $ (windows $ W.greedyView $ myWorkspaces !! 3))
+ , ("M-5", addName "Switch to workspace 5" $ (windows $ W.greedyView $ myWorkspaces !! 4))
+ , ("M-6", addName "Switch to workspace 6" $ (windows $ W.greedyView $ myWorkspaces !! 5))
+ , ("M-7", addName "Switch to workspace 7" $ (windows $ W.greedyView $ myWorkspaces !! 6))
+ , ("M-8", addName "Switch to workspace 8" $ (windows $ W.greedyView $ myWorkspaces !! 7))
+ , ("M-9", addName "Switch to workspace 9" $ (windows $ W.greedyView $ myWorkspaces !! 8))]
+
+ ^++^ subKeys "Send window to workspace"
+ [ ("M-S-1", addName "Send to workspace 1" $ (windows $ W.shift $ myWorkspaces !! 0))
+ , ("M-S-2", addName "Send to workspace 2" $ (windows $ W.shift $ myWorkspaces !! 1))
+ , ("M-S-3", addName "Send to workspace 3" $ (windows $ W.shift $ myWorkspaces !! 2))
+ , ("M-S-4", addName "Send to workspace 4" $ (windows $ W.shift $ myWorkspaces !! 3))
+ , ("M-S-5", addName "Send to workspace 5" $ (windows $ W.shift $ myWorkspaces !! 4))
+ , ("M-S-6", addName "Send to workspace 6" $ (windows $ W.shift $ myWorkspaces !! 5))
+ , ("M-S-7", addName "Send to workspace 7" $ (windows $ W.shift $ myWorkspaces !! 6))
+ , ("M-S-8", addName "Send to workspace 8" $ (windows $ W.shift $ myWorkspaces !! 7))
+ , ("M-S-9", addName "Send to workspace 9" $ (windows $ W.shift $ myWorkspaces !! 8))]
+
+ ^++^ subKeys "Move window to WS and go there"
+ [ ("M-S-<Page_Up>", addName "Move window to next WS" $ shiftTo Next nonNSP >> moveTo Next nonNSP)
+ , ("M-S-<Page_Down>", addName "Move window to prev WS" $ shiftTo Prev nonNSP >> moveTo Prev nonNSP)]
+
+ ^++^ subKeys "Window navigation"
+ [ ("M-j", addName "Move focus to next window" $ windows W.focusDown)
+ , ("M-k", addName "Move focus to prev window" $ windows W.focusUp)
+ , ("M-m", addName "Move focus to master window" $ windows W.focusMaster)
+ , ("M-S-j", addName "Swap focused window with next window" $ windows W.swapDown)
+ , ("M-S-k", addName "Swap focused window with prev window" $ windows W.swapUp)
+ , ("M-S-m", addName "Swap focused window with master window" $ windows W.swapMaster)
+ , ("M-<Backspace>", addName "Move focused window to master" $ promote)
+ , ("M-S-,", addName "Rotate all windows except master" $ rotSlavesDown)
+ , ("M-S-.", addName "Rotate all windows current stack" $ rotAllDown)]
+
+ -- Dmenu scripts (dmscripts)
+ -- In Xmonad and many tiling window managers, M-p is the default keybinding to
+ -- launch dmenu_run, so I've decided to use M-p plus KEY for these dmenu scripts.
+ ^++^ subKeys "Dmenu scripts"
+ [ ("M-tab", addName "List all dmscripts" $ spawn "dmenu_run")
+ , ("M-p a", addName "Choose ambient sound" $ spawn "dm-sounds")
+ , ("M-p b", addName "Set background" $ spawn "dm-setbg")
+ , ("M-p c", addName "Choose color scheme" $ spawn "~/.local/bin/dtos-colorscheme")
+ , ("M-p C", addName "Pick color from scheme" $ spawn "dm-colpick")
+ , ("M-p e", addName "Edit config files" $ spawn "dm-confedit")
+ , ("M-p i", addName "Take a screenshot" $ spawn "dm-maim")
+ , ("M-p k", addName "Kill processes" $ spawn "dm-kill")
+ , ("M-p m", addName "View manpages" $ spawn "dm-man")
+ , ("M-p n", addName "Store and copy notes" $ spawn "dm-note")
+ , ("M-p o", addName "Browser bookmarks" $ spawn "dm-bookman")
+ , ("M-p p", addName "Passmenu" $ spawn "passmenu -p \"Pass: \"")
+ , ("M-p q", addName "Logout Menu" $ spawn "dm-logout")
+ , ("M-p r", addName "Listen to online radio" $ spawn "dm-radio")
+ , ("M-p s", addName "Search various engines" $ spawn "dm-websearch")
+ , ("M-p t", addName "Translate text" $ spawn "dm-translate")]
+
+ ^++^ subKeys "Favorite programs"
+ [ ("M-<Return>", addName "Launch terminal" $ spawn (myTerminal))
+ , ("M-b", addName "Launch web browser" $ spawn (myBrowser))
+ , ("M-M1-h", addName "Launch htop" $ spawn (myTerminal ++ " -e htop"))]
+
+ ^++^ subKeys "Monitors"
+ [ ("M-.", addName "Switch focus to next monitor" $ nextScreen)
+ , ("M-,", addName "Switch focus to prev monitor" $ prevScreen)]
+
+ -- Switch layouts
+ ^++^ subKeys "Switch layouts"
+ [ ("M-<Tab>", addName "Switch to next layout" $ sendMessage NextLayout)
+ , ("M-<Space>", addName "Toggle noborders/full" $ sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts)]
+
+ -- Window resizing
+ ^++^ subKeys "Window resizing"
+ [ ("M-h", addName "Shrink window" $ sendMessage Shrink)
+ , ("M-l", addName "Expand window" $ sendMessage Expand)
+ , ("M-M1-j", addName "Shrink window vertically" $ sendMessage MirrorShrink)
+ , ("M-M1-k", addName "Expand window vertically" $ sendMessage MirrorExpand)]
+
+ -- Floating windows
+ ^++^ subKeys "Floating windows"
+ [ ("M-f", addName "Toggle float layout" $ sendMessage (T.Toggle "floats"))
+ , ("M-t", addName "Sink a floating window" $ withFocused $ windows . W.sink)
+ , ("M-S-t", addName "Sink all floated windows" $ sinkAll)]
+
+ -- Increase/decrease spacing (gaps)
+ ^++^ subKeys "Window spacing (gaps)"
+ [ ("C-M1-j", addName "Decrease window spacing" $ decWindowSpacing 4)
+ , ("C-M1-k", addName "Increase window spacing" $ incWindowSpacing 4)
+ , ("C-M1-h", addName "Decrease screen spacing" $ decScreenSpacing 4)
+ , ("C-M1-l", addName "Increase screen spacing" $ incScreenSpacing 4)]
+
+ -- Increase/decrease windows in the master pane or the stack
+ ^++^ subKeys "Increase/decrease windows in master pane or the stack"
+ [ ("M-S-<Up>", addName "Increase clients in master pane" $ sendMessage (IncMasterN 1))
+ , ("M-S-<Down>", addName "Decrease clients in master pane" $ sendMessage (IncMasterN (-1)))
+ , ("M-=", addName "Increase max # of windows for layout" $ increaseLimit)
+ , ("M--", addName "Decrease max # of windows for layout" $ decreaseLimit)]
+
+ -- Sublayouts
+ -- This is used to push windows to tabbed sublayouts, or pull them out of it.
+ ^++^ subKeys "Sublayouts"
+ [ ("M-C-h", addName "pullGroup L" $ sendMessage $ pullGroup L)
+ , ("M-C-l", addName "pullGroup R" $ sendMessage $ pullGroup R)
+ , ("M-C-k", addName "pullGroup U" $ sendMessage $ pullGroup U)
+ , ("M-C-j", addName "pullGroup D" $ sendMessage $ pullGroup D)
+ , ("M-C-m", addName "MergeAll" $ withFocused (sendMessage . MergeAll))
+ -- , ("M-C-u", addName "UnMerge" $ withFocused (sendMessage . UnMerge))
+ , ("M-C-/", addName "UnMergeAll" $ withFocused (sendMessage . UnMergeAll))
+ , ("M-C-.", addName "Switch focus next tab" $ onGroup W.focusUp')
+ , ("M-C-,", addName "Switch focus prev tab" $ onGroup W.focusDown')]
+
+ -- Scratchpads
+ -- Toggle show/hide these programs. They run on a hidden workspace.
+ -- When you toggle them to show, it brings them to current workspace.
+ -- Toggle them to hide and it sends them back to hidden workspace (NSP).
+ ^++^ subKeys "Scratchpads"
+ [ ("M-s t", addName "Toggle scratchpad terminal" $ namedScratchpadAction myScratchPads "terminal")
+ , ("M-s m", addName "Toggle scratchpad mocp" $ namedScratchpadAction myScratchPads "mocp")
+ , ("M-s c", addName "Toggle scratchpad calculator" $ namedScratchpadAction myScratchPads "calculator")]
+
+ -- Controls for mocp music player (SUPER-u followed by a key)
+ ^++^ subKeys "Mocp music player"
+ [ ("M-u p", addName "mocp play" $ spawn "mocp --play")
+ , ("M-u l", addName "mocp next" $ spawn "mocp --next")
+ , ("M-u h", addName "mocp prev" $ spawn "mocp --previous")
+ , ("M-u <Space>", addName "mocp toggle pause" $ spawn "mocp --toggle-pause")]
+
+ ^++^ subKeys "GridSelect"
+ -- , ("C-g g", addName "Select favorite apps" $ runSelectedAction' defaultGSConfig gsCategories)
+ [ ("M-M1-<Return>", addName "Select favorite apps" $ spawnSelected'
+ $ gsGames ++ gsEducation ++ gsInternet ++ gsMultimedia ++ gsOffice ++ gsSettings ++ gsSystem ++ gsUtilities)
+ , ("M-M1-c", addName "Select favorite apps" $ spawnSelected' gsCategories)
+ , ("M-M1-t", addName "Goto selected window" $ goToSelected $ mygridConfig myColorizer)
+ , ("M-M1-b", addName "Bring selected window" $ bringSelected $ mygridConfig myColorizer)
+ , ("M-M1-1", addName "Menu of games" $ spawnSelected' gsGames)
+ , ("M-M1-2", addName "Menu of education apps" $ spawnSelected' gsEducation)
+ , ("M-M1-3", addName "Menu of Internet apps" $ spawnSelected' gsInternet)
+ , ("M-M1-4", addName "Menu of multimedia apps" $ spawnSelected' gsMultimedia)
+ , ("M-M1-5", addName "Menu of office apps" $ spawnSelected' gsOffice)
+ , ("M-M1-6", addName "Menu of settings apps" $ spawnSelected' gsSettings)
+ , ("M-M1-7", addName "Menu of system apps" $ spawnSelected' gsSystem)
+ , ("M-M1-8", addName "Menu of utilities apps" $ spawnSelected' gsUtilities)]
+
+ -- Emacs (SUPER-e followed by a key)
+ ^++^ subKeys "Emacs"
+ [ ("M-e e", addName "Emacsclient Dashboard" $ spawn (myEmacs ++ ("--eval '(dashboard-refresh-buffer)'")))
+ , ("M-e a", addName "Emacsclient EMMS (music)" $ spawn (myEmacs ++ ("--eval '(emms)' --eval '(emms-play-directory-tree \"~/Music/\")'")))
+ , ("M-e b", addName "Emacsclient Ibuffer" $ spawn (myEmacs ++ ("--eval '(ibuffer)'")))
+ , ("M-e d", addName "Emacsclient Dired" $ spawn (myEmacs ++ ("--eval '(dired nil)'")))
+ , ("M-e i", addName "Emacsclient ERC (IRC)" $ spawn (myEmacs ++ ("--eval '(erc)'")))
+ , ("M-e n", addName "Emacsclient Elfeed (RSS)" $ spawn (myEmacs ++ ("--eval '(elfeed)'")))
+ , ("M-e s", addName "Emacsclient Eshell" $ spawn (myEmacs ++ ("--eval '(eshell)'")))
+ , ("M-e v", addName "Emacsclient Vterm" $ spawn (myEmacs ++ ("--eval '(+vterm/here nil)'")))
+ , ("M-e w", addName "Emacsclient EWW Browser" $ spawn (myEmacs ++ ("--eval '(doom/window-maximize-buffer(eww \"distro.tube\"))'")))]
+
+ -- Multimedia Keys
+ ^++^ subKeys "Multimedia keys"
+ [ ("<XF86AudioPlay>", addName "mocp play" $ spawn "mocp --play")
+ , ("<XF86AudioPrev>", addName "mocp next" $ spawn "mocp --previous")
+ , ("<XF86AudioNext>", addName "mocp prev" $ spawn "mocp --next")
+ , ("<XF86AudioMute>", addName "Toggle audio mute" $ spawn "amixer set Master toggle")
+ , ("<XF86AudioLowerVolume>", addName "Lower vol" $ spawn "amixer set Master 5%- unmute")
+ , ("<XF86AudioRaiseVolume>", addName "Raise vol" $ spawn "amixer set Master 5%+ unmute")
+ , ("<XF86HomePage>", addName "Open home page" $ spawn (myBrowser ++ " https://www.youtube.com/c/DistroTube"))
+ , ("<XF86Search>", addName "Web search (dmscripts)" $ spawn "dm-websearch")
+ , ("<XF86Mail>", addName "Email client" $ runOrRaise "thunderbird" (resource =? "thunderbird"))
+ , ("<XF86Calculator>", addName "Calculator" $ runOrRaise "qalculate-gtk" (resource =? "qalculate-gtk"))
+ , ("<XF86Eject>", addName "Eject /dev/cdrom" $ spawn "eject /dev/cdrom")
+ , ("<Print>", addName "Take screenshot (dmscripts)" $ spawn "dm-maim")
+ ]
+ -- The following lines are needed for named scratchpads.
+ where nonNSP = WSIs (return (\ws -> W.tag ws /= "NSP"))
+ nonEmptyNonNSP = WSIs (return (\ws -> isJust (W.stack ws) && W.tag ws /= "NSP"))
+
+main :: IO ()
+main = do
+ -- Launching three instances of xmobar on their monitors.
+ xmproc0 <- spawnPipe ("xmobar -x 0 $HOME/.config/xmobar/" ++ colorScheme ++ "-xmobarrc")
+ xmproc1 <- spawnPipe ("xmobar -x 1 $HOME/.config/xmobar/" ++ colorScheme ++ "-xmobarrc")
+ xmproc2 <- spawnPipe ("xmobar -x 2 $HOME/.config/xmobar/" ++ colorScheme ++ "-xmobarrc")
+ -- the xmonad, ya know...what the WM is named after!
+ xmonad $ addDescrKeys' ((mod4Mask, xK_F1), showKeybindings) myKeys $ ewmh $ docks $ def
+ { manageHook = myManageHook <+> manageDocks
+ , handleEventHook = swallowEventHook (className =? "Alacritty" <||> className =? "st-256color" <||> className =? "XTerm") (return True)
+ , modMask = myModMask
+ , terminal = myTerminal
+ , startupHook = myStartupHook
+ , layoutHook = showWName' myShowWNameTheme $ myLayoutHook
+ , workspaces = myWorkspaces
+ , borderWidth = myBorderWidth
+ , normalBorderColor = myNormColor
+ , focusedBorderColor = myFocusColor
+ , logHook = dynamicLogWithPP $ filterOutWsPP [scratchpadWorkspaceTag] $ xmobarPP
+ { ppOutput = \x -> hPutStrLn xmproc0 x -- xmobar on monitor 1
+ >> hPutStrLn xmproc1 x -- xmobar on monitor 2
+ >> hPutStrLn xmproc2 x -- xmobar on monitor 3
+ , ppCurrent = xmobarColor color06 "" . wrap
+ ("<box type=Bottom width=2 mb=2 color=" ++ color06 ++ ">") "</box>"
+ -- Visible but not current workspace
+ , ppVisible = xmobarColor color06 "" . clickable
+ -- Hidden workspace
+ , ppHidden = xmobarColor color05 "" . wrap
+ ("<box type=Top width=2 mt=2 color=" ++ color05 ++ ">") "</box>" . clickable
+ -- Hidden workspaces (no windows)
+ , ppHiddenNoWindows = xmobarColor color05 "" . clickable
+ -- Title of active window
+ , ppTitle = xmobarColor color16 "" . shorten 60
+ -- Separator character
+ , ppSep = "<fc=" ++ color09 ++ "> <fn=1>|</fn> </fc>"
+ -- Urgent workspace
+ , ppUrgent = xmobarColor color02 "" . wrap "!" "!"
+ -- Adding # of windows on current workspace to the bar
+ , ppExtras = [windowCount]
+ -- order of things in xmobar
+ , ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t]
+ }
+ }