import XMonad import XMonad.StackSet as F import XMonad.ManageHook import XMonad.Layout.Spacing import XMonad.Layout.ThreeColumns import XMonad.Layout.Magnifier import XMonad.ManageHook import XMonad.Hooks.DynamicLog import XMonad.Hooks.ManageDocks import XMonad.Hooks.ManageHelpers import XMonad.Hooks.UrgencyHook import XMonad.Hooks.EwmhDesktops import XMonad.Hooks.WindowSwallowing import XMonad.Util.EZConfig import XMonad.Util.NamedActions import XMonad.Util.NamedScratchpad import XMonad.Util.Run import XMonad.Util.SpawnOnce import qualified Codec.Binary.UTF8.String as UTF8 import qualified DBus as D import qualified DBus.Client as D import Graphics.X11.ExtraTypes.XF86 main :: IO () main = mkDbusClient >>= main' main' :: D.Client -> IO () main' dbus = xmonad . docks . ewmh . ewmhFullscreen $ def { terminal = myTerminal , borderWidth = 3 , modMask = myModMask , layoutHook = spacingWithEdge 10 $ myLayout , manageHook = namedScratchpadManageHook scratchpads , logHook = dynamicLogWithPP (myLogHook dbus) , startupHook = myStartupHook , handleEventHook = swallowEventHook (className =? "Alacritty") (return True) } `additionalKeysP` myKeys myStartupHook = do spawnOnce "nitrogen --restore" spawnOnce "lxsession" spawnOnce "picom -b" spawn "polybar" spawnOnce "~/.xmonad/layoutXmonad.sh" mkDbusClient :: IO D.Client mkDbusClient = do dbus <- D.connectSession D.requestName dbus (D.busName_ "org.xmonad.log") opts return dbus where opts = [D.nameAllowReplacement, D.nameReplaceExisting, D.nameDoNotQueue] -- Emit a DBus signal on log updates dbusOutput :: D.Client -> String -> IO () dbusOutput dbus str = let opath = D.objectPath_ "/org/xmonad/Log" iname = D.interfaceName_ "org.xmonad.Log" mname = D.memberName_ "Update" signal = D.signal opath iname mname body = [D.toVariant $ UTF8.decodeString str] in D.emit dbus $ signal { D.signalBody = body } myLogHook :: D.Client -> PP myLogHook dbus = def { ppSep = magenta " • " , ppTitleSanitize = xmobarStrip , ppCurrent = wrap " " "" . xmobarBorder "Top" "#8be9fd" 2 , ppHidden = white . wrap " " "" , ppHiddenNoWindows = lowWhite . wrap " " "" , ppUrgent = red . wrap (yellow "!") (yellow "!") , ppOrder = \[ws, l, _, wins] -> [ws, l, wins] -- , ppExtras = [formatFocused formatUnfocused] } where formatFocused = wrap (white "[") (white "]") . magenta . ppWindow formatUnfocused = wrap (lowWhite "[") (lowWhite "]") . blue . ppWindow -- | Windows should have *some* title, which should not not exceed a -- sane length. ppWindow :: String -> String ppWindow = xmobarRaw . (\w -> if null w then "untitled" else w) . shorten 30 blue, lowWhite, magenta, red, white, yellow :: String -> String magenta = xmobarColor "#ff79c6" "" blue = xmobarColor "#bd93f9" "" white = xmobarColor "#f8f8f2" "" yellow = xmobarColor "#f1fa8c" "" red = xmobarColor "#ff5555" "" lowWhite = xmobarColor "#bbbbbb" "" myTerminal = "alacritty" myModMask = mod1Mask myLayout = avoidStruts tiled ||| Mirror tiled ||| Full ||| threeCol where threeCol = magnifiercz' 1.3 $ ThreeColMid nmaster delta ratio tiled = Tall nmaster delta ratio nmaster = 1 -- Default number of windows in the master pane ratio = 1/2 -- Default proportion of screen occupied by master pane delta = 3/100 -- Percent of screen to increment by when resizing panes myKeys :: [(String, X ())] myKeys = [ ("" , spawn "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle") , ("" , spawn "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-") , ("" , spawn "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+") , ( "M-C-m" , namedScratchpadAction scratchpads "music") , ( "M-C-t" , namedScratchpadAction scratchpads "term") , ( "M-C-c" , namedScratchpadAction scratchpads "qalc") ] scratchpads :: NamedScratchpads scratchpads = [ NS "music" spawnMusic findMusic manageMusic , NS "term" spawnTerm findTerm manageTerm , NS "qalc" spawnQalc findQalc manageQalc ] where spawnMusic = "~/.xmonad/cider.sh" findMusic = className =? "Cider" manageMusic = customFloating $ F.RationalRect l t w h where h = 0.5 w = 0.4 t = 0.75 -h l = 0.70 -w spawnTerm = "st" ++ " -n scratchpad" findTerm = resource =? "scratchpad" manageTerm = customFloating $ F.RationalRect l t w h where h = 0.5 w = 0.4 t = 0.75 -h l = 0.70 -w spawnQalc = "qalculate-gtk" findQalc = className =? "Qalculate" manageQalc = customFloating $ F.RationalRect l t w h where h = 0.7 w = 0.4 t = 0.75 -h l = 0.70 -w