From 93624c1d352a60feccf1ef5fbfbaa7ad9e9701b5 Mon Sep 17 00:00:00 2001 From: Phil Bajsicki Date: Sat, 15 Apr 2023 17:12:02 +0200 Subject: [PATCH] Add xmonad.hs --- .config/xmonad/lib/Colors/DoomOne.hs | 28 ++ .config/xmonad/xmonad.hs | 401 +++++++++++++++++++++++++++ 2 files changed, 429 insertions(+) create mode 100644 .config/xmonad/lib/Colors/DoomOne.hs create mode 100644 .config/xmonad/xmonad.hs diff --git a/.config/xmonad/lib/Colors/DoomOne.hs b/.config/xmonad/lib/Colors/DoomOne.hs new file mode 100644 index 0000000..a4fdb0f --- /dev/null +++ b/.config/xmonad/lib/Colors/DoomOne.hs @@ -0,0 +1,28 @@ +module Colors.DoomOne where + +import XMonad + +colorScheme = "doom-one" + +colorBack = "#282c34" +colorFore = "#bbc2cf" + +color01 = "#1c1f24" +color02 = "#ff6c6b" +color03 = "#98be65" +color04 = "#da8548" +color05 = "#51afef" +color06 = "#c678dd" +color07 = "#5699af" +color08 = "#202328" +color09 = "#5b6268" +color10 = "#da8548" +color11 = "#4db5bd" +color12 = "#ecbe7b" +color13 = "#3071db" +color14 = "#a9a1e1" +color15 = "#46d9ff" +color16 = "#dfdfdf" + +colorTrayer :: String +colorTrayer = "--tint 0x282c34" diff --git a/.config/xmonad/xmonad.hs b/.config/xmonad/xmonad.hs new file mode 100644 index 0000000..e7b50bc --- /dev/null +++ b/.config/xmonad/xmonad.hs @@ -0,0 +1,401 @@ +-- 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 c", 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)]