{-# LANGUAGE ImportQualifiedPost #-} import Data.Map qualified as M import System.Exit import XMonad import XMonad.Actions.Navigation2D import XMonad.Hooks.DynamicLog import XMonad.Hooks.EwmhDesktops import XMonad.Hooks.FloatConfigureReq import XMonad.Hooks.ManageDocks import XMonad.Hooks.ManageHelpers import XMonad.Hooks.StatusBar import XMonad.Layout.BinarySpacePartition import XMonad.Layout.BorderResize import XMonad.Layout.NoBorders import XMonad.Layout.Spacing import XMonad.Layout.ToggleLayouts import XMonad.StackSet qualified as W import XMonad.Util.ClickableWorkspaces import XMonad.Util.EZConfig import XMonad.Util.Hacks import XMonad.Util.NamedScratchpad import XMonad.Util.Run import XMonad.Util.WorkspaceCompare -- Define the color scheme using the Catppuccin palette catppuccinColors :: (String, String, String, String, String, String, String) catppuccinColors = ( "#89b4fa" -- blue , "#f38ba8" -- red , "#a6e3a1" -- green , "#f9e2af" -- yellow , "#f5c2e7" -- pink , "#cdd6f4" -- white , "#45475a" -- grey ) -- XMobar configuration xmobarConf :: PP xmobarConf = def { ppSep = yellowC " | " , ppTitleSanitize = xmobarStrip , ppCurrent = xmobarBorder "Top" blue 2 . pad , ppHidden = whiteC . pad , ppHiddenNoWindows = greyC . pad , ppUrgent = redC . wrap (yellowC "!") (yellowC "!") , ppOrder = \[ws, l, _] -> [ws, l] } where (blue, red, _, yellow, _, white, grey) = catppuccinColors xmobarColorWith :: String -> String -> String xmobarColorWith color = xmobarColor color "" redC = xmobarColorWith red yellowC = xmobarColorWith yellow whiteC = xmobarColorWith white greyC = xmobarColorWith grey main :: IO () main = do xmproc <- spawnPipe "xmobar" xmonad $ javaHack $ navigation2D def (xK_k, xK_h, xK_j, xK_l) [ (mod4Mask, windowGo) , (mod4Mask .|. shiftMask, windowSwap) ] False $ docks $ addEwmhWorkspaceSort (pure (filterOutWs [scratchpadWorkspaceTag])) $ ewmhFullscreen $ ewmh $ withEasySB (statusBarProp "xmobar ~/.xmonad/xmobar/xmobar.hs" (clickablePP (filterOutWsPP [scratchpadWorkspaceTag] xmobarConf))) defToggleStrutsKey myConfig myConfig = def { modMask = mod4Mask , layoutHook = lessBorders OnlyScreenFloat $ avoidStruts $ spacingRaw False (Border 10 10 10 10) True (Border 10 10 10 10) True $ borderResize emptyBSP , terminal = myTerminal , keys = myKeys , borderWidth = 2 , normalBorderColor = "#6c7086" , focusedBorderColor = "#a6e3a1" , handleEventHook = fixSteamFlicker , startupHook = addExclusives [["vesktop", "telegram"]] , manageHook = composeAll [ namedScratchpadManageHook scratchpads , isFullscreen --> doFullFloat ] } `additionalKeysP` myAdditionalKeys scratchpads :: [NamedScratchpad] scratchpads = [ NS "vesktop" "vesktop" (className =? "vesktop") (rectCentered 0.7) , NS "telegram" "telegram-desktop" (className =? "TelegramDesktop") (rectCentered 0.7) ] where rectCentered percentage = customFloating $ W.RationalRect offset offset percentage percentage where offset = (1 - percentage) / 2 -- Application Launchers myFileManager, myBrowser, myTerminal :: String myFileManager = "nautilus" myBrowser = "firefox-nightly" myTerminal = "wezterm" rofiMacro :: String rofiMacro = "rofi -show" centerRect :: W.RationalRect centerRect = W.RationalRect 0.25 0.25 0.5 0.5 -- Functions for Floating Windows floatOrNot :: X () -> X () -> X () floatOrNot float notFloat = withFocused $ \windowId -> do floats <- gets (W.floating . windowset) if windowId `M.member` floats then float else notFloat centerFloat' :: Window -> X () centerFloat' window = windows $ W.float window centerRect toggleFloat :: X () toggleFloat = floatOrNot (withFocused $ windows . W.sink) (withFocused centerFloat') -- Keybindings myAdditionalKeys :: [(String, X ())] myAdditionalKeys = [ ("M-", spawn myTerminal) , ("M-r", spawn $ rofiMacro ++ " drun") , ("M-w", spawn myBrowser) , ("M-e", spawn myFileManager) , ("M-q", kill) , ("M-d", namedScratchpadAction scratchpads "vesktop") , ("M-t", namedScratchpadAction scratchpads "telegram") , ("M-S-e", resetFocusedNSP) , ("M-S-s", spawn "screenshot --window") , ("M-C-3", spawn "screenshot --screen") , ("M-C-4", spawn "screenshot --area") , ("M-C-h", sendMessage $ ExpandTowards L) , ("M-C-j", sendMessage $ ExpandTowards D) , ("M-C-k", sendMessage $ ExpandTowards U) , ("M-C-l", sendMessage $ ExpandTowards R) , ("M-", toggleFloat) , ("M-m", withFocused hide) , ("M-n", sendMessage $ Toggle "Full") , ("M-S-q", io exitSuccess) , ("M-S-r", spawn "xmonad --recompile; xmonad --restart") , ("", spawn "playerctl play-pause") , ("", spawn "playerctl next") , ("", spawn "playerctl previous") ] myKeys :: XConfig l -> M.Map (KeyMask, KeySym) (X ()) myKeys conf@XConfig {XMonad.modMask = modm} = M.fromList $ [ ((m .|. modm, k), windows $ f i) | (i, k) <- zip (workspaces conf) [xK_1 .. xK_9] , (f, m) <- [(W.greedyView, 0), (W.shift, shiftMask)] ]