2020-03-25 14:25:15 +00:00
|
|
|
{-# Language ScopedTypeVariables, LambdaCase #-}
|
2020-03-23 19:23:31 +00:00
|
|
|
{-# OPTIONS_GHC -fno-warn-missing-signatures -fno-warn-unused-binds #-}
|
|
|
|
-- Imports -------------------------------------------------------- {{{
|
2020-04-01 10:02:59 +00:00
|
|
|
|
2020-03-22 18:40:50 +00:00
|
|
|
module Config (main) where
|
|
|
|
|
2020-05-09 13:24:23 +00:00
|
|
|
import Control.Concurrent
|
|
|
|
import Control.Exception ( catch
|
|
|
|
, SomeException
|
|
|
|
)
|
2020-03-25 10:05:44 +00:00
|
|
|
import Data.Char (isDigit)
|
2020-05-09 13:24:23 +00:00
|
|
|
import Data.List ( isSuffixOf , isPrefixOf)
|
2020-03-25 10:05:44 +00:00
|
|
|
import System.Exit (exitSuccess)
|
|
|
|
|
2020-04-01 10:08:40 +00:00
|
|
|
import qualified Rofi
|
|
|
|
|
2020-05-09 13:24:23 +00:00
|
|
|
|
2020-04-01 10:08:40 +00:00
|
|
|
import qualified Data.Map as M
|
|
|
|
import qualified Data.Monoid
|
2020-05-09 13:24:23 +00:00
|
|
|
import Data.Foldable ( for_ )
|
2020-04-01 10:08:40 +00:00
|
|
|
import qualified System.IO as SysIO
|
2020-03-22 18:06:44 +00:00
|
|
|
|
2020-04-02 07:31:20 +00:00
|
|
|
import XMonad.Layout.HintedGrid
|
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
import XMonad hiding ((|||))
|
2020-04-01 10:08:40 +00:00
|
|
|
import XMonad.Actions.Commands
|
2020-03-22 18:06:44 +00:00
|
|
|
import XMonad.Actions.CopyWindow
|
|
|
|
import XMonad.Actions.Submap
|
|
|
|
import XMonad.Config.Desktop
|
|
|
|
import XMonad.Hooks.DynamicLog
|
|
|
|
import XMonad.Hooks.ManageDocks
|
|
|
|
import XMonad.Hooks.SetWMName (setWMName)
|
2020-04-01 10:08:40 +00:00
|
|
|
import XMonad.Layout.BinarySpacePartition
|
|
|
|
import XMonad.Layout.BorderResize
|
2020-03-22 18:06:44 +00:00
|
|
|
import XMonad.Layout.Gaps
|
|
|
|
import XMonad.Layout.LayoutCombinators ((|||))
|
2020-04-01 10:08:40 +00:00
|
|
|
import XMonad.Layout.LayoutHints
|
|
|
|
import XMonad.Layout.MouseResizableTile
|
2020-04-01 10:02:59 +00:00
|
|
|
import XMonad.Layout.NoBorders
|
2020-04-01 10:08:40 +00:00
|
|
|
import XMonad.Layout.Renamed (renamed, Rename(Replace))
|
2020-04-01 10:02:59 +00:00
|
|
|
import XMonad.Layout.ResizableTile
|
2020-03-25 10:05:44 +00:00
|
|
|
import XMonad.Layout.Spacing (spacingRaw, Border(..), toggleWindowSpacingEnabled)
|
2020-03-22 18:06:44 +00:00
|
|
|
import XMonad.Layout.ToggleLayouts
|
2020-03-23 19:23:31 +00:00
|
|
|
import XMonad.Layout.ZoomRow
|
2020-05-09 13:24:23 +00:00
|
|
|
import XMonad.Util.EZConfig (additionalKeysP, removeKeysP)
|
2020-03-22 18:06:44 +00:00
|
|
|
import XMonad.Util.NamedScratchpad
|
2020-03-23 19:23:31 +00:00
|
|
|
import XMonad.Util.Run
|
2020-03-22 18:06:44 +00:00
|
|
|
import XMonad.Util.SpawnOnce (spawnOnce)
|
2020-03-25 10:05:44 +00:00
|
|
|
import qualified XMonad.Actions.Navigation2D as Nav2d
|
2020-04-01 10:08:40 +00:00
|
|
|
import qualified XMonad.Hooks.EwmhDesktops as Ewmh
|
|
|
|
import qualified XMonad.Hooks.ManageHelpers as ManageHelpers
|
2020-03-25 11:29:22 +00:00
|
|
|
import qualified XMonad.Layout.BoringWindows as BoringWindows
|
2020-05-09 13:24:23 +00:00
|
|
|
import XMonad.Layout.IndependentScreens
|
2020-04-01 10:08:40 +00:00
|
|
|
import qualified XMonad.StackSet as W
|
|
|
|
import qualified XMonad.Util.XSelection as XSel
|
2020-03-22 18:06:44 +00:00
|
|
|
|
2020-04-01 10:02:59 +00:00
|
|
|
{-# ANN module "HLint: ignore Redundant $" #-}
|
|
|
|
{-# ANN module "HLint: ignore Redundant bracket" #-}
|
|
|
|
{-# ANN module "HLint: ignore Move brackets to avoid $" #-}
|
2020-04-01 10:08:40 +00:00
|
|
|
{-# ANN module "HLint: ignore Unused LANGUAGE pragma" #-}
|
|
|
|
|
|
|
|
-- }}}
|
2020-04-01 10:02:59 +00:00
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
-- Values -------------------- {{{
|
|
|
|
|
|
|
|
myModMask = mod4Mask
|
2020-03-29 09:36:09 +00:00
|
|
|
myLauncher = Rofi.asCommand (def { Rofi.theme = Rofi.bigTheme }) ["-show run"]
|
2020-04-27 15:21:09 +00:00
|
|
|
myTerminal = "termite"
|
2020-03-29 17:39:21 +00:00
|
|
|
myBrowser = "qutebrowser"
|
|
|
|
--myBrowser = "google-chrome-stable"
|
2020-03-22 18:06:44 +00:00
|
|
|
|
2020-03-25 10:05:44 +00:00
|
|
|
{-| adds the scripts-directory path to the filename of a script |-}
|
|
|
|
scriptFile :: String -> String
|
|
|
|
scriptFile script = "/home/leon/scripts/" ++ script
|
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
scratchpads :: [NamedScratchpad]
|
2020-03-23 19:23:31 +00:00
|
|
|
scratchpads =
|
2020-04-04 13:12:33 +00:00
|
|
|
[ NS "terminal" launchTerminal (className =? "scratchpad_term") (customFloating $ W.RationalRect 0.66 0.7 0.34 0.3)
|
|
|
|
, NS "ghci" launchGHCI (className =? "scratchpad_ghci") (customFloating $ W.RationalRect 0.66 0.7 0.34 0.3)
|
2020-03-24 12:00:43 +00:00
|
|
|
, NS "spotify" "spotify" (appName =? "spotify") defaultFloating
|
|
|
|
, NS "discord" "discord" (appName =? "discord") defaultFloating
|
2020-03-23 19:23:31 +00:00
|
|
|
, NS "whatsapp" launchWhatsapp (("WhatsApp" `isSuffixOf`) <$> title) defaultFloating
|
|
|
|
, NS "slack" "slack" (("Slack | " `isPrefixOf`) <$> title) defaultFloating
|
2020-03-22 18:06:44 +00:00
|
|
|
]
|
2020-03-25 10:05:44 +00:00
|
|
|
where
|
2020-03-23 19:23:31 +00:00
|
|
|
launchTerminal = myTerminal ++ " --class scratchpad_term"
|
2020-04-04 13:12:33 +00:00
|
|
|
launchGHCI = myTerminal ++ " --class scratchpad_ghci stack exec -- ghci"
|
2020-03-23 19:23:31 +00:00
|
|
|
launchWhatsapp = "gtk-launch chrome-hnpfjngllnobngcgfapefoaidbinmjnm-Default.desktop"
|
2020-03-22 18:06:44 +00:00
|
|
|
|
|
|
|
|
|
|
|
-- Colors ------ {{{
|
|
|
|
fg = "#ebdbb2"
|
|
|
|
bg = "#282828"
|
|
|
|
gray = "#a89984"
|
|
|
|
bg1 = "#3c3836"
|
|
|
|
bg2 = "#504945"
|
|
|
|
bg3 = "#665c54"
|
|
|
|
bg4 = "#7c6f64"
|
|
|
|
|
|
|
|
green = "#b8bb26"
|
|
|
|
darkgreen = "#98971a"
|
|
|
|
red = "#fb4934"
|
|
|
|
darkred = "#cc241d"
|
|
|
|
yellow = "#fabd2f"
|
|
|
|
blue = "#83a598"
|
|
|
|
purple = "#d3869b"
|
|
|
|
aqua = "#8ec07c"
|
|
|
|
-- }}}
|
|
|
|
|
|
|
|
-- }}}
|
|
|
|
|
|
|
|
-- Layout ---------------------------------------- {{{
|
2020-03-23 19:23:31 +00:00
|
|
|
--layoutHints .
|
2020-04-01 11:24:37 +00:00
|
|
|
myLayout = avoidStruts . BoringWindows.boringWindows . smartBorders . toggleLayouts Full . layoutHintsToCenter $ layouts
|
2020-03-23 19:23:31 +00:00
|
|
|
where
|
2020-04-19 14:40:11 +00:00
|
|
|
layouts =((rename "Tall" $ onlySpacing $ mouseResizableTile {draggerType = dragger}) -- ResizableTall 1 (3/100) (1/2) []
|
|
|
|
||| (rename "Horizon" $ onlySpacing $ mouseResizableTileMirrored {draggerType = dragger}) -- Mirror $ ResizableTall 1 (3/100) (3/4) []
|
2020-04-03 07:50:08 +00:00
|
|
|
||| (rename "BSP" $ spacingAndGaps $ borderResize $ emptyBSP)
|
2020-04-01 10:08:40 +00:00
|
|
|
||| (rename "Row" $ spacingAndGaps $ zoomRow)
|
2020-04-02 07:31:20 +00:00
|
|
|
||| (rename "grid" $ spacingAndGaps $ Grid False))
|
2020-03-25 10:05:44 +00:00
|
|
|
-- ||| (rename "threeCol" $ spacingAndGaps $ ThreeColMid 1 (3/100) (1/2))
|
|
|
|
-- ||| (rename "spiral" $ spacingAndGaps $ spiral (9/21))
|
2020-03-23 19:23:31 +00:00
|
|
|
-- Grid
|
|
|
|
|
2020-03-25 10:05:44 +00:00
|
|
|
rename n = renamed [Replace n]
|
2020-03-23 19:23:31 +00:00
|
|
|
|
2020-03-25 10:05:44 +00:00
|
|
|
gap = 7
|
2020-04-19 14:40:11 +00:00
|
|
|
onlySpacing = gaps [ (dir, (gap*2)) | dir <- [L, R, D, U] ] -- gaps are included in mouseResizableTile
|
2020-03-27 08:06:13 +00:00
|
|
|
dragger = let x = fromIntegral gap * 2
|
2020-03-25 14:33:33 +00:00
|
|
|
in FixedDragger x x
|
|
|
|
spacingAndGaps = let intGap = fromIntegral gap
|
2020-04-24 15:52:50 +00:00
|
|
|
spacingBorder = Border (intGap) (intGap) (intGap) (intGap)
|
|
|
|
gapBorder = Border intGap intGap intGap intGap
|
|
|
|
in spacingRaw True spacingBorder True gapBorder True
|
2020-03-27 08:06:13 +00:00
|
|
|
|
2020-03-23 19:23:31 +00:00
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
-- }}}
|
|
|
|
|
|
|
|
-- Startuphook ----------------------------- {{{
|
|
|
|
|
2020-03-22 18:40:50 +00:00
|
|
|
myStartupHook :: X ()
|
2020-03-22 18:06:44 +00:00
|
|
|
myStartupHook = do
|
2020-04-19 14:40:11 +00:00
|
|
|
spawnOnce "picom --config ~/.config/picom.conf --experimental-backends" --no-fading-openclose"
|
2020-03-22 18:06:44 +00:00
|
|
|
spawnOnce "pasystray"
|
2020-03-25 19:48:11 +00:00
|
|
|
spawnOnce "nm-applet"
|
2020-04-28 14:20:17 +00:00
|
|
|
spawnOnce "xfce4-clipman"
|
|
|
|
spawnOnce "mailspring --background"
|
2020-05-01 19:02:35 +00:00
|
|
|
spawnOnce "redshift -P -O 5000"
|
2020-04-03 07:50:08 +00:00
|
|
|
spawn "xset r rate 300 50" -- make key repeat quicker
|
2020-05-09 13:24:23 +00:00
|
|
|
spawn "/home/leon/.screenlayout/dualscreen-landscape.sh"
|
|
|
|
_ <- liftIO $ Control.Concurrent.threadDelay (1000 * 10)
|
2020-03-22 18:06:44 +00:00
|
|
|
spawn "/home/leon/.config/polybar/launch.sh"
|
2020-04-19 15:49:39 +00:00
|
|
|
spawn "feh --bg-fill /home/leon/Bilder/wallpapers/mountains_with_clounds.jpg"
|
2020-03-22 18:06:44 +00:00
|
|
|
setWMName "LG3D" -- Java stuff hack
|
|
|
|
|
|
|
|
-- }}}
|
|
|
|
|
|
|
|
-- Keymap --------------------------------------- {{{
|
|
|
|
|
2020-04-01 10:02:59 +00:00
|
|
|
-- Default mappings that need to be removed
|
|
|
|
removedKeys :: [String]
|
2020-05-09 13:24:23 +00:00
|
|
|
removedKeys = ["M-S-c", "M-S-q", "M-h", "M-l"] ++ ["M-" ++ show n | n <- [1..9 :: Int]]
|
2020-03-22 18:06:44 +00:00
|
|
|
|
2020-05-07 14:05:16 +00:00
|
|
|
multiMonitorOperation :: (WorkspaceId -> WindowSet -> WindowSet) -> ScreenId -> X ()
|
|
|
|
multiMonitorOperation operation n = do
|
|
|
|
monitor <- screenWorkspace n
|
2020-05-09 13:24:23 +00:00
|
|
|
case monitor of
|
2020-05-07 14:05:16 +00:00
|
|
|
Just mon -> windows $ operation mon
|
|
|
|
Nothing -> return ()
|
|
|
|
|
|
|
|
|
2020-05-09 13:24:23 +00:00
|
|
|
myKeys :: XConfig a -> XConfig a
|
|
|
|
myKeys c = additionalKeysP c $
|
|
|
|
[ ("M-+", sendMessage zoomIn)
|
|
|
|
, ("M--", sendMessage zoomOut)
|
|
|
|
, ("M-#", sendMessage zoomReset)
|
|
|
|
|
|
|
|
, ("M-f", toggleFullscreen)
|
|
|
|
|
|
|
|
, ("M-S-C-c", kill1)
|
|
|
|
, ("M-S-C-q", io exitSuccess)
|
|
|
|
|
|
|
|
-- Binary space partitioning
|
|
|
|
, ("M-<Backspace>", sendMessage Swap)
|
|
|
|
, ("M-M1-<Backspace>", sendMessage Rotate)
|
|
|
|
|
|
|
|
-- Media
|
|
|
|
, ("<XF86AudioRaiseVolume>", spawn "amixer sset Master 5%+")
|
|
|
|
, ("<XF86AudioLowerVolume>", spawn "amixer sset Master 5%-")
|
|
|
|
|
|
|
|
-- Multi monitor
|
|
|
|
, ("M-s", multiMonitorOperation W.view 1)
|
|
|
|
, ("M-d", multiMonitorOperation W.view 0)
|
|
|
|
, ("M-S-s", (multiMonitorOperation W.shift 1) >> multiMonitorOperation W.view 1)
|
|
|
|
, ("M-S-d", (multiMonitorOperation W.shift 0) >> multiMonitorOperation W.view 0)
|
|
|
|
|
|
|
|
-- programs
|
|
|
|
, ("M-p", spawn myLauncher)
|
|
|
|
, ("M-b", spawn myBrowser)
|
|
|
|
, ("M-C-p", spawn (myTerminal ++ " --class termite_floating -e fff"))
|
|
|
|
, ("M-S-p", Rofi.showCombi (def { Rofi.theme = Rofi.bigTheme }) [ "drun", "window", "ssh" ])
|
|
|
|
, ("M-S-e", Rofi.showNormal (def { Rofi.theme = Rofi.bigTheme }) "emoji" )
|
|
|
|
--, ("M-s", spawn $ scriptFile "rofi-search.sh")
|
|
|
|
, ("M-S-o", spawn $ scriptFile "rofi-open.sh")
|
|
|
|
, ("M-n", scratchpadSubmap )
|
|
|
|
, ("M-m", mediaSubmap )
|
|
|
|
, ("M-e", Rofi.promptRunCommand def specialCommands)
|
|
|
|
, ("M-C-e", Rofi.promptRunCommand def =<< defaultCommands )
|
|
|
|
, ("M-o", Rofi.promptRunCommand def withSelectionCommands)
|
|
|
|
, ("M-S-C-g", spawn "killall -INT -g giph" >> spawn "notify-send gif 'saved gif in ~/Bilder/gifs'") -- stop gif recording
|
|
|
|
] ++ generatedMappings
|
2020-03-22 18:06:44 +00:00
|
|
|
where
|
2020-03-27 08:06:13 +00:00
|
|
|
generatedMappings :: [(String, X ())]
|
2020-05-09 13:24:23 +00:00
|
|
|
generatedMappings = windowGoMappings ++ windowSwapMappings ++ resizeMappings ++ workspaceMappings
|
2020-03-27 08:06:13 +00:00
|
|
|
where
|
2020-05-09 13:24:23 +00:00
|
|
|
workspaceMappings =
|
|
|
|
[ (mappingPrefix ++ show wspNum, windows $ onCurrentScreen action wsp)
|
|
|
|
| (wsp, wspNum) <- zip (workspaces' c) [1..9 :: Int]
|
|
|
|
, (mappingPrefix, action) <- [("M-", W.greedyView), ("M-S-", W.shift), ("M-C-", copy)]
|
|
|
|
]
|
2020-04-01 12:37:33 +00:00
|
|
|
|
|
|
|
keyDirPairs = [("h", L), ("j", D), ("k", U), ("l", R)]
|
|
|
|
|
|
|
|
windowGoMappings = [ ("M-M1-" ++ key, Nav2d.windowGo dir False) | (key, dir) <- keyDirPairs ]
|
|
|
|
windowSwapMappings = [ ("M-S-M1-" ++ key, Nav2d.windowSwap dir False) | (key, dir) <- keyDirPairs ]
|
2020-04-02 07:31:20 +00:00
|
|
|
resizeMappings =
|
2020-05-07 14:05:16 +00:00
|
|
|
[ ("M-C-h", ifLayoutIs "BSP" (sendMessage $ ExpandTowards L) (ifLayoutIs "Horizon" (sendMessage ShrinkSlave) (sendMessage Shrink)))
|
|
|
|
, ("M-C-j", ifLayoutIs "BSP" (sendMessage $ ExpandTowards D) (ifLayoutIs "Horizon" (sendMessage Expand) (sendMessage MirrorShrink >> sendMessage ExpandSlave)))
|
|
|
|
, ("M-C-k", ifLayoutIs "BSP" (sendMessage $ ExpandTowards U) (ifLayoutIs "Horizon" (sendMessage Shrink) (sendMessage MirrorExpand >> sendMessage ShrinkSlave)))
|
|
|
|
, ("M-C-l", ifLayoutIs "BSP" (sendMessage $ ExpandTowards R) (ifLayoutIs "Horizon" (sendMessage ExpandSlave) (sendMessage Expand)))
|
2020-03-27 08:06:13 +00:00
|
|
|
]
|
2020-04-01 11:24:37 +00:00
|
|
|
|
2020-05-09 13:24:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
toggleFullscreen :: X ()
|
|
|
|
toggleFullscreen = do
|
|
|
|
sendMessage ToggleLayout -- toggle fullscreen layout
|
|
|
|
sendMessage ToggleStruts -- bar is hidden -> no need to make place for it
|
2020-04-27 15:21:09 +00:00
|
|
|
--safeSpawn "polybar-msg" ["cmd", "toggle"] -- toggle polybar visibility
|
2020-03-22 18:06:44 +00:00
|
|
|
|
2020-03-25 14:25:15 +00:00
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
scratchpadSubmap :: X ()
|
2020-03-24 12:00:43 +00:00
|
|
|
scratchpadSubmap = describedSubmap "Scratchpads"
|
|
|
|
[ ((myModMask, xK_n), "<M-n> terminal", namedScratchpadAction scratchpads "terminal")
|
|
|
|
, ((myModMask, xK_h), "<M-h> ghci", namedScratchpadAction scratchpads "ghci")
|
|
|
|
, ((myModMask, xK_w), "<M-w> whatsapp", namedScratchpadAction scratchpads "whatsapp")
|
|
|
|
, ((myModMask, xK_s), "<M-s> slack", namedScratchpadAction scratchpads "slack")
|
|
|
|
, ((myModMask, xK_m), "<M-m> spotify", namedScratchpadAction scratchpads "spotify")
|
|
|
|
, ((myModMask, xK_d), "<M-m> discord", namedScratchpadAction scratchpads "discord")
|
2020-03-24 11:53:14 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
mediaSubmap :: X ()
|
2020-03-24 12:00:43 +00:00
|
|
|
mediaSubmap = describedSubmap "Media"
|
2020-03-25 10:05:44 +00:00
|
|
|
[ ((myModMask, xK_m), "<M-m> play/pause", spawn "playerctl play-pause")
|
|
|
|
, ((myModMask, xK_l), "<M-l> next", spawn "playerctl next")
|
|
|
|
, ((myModMask, xK_l), "<M-h> previous", spawn "playerctl previous")
|
|
|
|
, ((myModMask, xK_k), "<M-k> increase volume", spawn "amixer sset Master 5%+")
|
|
|
|
, ((myModMask, xK_j), "<M-j> decrease volume", spawn "amixer sset Master 5%-")
|
2020-03-24 11:53:14 +00:00
|
|
|
]
|
2020-03-23 19:23:31 +00:00
|
|
|
|
2020-03-31 16:38:27 +00:00
|
|
|
withSelectionCommands :: [(String, X ())]
|
2020-04-01 10:02:59 +00:00
|
|
|
withSelectionCommands =
|
2020-03-31 16:38:27 +00:00
|
|
|
[ ("Google", XSel.transformPromptSelection ("https://google.com/search?q=" ++) "qutebrowser")
|
|
|
|
, ("Hoogle", XSel.transformPromptSelection ("https://hoogle.haskell.org/?hoogle=" ++) "qutebrowser")
|
|
|
|
, ("Translate", XSel.transformPromptSelection ("https://translate.google.com/#view=home&op=translate&sl=auto&tl=en&text=" ++) "qutebrowser")
|
|
|
|
]
|
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
|
|
|
|
specialCommands :: [(String, X ())]
|
|
|
|
specialCommands =
|
2020-03-29 17:39:21 +00:00
|
|
|
[ ("screenshot", spawn $ scriptFile "screenshot.sh")
|
2020-04-02 07:31:20 +00:00
|
|
|
, ("screenshot to file", spawn $ scriptFile "screenshot.sh --tofile")
|
|
|
|
, ("screenshot full to file", spawn $ scriptFile "screenshot.sh --tofile --fullscreen")
|
2020-04-18 18:27:12 +00:00
|
|
|
, ("screengif to file", spawn (scriptFile "screengif.sh") >> spawn "notify-send gif 'stop gif-recording with M-S-C-g'")
|
2020-04-02 07:31:20 +00:00
|
|
|
, ("clipboard history", spawn $ "clipmenu")
|
2020-03-29 18:47:50 +00:00
|
|
|
, ("toggleOptimal", sendMessage ToggleGaps >> toggleWindowSpacingEnabled)
|
2020-03-29 17:39:21 +00:00
|
|
|
, ("toggleSpacing", toggleWindowSpacingEnabled)
|
|
|
|
, ("toggleGaps", sendMessage ToggleGaps)
|
|
|
|
, ("Copy to all workspaces", windows copyToAll) -- windows: Modify the current window list with a pure function, and refresh
|
|
|
|
, ("Kill all other copies", killAllOtherCopies)
|
2020-04-03 07:50:08 +00:00
|
|
|
, ("toggle polybar", safeSpawn "polybar-msg" ["cmd", "toggle"])
|
2020-03-22 18:06:44 +00:00
|
|
|
]
|
|
|
|
|
2020-03-31 16:38:27 +00:00
|
|
|
|
2020-03-24 12:00:43 +00:00
|
|
|
describedSubmap :: String -> [((KeyMask, KeySym), String, X ())] -> X ()
|
2020-03-25 10:05:44 +00:00
|
|
|
describedSubmap submapTitle mappings = promptDzenWhileRunning submapTitle descriptions mySubmap
|
2020-03-24 11:53:14 +00:00
|
|
|
where
|
2020-03-25 10:05:44 +00:00
|
|
|
mySubmap = submap $ M.fromList $ map (\(k, _, f) -> (k, f)) mappings
|
2020-03-24 11:53:14 +00:00
|
|
|
descriptions = map (\(_,x,_) -> x) mappings
|
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
-- }}}
|
|
|
|
|
|
|
|
-- ManageHook -------------------------------{{{
|
|
|
|
|
|
|
|
myManageHook :: Query (Data.Monoid.Endo WindowSet)
|
|
|
|
myManageHook = composeAll
|
2020-03-29 17:39:21 +00:00
|
|
|
[ resource =? "Dialog" --> ManageHelpers.doCenterFloat
|
|
|
|
, appName =? "pavucontrol" --> ManageHelpers.doCenterFloat
|
|
|
|
, className =? "mpv" --> ManageHelpers.doRectFloat (W.RationalRect 0.9 0.9 0.1 0.1)
|
2020-04-18 18:27:12 +00:00
|
|
|
, title =? "Something" --> doFloat
|
2020-05-04 12:48:12 +00:00
|
|
|
, className =? "termite_floating" --> ManageHelpers.doRectFloat(W.RationalRect 0.2 0.2 0.6 0.6)
|
2020-03-23 19:23:31 +00:00
|
|
|
-- , isFullscreen --> doF W.focusDown <+> doFullFloat
|
|
|
|
, manageDocks
|
|
|
|
, namedScratchpadManageHook scratchpads
|
2020-03-22 18:40:50 +00:00
|
|
|
]
|
2020-03-22 18:06:44 +00:00
|
|
|
|
|
|
|
-- }}}
|
|
|
|
|
|
|
|
-- Main ------------------------------------ {{{
|
2020-03-22 18:40:50 +00:00
|
|
|
main :: IO ()
|
2020-03-22 18:06:44 +00:00
|
|
|
main = do
|
2020-05-09 13:24:23 +00:00
|
|
|
currentScreenCount :: Int <- countScreens
|
|
|
|
let monitorIndices = [0..currentScreenCount - 1]
|
|
|
|
|
|
|
|
-- create a fifo named pipe for every monitor (called /tmp/xmonad-state-bar0, etc)
|
|
|
|
for_ monitorIndices (\idx -> safeSpawn "mkfifo" ["/tmp/xmonad-state-bar" ++ show idx])
|
|
|
|
|
|
|
|
-- create polybarLogHooks for every monitor and combine them using the <+> monoid instance
|
|
|
|
let polybarLogHooks = foldMap (polybarLogHook . fromIntegral) monitorIndices
|
|
|
|
|
|
|
|
let myConfig = myKeys (desktopConfig
|
|
|
|
{ terminal = myTerminal
|
|
|
|
, workspaces = withScreens (fromIntegral currentScreenCount) (map show [1..9 :: Int])
|
|
|
|
, modMask = myModMask
|
|
|
|
, borderWidth = 2
|
|
|
|
, layoutHook = myLayout
|
|
|
|
, logHook = polybarLogHook 0 <+> polybarLogHook 1 <+> logHook def
|
|
|
|
, startupHook = myStartupHook <+> startupHook def -- <+> return () >> checkKeymap myConfig (myKeys myConfig)
|
|
|
|
, manageHook = myManageHook <+> manageHook def
|
|
|
|
, focusedBorderColor = aqua
|
|
|
|
, normalBorderColor = "#282828"
|
|
|
|
--, handleEventHook = minimizeEventHook <+> handleEventHook def <+> hintsEventHook -- <+> Ewmh.fullscreenEventHook
|
|
|
|
} `removeKeysP` removedKeys)
|
|
|
|
|
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
|
2020-03-27 08:06:13 +00:00
|
|
|
xmonad
|
|
|
|
$ Ewmh.ewmh
|
2020-03-25 10:05:44 +00:00
|
|
|
$ Nav2d.withNavigation2DConfig def { Nav2d.defaultTiledNavigation = Nav2d.sideNavigation }
|
2020-05-09 13:24:23 +00:00
|
|
|
$ myConfig
|
2020-03-22 18:06:44 +00:00
|
|
|
|
2020-03-25 17:36:34 +00:00
|
|
|
|
|
|
|
|
2020-03-22 18:06:44 +00:00
|
|
|
-- }}}
|
|
|
|
|
|
|
|
-- POLYBAR Kram -------------------------------------- {{{
|
|
|
|
|
2020-05-09 13:24:23 +00:00
|
|
|
-- | Loghook for polybar on a given monitor.
|
|
|
|
-- Will write the polybar formatted string to /tmp/xmonad-state-bar${monitor}
|
|
|
|
polybarLogHook :: Int -> X ()
|
|
|
|
polybarLogHook monitor = do
|
|
|
|
barOut <- dynamicLogString $ polybarPP monitor
|
|
|
|
io $ SysIO.appendFile ("/tmp/xmonad-state-bar" ++ show monitor) (barOut ++ "\n")
|
2020-03-22 18:06:44 +00:00
|
|
|
|
2020-05-09 13:24:23 +00:00
|
|
|
|
|
|
|
-- swapping namedScratchpadFilterOutWorkspacePP and marshallPP will throw "Prelude.read no Parse" errors..... wtf
|
|
|
|
-- | create a polybar Pretty printer, marshalled for given monitor.
|
|
|
|
polybarPP :: Int -> PP
|
|
|
|
polybarPP monitor = namedScratchpadFilterOutWorkspacePP $ marshallPP (fromIntegral monitor) $ def
|
|
|
|
{ ppCurrent = withBG bg2
|
2020-03-23 19:23:31 +00:00
|
|
|
, ppVisible = withBG bg2
|
2020-03-22 18:06:44 +00:00
|
|
|
, ppUrgent = withFG red
|
2020-03-25 14:33:33 +00:00
|
|
|
, ppLayout = removeWord "Minimize" . removeWord "Hinted" . removeWord "Spacing" . withFG purple
|
2020-03-22 18:06:44 +00:00
|
|
|
, ppHidden = wrap " " " " . unwords . map wrapOpenWorkspaceCmd . words
|
|
|
|
, ppWsSep = ""
|
|
|
|
, ppSep = " | "
|
|
|
|
, ppExtras = []
|
2020-05-09 13:24:23 +00:00
|
|
|
, ppTitle = withFG aqua . (shorten 40)
|
2020-03-22 18:06:44 +00:00
|
|
|
}
|
|
|
|
where
|
2020-03-23 19:23:31 +00:00
|
|
|
removeWord substr = unwords . filter (/= substr) . words
|
2020-03-22 18:06:44 +00:00
|
|
|
withBG col = wrap ("%{B" ++ col ++ "} ") " %{B-}"
|
|
|
|
withFG col = wrap ("%{F" ++ col ++ "} ") " %{F-}"
|
2020-03-23 19:23:31 +00:00
|
|
|
wrapOpenWorkspaceCmd wsp
|
2020-03-22 18:06:44 +00:00
|
|
|
| all isDigit wsp = wrapOnClickCmd ("xdotool key super+" ++ wsp) wsp
|
|
|
|
| otherwise = wsp
|
|
|
|
wrapOnClickCmd command = wrap ("%{A1:" ++ command ++ ":}") "%{A}"
|
|
|
|
|
|
|
|
-- }}}
|
2020-03-23 19:23:31 +00:00
|
|
|
|
2020-03-25 10:05:44 +00:00
|
|
|
-- Utilities --------------------------------------------------- {{{
|
2020-05-09 13:24:23 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
catchAndNotifyAny :: IO () -> IO ()
|
|
|
|
catchAndNotifyAny ioAction = catch ioAction (\(e :: SomeException) -> safeSpawn "notify-send" ["Xmonad exception", show e])
|
|
|
|
|
|
|
|
|
2020-03-25 10:05:44 +00:00
|
|
|
promptDzenWhileRunning :: String -> [String] -> X () -> X ()
|
|
|
|
promptDzenWhileRunning promptTitle options action = do
|
|
|
|
handle <- spawnPipe $ "sleep 1 && dzen2 -e onstart=uncollapse -l " ++ lineCount ++ " -fn '" ++ font ++ "'"
|
|
|
|
io $ SysIO.hPutStrLn handle (promptTitle ++ unlines options)
|
|
|
|
_ <- action
|
|
|
|
io $ SysIO.hClose handle
|
|
|
|
where
|
|
|
|
lineCount = show $ length options
|
|
|
|
font = "-*-iosevka-medium-r-s*--16-87-*-*-*-*-iso10???-1"
|
|
|
|
|
2020-04-01 12:37:33 +00:00
|
|
|
ifLayoutIs :: String -> X a -> X a -> X a
|
|
|
|
ifLayoutIs layoutAName onLayoutA onLayoutB = do
|
|
|
|
layout <- getActiveLayoutDescription
|
|
|
|
if (layout == layoutAName) then onLayoutA else onLayoutB
|
|
|
|
|
|
|
|
-- Get the name of the active layout.
|
|
|
|
getActiveLayoutDescription :: X String
|
|
|
|
getActiveLayoutDescription = (description . W.layout . W.workspace . W.current) <$> gets windowset
|
2020-03-25 10:05:44 +00:00
|
|
|
|
|
|
|
-- }}}
|