-- 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 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 = ""++ws++"" where i = fromJust $ M.lookup ws myWorkspaceIndices 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-) -- <+> fullscreenEventHook , modMask = mod4Mask , terminal = "alacritty" , startupHook = do setWMName "LG3D" spawnOnce "feh --randomize --bg-fill /usr/share/backgrounds/dtos-backgrounds/*" -- 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 ("") "" -- Visible but not current workspace , ppVisible = xmobarColor color06 "" . clickable -- Hidden workspace , ppHidden = xmobarColor color05 "" . wrap ("") "" . clickable -- Hidden workspaces (no windows) , 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` -- 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-", promote) , ("M-S-,", rotSlavesDown) , ("M-S-.", rotAllDown) , ("M-.", nextScreen) , ("M-,", prevScreen) -- Switch layouts , ("M-", 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-", spawn "~/.local/bin/dm-run") , ("M-d", spawn "rofi -show drun") , ("M-e", spawn "emacsclient -c -a 'emacs'") , ("M-", spawn "alacritty") , ("M-S-", spawn "feh --randomize --bg-fill ~/pictures/wallpapers/*") , ("M-", spawn "dm-maim") , ("", 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") -- , ("", 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 , ("", 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%") -- , ("", addName "Open home page" $ spawn (myBrowser ++ " https://www.youtube.com/c/DistroTube")) , ("", spawn "dm-websearch") , ("", runOrRaise "evolution" (resource =? "evolution")) , ("", runOrRaise "qalculate-gtk" (resource =? "qalculate-gtk")) -- , ("", spawn "eject /dev/cdrom") ] `additionalMouseBindings` [ ((mod4Mask, button4), \w -> focus w >> prevWS) , ((mod4Mask, button5), \w -> focus w >> nextWS)]