import XMonad import System.Directory import System.IO (hClose, hPutStr, hPutStrLn) import System.Exit (exitSuccess) import qualified XMonad.StackSet as W 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.SpawnOn import XMonad.Actions.UpdatePointer import XMonad.Actions.WindowGo (runOrRaise) import XMonad.Actions.WithAll (sinkAll, killAll) import qualified XMonad.Actions.Search as S 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 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 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 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 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 import Colors.DoomOne myBorderWidth :: Dimension myBorderWidth = 2 windowCount :: X (Maybe String) 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 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 myTabTheme = def { fontName = "xft:Iosevka-9" , activeColor = color15 , inactiveColor = colorBack , activeBorderColor = color15 , inactiveBorderColor = colorFore , activeTextColor = colorBack , inactiveTextColor = colorFore } 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 = ""++ws++"" where i = fromJust $ M.lookup ws myWorkspaceIndices myManageHook = manageSpawn <> 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 =? "lxqt-openssh-askpass" --> doFloat , className =? "Yad" --> doCenterFloat , (className =? "firefox" <&&> resource =? "Dialog") --> doFloat -- Float Firefox Dialog , isFullscreen --> doFullFloat ] myStartupHook = do setWMName "LG3D" spawnOnce "lxsession" spawnOnce "setxkbmap -model pc104 -layout pl -option compose:rctrl" spawnOnce "gocryptfs ~/.bajsicki enc --extpass lxqt-openssh-askpass" spawnOnce "feh --randomize --bg-fill /usr/share/backgrounds/archlinux/*" 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") spawnOnce "dunst" spawnOnce "aw-server" spawnOnce "aw-watcher-afk" spawnOnce "aw-watcher-window" spawnOnce "poetry run aw-watcher-spotify" spawnOnce "/usr/bin/emacs --daemon" spawnOn "1" "firefox-developer-edition" spawnOn "2" "evolution" spawnOn "3" "discord" spawnOn "6" "google-chrome-stable --profile-directory='Profile 1'" spawnOn "9" "steam" spawnOn "e" "/usr/bin/emacsclient" spawnOn "j" "keepassxc ~/enc/keys/Passwords.kdbx" main :: IO () main = do 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") xmonad $ ewmh $ docks $ def { manageHook = myManageHook <+> manageDocks , handleEventHook = swallowEventHook (className =? "Alacritty" <||> className =? "st-256color" <||> className =? "XTerm") (return True) , modMask = mod4Mask , terminal = "alacritty" , startupHook = myStartupHook , 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 >> hPutStrLn xmproc1 x >> hPutStrLn xmproc2 x , ppCurrent = xmobarColor color06 "" . wrap ("") "" , ppVisible = xmobarColor color06 "" . clickable , ppHidden = xmobarColor color05 "" . wrap ("") "" . clickable , ppHiddenNoWindows = xmobarColor color05 "" . clickable -- Title of active window , ppTitle = xmobarColor colorFore "" . shorten 48 -- Separator character , ppSep = " | " -- 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) } `additionalKeysP` [ ("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)) , ("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-", promote) , ("M-S-,", rotSlavesDown) , ("M-S-.", rotAllDown) , ("M-.", nextScreen) , ("M-,", prevScreen) , ("M-", sendMessage NextLayout) , ("M-f", sendMessage (MT.Toggle NBFULL) >> sendMessage ToggleStruts) , ("M-y", sendMessage Shrink) , ("M-l", sendMessage Expand) , ("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') , ("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-d", spawn "rofi -show drun") , ("M-e", spawn "emacsclient -c -a 'emacs'") , ("M-", spawn "alacritty") , ("M-S-", spawn "feh --randomize --bg-fill /usr/share/backgrounds/archlinux/*") , ("M-", spawn "dm-maim") , ("", spawn "flameshot gui") , ("M-c i", orgPrompt def "TODO" "~/enc/org/phil.org") , ("M-c l", orgPromptPrimary def "LINK" "~/enc/org/phil.org") , ("M-c n", orgPrompt def "NOTE" "~/enc/org/phil.org") , ("M-c p", orgPromptRefile def "TODO" "~/enc/org/phil.org") -- 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')\"") , ("", spawn "mpc toggle") , ("", spawn "mpc prev") , ("", spawn "mpc next") , ("", spawn "amixer set Master toggle") , ("", spawn "pactl set-sink-volume \"bluez_output.E8_EE_CC_02_F6_8A.1\" -5%") , ("", spawn "pactl set-sink-volume \"bluez_output.E8_EE_CC_02_F6_8A.1\" +5%") ] `additionalMouseBindings` [ ((mod4Mask, button4), \w -> focus w >> prevWS) , ((mod4Mask, button5), \w -> focus w >> nextWS)]