19 KiB
19 KiB
Phil B's xmonad config
Info:
This is my XMonad config. It's heavily based on Derek Taylor's config from DTOS.
Imports
-- 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
import XMonad.Actions.GridSelect
import XMonad.Actions.MouseResize
import XMonad.Actions.Promote
import XMonad.Actions.RotSlaves (rotSlavesDown, rotAllDown)
import XMonad.Actions.UpdatePointer
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(..))
import XMonad.Prompt
import XMonad.Prompt.OrgMode
-- Utilities
import XMonad.Util.Dmenu
import XMonad.Util.EZConfig
import XMonad.Util.NamedActions
import XMonad.Util.NamedScratchpad
import XMonad.Util.Run (runProcessWithInput, safeSpawn, spawnPipe)
import XMonad.Util.SpawnOnce
import XMonad.Util.ClickableWorkspaces
-- ColorScheme module (SET ONLY ONE!)
-- Possible choice are:
-- DoomOne
-- Dracula
-- GruvboxDark
-- MonokaiPro
-- Nord
-- OceanicNext
-- Palenight
-- SolarizedDark
-- SolarizedLight
-- TomorrowNight
import Colors.DoomOne
Window Management and Layouts
myBorderWidth :: Dimension --used in 2 places
myBorderWidth = 2 -- Sets border width for windows
windowCount :: X (Maybe String) --used in 2 places
windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset
--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
-- 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"]
$ smartBorders
-- $ windowNavigation
$ addTabs shrinkText myTabTheme
$ subLayout [] (smartBorders Simplest)
$ mySpacing 8
$ ResizableTall 1 (3/100) (1/2) []
monocle = renamed [Replace "monocle"]
$ smartBorders
$ windowNavigation
$ mySpacing 8
$ addTabs shrinkText myTabTheme
$ subLayout [] (smartBorders Simplest)
$ Full
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
-- setting colors for tabs layout and tabs sublayout.
myTabTheme = def { fontName = "xft:Iosevka-9"
, activeColor = color15
, inactiveColor = colorBack
, activeBorderColor = color15
, inactiveBorderColor = colorFore
, activeTextColor = colorBack
, inactiveTextColor = colorFore
}
myManageHook = composeAll
[ 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 =? "zoom" --> doFloat
, className =? "Yad" --> doCenterFloat
, (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog
, isFullscreen --> doFullFloat
]
-- myWorkspaceIndices = M.fromList $ zipWith (,) workspaces [1..] -- (,) == \x y -> (x,y)
mySB = statusBarProp "xmobar" (clickablePP xmobarPP)
myWorkspaces = ["1", "2", "3", "4", "5", "6", "7", "8", "9",
"e",
"w", "g", "d", "b", "j", "f", "o", "u",
"r", "s", "t", "h", "v", "y", "n", "a", "i", "l",
"x", "c", "m", "k", "q", "z", "p"
]
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
Main XMonad loop
main :: IO ()
main = do
-- Launching three instances of xmobar on their monitors.
xmproc0 <- spawnPipe ("xmobar -x 0 $HOME/.config/xmobar/tomorrow-night-xmobarrc")
xmproc1 <- spawnPipe ("xmobar -x 1 $HOME/.config/xmobar/tomorrow-night-xmobarrc")
xmproc2 <- spawnPipe ("xmobar -x 2 $HOME/.config/xmobar/tomorrow-night-xmobarrc")
-- the xmonad, ya know...what the WM is named after!
xmonad $ ewmh $ docks $ def
{ manageHook = myManageHook <+> manageDocks
, handleEventHook = swallowEventHook (className =? "Alacritty" <||> className =? "st-256color" <||> className =? "XTerm") (return True)
-- docks
-- Uncomment this line to enable fullscreen support on things like YouTube/Netflix.
-- This works perfect on SINGLE monitor systems. On multi-monitor systems,
-- it adds a border around the window if screen does not have focus. So, solution
-- is to use a keybinding to toggle fullscreen noborders instead. (M-<Space>)
-- <+> fullscreenEventHook
, modMask = mod4Mask
, terminal = "alacritty"
, startupHook = do
setWMName "LG3D"
spawnOnce "feh --randomize --bg-fill /usr/share/backgrounds/archlinux/*" -- feh set random wallpaper"
spawnOnce "lxsession"
spawnOnce "nm-applet"
spawnOnce "picom"
spawnOnce "volumeicon"
spawn "~/.screenalyout/3-laptop-center.sh"
spawn "setxkbmap -model pc104 -layout pl"
spawn "dunst"
spawnOnce "python tech/source/aw-watcher-spotify/aw_watcher_spotify/main.py"
spawnOnce "aw-watcher-afk"
spawnOnce "aw-watcher-window"
spawn "killall conky" -- kill current conky on each restart
spawn "/usr/bin/emacs --daemon" -- emacs daemon for the emacsclient
spawn "killall trayer" -- kill current trayer on each
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 20")
, layoutHook = avoidStruts
$ windowNavigation
$ subTabbed
$ windowArrange
$ mkToggle (NBFULL ?? NOBORDERS ?? EOT)
$ withBorder myBorderWidth tall
||| noBorders monocle
||| noBorders tabs
, workspaces = myWorkspaces
, borderWidth = myBorderWidth
, normalBorderColor = colorBack
, focusedBorderColor = color15
, logHook = dynamicLogWithPP 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=1 color=" ++ color06 ++ ">") "</box>"
-- Visible but not current workspace
, ppVisible = xmobarColor color06 "" . clickable
-- Hidden workspace
, ppHidden = xmobarColor color05 "" . wrap
("<box type=Top width=2 mt=1 color=" ++ color05 ++ ">") "</box>" . clickable
-- Hidden workspaces (no windows)
, ppHiddenNoWindows = xmobarColor color05 "" . clickable
-- Title of active window
, ppTitle = xmobarColor colorFore "" . shorten 48
-- 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]
} >> updatePointer (0.5, 0.5) (0.0, 0.0) }
Keybinds
`additionalKeysP`
-- subKeys "Switch to workspace"
[ ("M-s 1", (windows $ W.greedyView $ myWorkspaces !! 0))
, ("M-s 2", (windows $ W.greedyView $ myWorkspaces !! 1))
, ("M-s 3", (windows $ W.greedyView $ myWorkspaces !! 2))
, ("M-s 4", (windows $ W.greedyView $ myWorkspaces !! 3))
, ("M-s 5", (windows $ W.greedyView $ myWorkspaces !! 4))
, ("M-s 6", (windows $ W.greedyView $ myWorkspaces !! 5))
, ("M-s 7", (windows $ W.greedyView $ myWorkspaces !! 6))
, ("M-s 8", (windows $ W.greedyView $ myWorkspaces !! 7))
, ("M-s 9", (windows $ W.greedyView $ myWorkspaces !! 8))
, ("M-s e", (windows $ W.greedyView $ myWorkspaces !! 9))
, ("M-s w", (windows $ W.greedyView $ myWorkspaces !! 10))
, ("M-s g", (windows $ W.greedyView $ myWorkspaces !! 11))
, ("M-s d", (windows $ W.greedyView $ myWorkspaces !! 12))
, ("M-s b", (windows $ W.greedyView $ myWorkspaces !! 13))
, ("M-s j", (windows $ W.greedyView $ myWorkspaces !! 14))
, ("M-s f", (windows $ W.greedyView $ myWorkspaces !! 15))
, ("M-s o", (windows $ W.greedyView $ myWorkspaces !! 16))
, ("M-s u", (windows $ W.greedyView $ myWorkspaces !! 17))
, ("M-s r", (windows $ W.greedyView $ myWorkspaces !! 18))
, ("M-s s", (windows $ W.greedyView $ myWorkspaces !! 19))
, ("M-s t", (windows $ W.greedyView $ myWorkspaces !! 20))
, ("M-s h", (windows $ W.greedyView $ myWorkspaces !! 21))
, ("M-s v", (windows $ W.greedyView $ myWorkspaces !! 22))
, ("M-s y", (windows $ W.greedyView $ myWorkspaces !! 23))
, ("M-s n", (windows $ W.greedyView $ myWorkspaces !! 24))
, ("M-s a", (windows $ W.greedyView $ myWorkspaces !! 25))
, ("M-s i", (windows $ W.greedyView $ myWorkspaces !! 26))
, ("M-s l", (windows $ W.greedyView $ myWorkspaces !! 27))
, ("M-s x", (windows $ W.greedyView $ myWorkspaces !! 28))
, ("M-s c", (windows $ W.greedyView $ myWorkspaces !! 29))
, ("M-s m", (windows $ W.greedyView $ myWorkspaces !! 30))
, ("M-s k", (windows $ W.greedyView $ myWorkspaces !! 31))
, ("M-s q", (windows $ W.greedyView $ myWorkspaces !! 32))
, ("M-s z", (windows $ W.greedyView $ myWorkspaces !! 33))
, ("M-s p", (windows $ W.greedyView $ myWorkspaces !! 34))
-- ^++^ subKeys "Throw to workspace"
, ("M-t 1", (windows $ W.shift $ myWorkspaces !! 0))
, ("M-t 2", (windows $ W.shift $ myWorkspaces !! 1))
, ("M-t 3", (windows $ W.shift $ myWorkspaces !! 2))
, ("M-t 4", (windows $ W.shift $ myWorkspaces !! 3))
, ("M-t 5", (windows $ W.shift $ myWorkspaces !! 4))
, ("M-t 6", (windows $ W.shift $ myWorkspaces !! 5))
, ("M-t 7", (windows $ W.shift $ myWorkspaces !! 6))
, ("M-t 8", (windows $ W.shift $ myWorkspaces !! 7))
, ("M-t 9", (windows $ W.shift $ myWorkspaces !! 8))
, ("M-t e", (windows $ W.shift $ myWorkspaces !! 9))
, ("M-t w", (windows $ W.shift $ myWorkspaces !! 10))
, ("M-t g", (windows $ W.shift $ myWorkspaces !! 11))
, ("M-t d", (windows $ W.shift $ myWorkspaces !! 12))
, ("M-t b", (windows $ W.shift $ myWorkspaces !! 13))
, ("M-t j", (windows $ W.shift $ myWorkspaces !! 14))
, ("M-t f", (windows $ W.shift $ myWorkspaces !! 15))
, ("M-t o", (windows $ W.shift $ myWorkspaces !! 16))
, ("M-t u", (windows $ W.shift $ myWorkspaces !! 17))
, ("M-t r", (windows $ W.shift $ myWorkspaces !! 18))
, ("M-t s", (windows $ W.shift $ myWorkspaces !! 19))
, ("M-t t", (windows $ W.shift $ myWorkspaces !! 20))
, ("M-t h", (windows $ W.shift $ myWorkspaces !! 21))
, ("M-t v", (windows $ W.shift $ myWorkspaces !! 22))
, ("M-t y", (windows $ W.shift $ myWorkspaces !! 23))
, ("M-t n", (windows $ W.shift $ myWorkspaces !! 24))
, ("M-t a", (windows $ W.shift $ myWorkspaces !! 25))
, ("M-t i", (windows $ W.shift $ myWorkspaces !! 26))
, ("M-t l", (windows $ W.shift $ myWorkspaces !! 27))
, ("M-t x", (windows $ W.shift $ myWorkspaces !! 28))
, ("M-t c", (windows $ W.shift $ myWorkspaces !! 29))
, ("M-t m", (windows $ W.shift $ myWorkspaces !! 30))
, ("M-t k", (windows $ W.shift $ myWorkspaces !! 31))
, ("M-t q", (windows $ W.shift $ myWorkspaces !! 32))
, ("M-t z", (windows $ W.shift $ myWorkspaces !! 33))
, ("M-t p", (windows $ W.shift $ myWorkspaces !! 34))
, ("M-o", windows W.focusUp)
, ("M-a", windows W.focusDown)
, ("M-S-o", windows W.swapUp)
, ("M-S-a", windows W.swapDown)
, ("M-S-y", windows W.swapMaster)
, ("M-<Backspace>", promote)
, ("M-S-,", rotSlavesDown)
, ("M-S-.", rotAllDown)
, ("M-.", nextScreen)
, ("M-,", prevScreen)
-- Switch layouts
, ("M-<Tab>", sendMessage NextLayout)
, ("M-f", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts)
-- Window resizing
, ("M-y", sendMessage Shrink)
, ("M-l", sendMessage Expand)
-- , ("M-M1-j", addName "Shrink window vertically" $ sendMessage MirrorShrink)
-- , ("M-M1-k", addName "Expand window vertically" $ sendMessage MirrorExpand)
-- Floating windows
-- ("M-f", addName "Toggle float layout" $ sendMessage (T.Toggle "floats"))
-- , ("M-S-t", addName "Sink a floating window" $ withFocused $ windows . W.sink)
, ("M-b", sinkAll)
-- Sublayouts
-- This is used to push windows to tabbed sublayouts, or pull them out of it.
, ("C-S-M1-n",sendMessage $ pullGroup L)
, ("C-S-M1-i",sendMessage $ pullGroup R)
, ("C-S-M1-o",sendMessage $ pullGroup U)
, ("C-S-M1-a",sendMessage $ pullGroup D)
, ("C-S-M1-f",withFocused (sendMessage . MergeAll))
-- , ("M-C-u",withFocused (sendMessage . UnMerge))
, ("C-S-M1-u", withFocused (sendMessage . UnMergeAll))
, ("C-S-M1-j", onGroup W.focusUp')
, ("C-S-M1-y", onGroup W.focusDown')
-- XMonad and apps
, ("C-M1-S-0", sequence_ [spawn "xmonad --restart", spawn "xmonad --recompile"])
, ("M-S-M1-C-0", io exitSuccess)
, ("S-C-M1-q", kill1)
, ("M-S-C-M1-q", killAll)
, ("M-S-<Return>", spawn "~/.local/bin/dm-run")
, ("M-d", spawn "rofi -show drun")
, ("M-e", spawn "emacsclient -c -a 'emacs'")
, ("M-<Return>", spawn "alacritty")
, ("M-S-<F11>", spawn "feh --randomize --bg-fill /usr/share/backgrounds/archlinux/*")
, ("M-<Print>", spawn "dm-maim")
, ("<Print>", spawn "flameshot gui")
-- ORG PROMPTS
, ("M-c i", orgPrompt def "TODO" "~/enc/org/inbox.org")
, ("M-c l", orgPromptPrimary def "LINK" "~/enc/org/inbox.org")
, ("M-c n", orgPrompt def "NOTE" "~/enc/org/inbox.org")
, ("M-c p", orgPromptRefile def "TODO" "~/enc/org/phil.org")
-- , ("<Print>", spawn "maim -so | xclip -selection clipboard -t image/png")
-- Time! Timestamps!
, ("M-w l", spawn "sleep 0.5 && xdotool type \"$(date +'%Y.%m.%d %H:%M:%S %Z')\"")
, ("M-w e", spawn "sleep 0.5 && xdotool type \"$(TZ=America/New_York date +'%Y.%m.%d %H:%M:%S %Z')\"")
, ("M-w m", spawn "sleep 0.5 && xdotool type \"$(TZ=America/Denver date +'%Y.%m.%d %H:%M:%S %Z')\"")
-- Multimedia Keys
, ("<XF86AudioPlay>", spawn "mpc toggle")
, ("<XF86AudioPrev>", spawn "mpc prev")
, ("<XF86AudioNext>", spawn "mpc next")
, ("<XF86AudioMute>", spawn "amixer set Master toggle")
, ("<XF86AudioLowerVolume>", spawn "pactl set-sink-volume \"bluez_output.E8_EE_CC_02_F6_8A.1\" -5%")
, ("<XF86AudioRaiseVolume>", spawn "pactl set-sink-volume \"bluez_output.E8_EE_CC_02_F6_8A.1\" +5%")
-- , ("<XF86HomePage>", addName "Open home page" $ spawn (myBrowser ++ " https://www.youtube.com/c/DistroTube"))
, ("<XF86Search>", spawn "dm-websearch")
, ("<XF86Mail>", runOrRaise "evolution" (resource =? "evolution"))
, ("<XF86Calculator>", runOrRaise "qalculate-gtk" (resource =? "qalculate-gtk"))
-- , ("<XF86Eject>", spawn "eject /dev/cdrom")
]
`additionalMouseBindings`
[ ((mod4Mask, button4), \w -> focus w >> prevWS)
, ((mod4Mask, button5), \w -> focus w >> nextWS)]