``` -- IMPORTS import XMonad hiding ( (|||) ) -- jump to layout import XMonad.Prompt import XMonad.Prompt.Shell import XMonad.Layout.LayoutCombinators (JumpToLayout(..), (|||)) -- jump to layout import XMonad.Config.Desktop import XMonad.Util.SpawnOnce import XMonad.Util.Run import XMonad.Util.EZConfig (additionalKeysP) import XMonad.Util.NamedWindows import XMonad.Util.NamedScratchpad import XMonad.Hooks.ManageDocks import XMonad.Hooks.EwmhDesktops import XMonad.Hooks.ManageHelpers import XMonad.Hooks.DynamicLog import XMonad.Hooks.UrgencyHook import qualified XMonad.StackSet as W import qualified Data.Map as M -- actions import XMonad.Actions.CopyWindow -- for dwm window style tagging import XMonad.Actions.SpawnOn import XMonad.Actions.UpdateFocus -- layout import XMonad.Layout.Renamed (renamed, Rename(Replace)) import XMonad.Layout.NoBorders import XMonad.Layout.Spacing import XMonad.Layout.GridVariants -- import XMonad.Layout.ResizableTile -- import XMonad.Layout.BinarySpacePartition -- The preferred terminal program, which is used in a binding below and by -- certain contrib modules. -- myTerminal :: String myScratchterm :: String mySurf :: String myTerminal = "st" myScratchterm = "st" mySurf = "tabbed surf -e" -- Whether focus follows the mouse pointer. myFocusFollowsMouse :: Bool myFocusFollowsMouse = False -- Whether clicking on a window to focus also passes the click to the window myClickJustFocuses :: Bool myClickJustFocuses = true -- Width of the window border in pixels. -- myBorderWidth = 2 -- modMask lets you specify which modkey you want to use. The default -- is mod1Mask ("left alt"). You may also consider using mod3Mask -- ("right alt"), which does not conflict with emacs keybindings. The -- "windows key" is usually mod4Mask. -- myModMask :: KeyMask myModMask = mod4Mask -- The default number of workspaces (virtual screens) and their names. -- By default we use numeric strings, but any string may be used as a -- workspace name. The number of workspaces is determined by the length -- of this list. -- -- A tagging example: -- -- > workspaces = ["web", "irc", "code" ] ++ map show [4..9] -- xmobarEscape :: [Char] -> [Char] xmobarEscape = concatMap doubleLts where doubleLts '<' = "<<" doubleLts x = [x] myWorkspaces :: [String] myWorkspaces = clickable . map xmobarEscape $ ["1:chat", "2:web", "3:shell", "4:work", "5:games", "6:dev", "7:mail", "8:misc", "9:doc"] where -- Make workspaces clickable. Needs xdotool. clickable l = [ "" ++ ws ++ "" | (i,ws) <- zip [1..9] l, let n = i ] -- Scratchpads scratchpads :: [NamedScratchpad] scratchpads = [ NS "notepad" spawnPad findPad managePad ] spawnPad :: String findPad :: Query Bool managePad :: ManageHook spawnPad = myScratchterm ++ " -n notepad ~/bin/scratchpad" findPad = resource =? "notepad" managePad = customFloating $ W.RationalRect l t w h where h = 0.9 w = 0.9 t = 0.95 -h l = 0.95 -w windowCount :: X (Maybe String) windowCount = gets $ Just . show . length . W.integrate' . W.stack . W.workspace . W.current . windowset -- Border colors for unfocused and focused windows, respectively. -- myNormalBorderColor :: String myFocusedBorderColor :: String myppCurrent :: String myppVisible :: String myppHidden :: String myppHiddenNoWindows :: String myppTitle :: String myppUrgent :: String myNormalBorderColor = "#181817" myFocusedBorderColor = "#00FF00" myppCurrent = "#cb4b16" myppVisible = "#cb4b16" myppHidden = "#268bd2" myppHiddenNoWindows = "#93A1A1" myppTitle = "#FDF6E3" myppUrgent = "#DC322F" -- Desktop notifications data LibNotifyUrgencyHook = LibNotifyUrgencyHook deriving (Read, Show) instance UrgencyHook LibNotifyUrgencyHook where urgencyHook LibNotifyUrgencyHook w = do name <- getName w Just idx <- W.findTag w <$> gets windowset safeSpawn "notify-send" [show name, "workspace " ++ idx] ------------------------------------------------------------------------ -- Key bindings. Add, modify or remove key bindings here. -- myKeys :: [([Char], X ())] myKeys = -- [("M-" ++ m ++ k, windows $ f i) -- | (i, k) <- zip myWorkspaces (map show [1 :: Int ..]) -- , (f, m) <- [(W.greedyView, ""), (W.shift, "S-"), (copy, "S-C-")]] -- ++ -- [("S-C-a", windows copyToAll) -- copy window to all workspaces , ("S-C-z", killAllOtherCopies) -- kill copies of window on other workspaces , ("M-", spawn myTerminal) , ("C-mod1-t", spawn myTerminal) , ("M-x", kill1) , ("M-e", spawn thunar) , ("M-S-s", spawn mySurf) , ("M-a", sendMessage MirrorExpand) , ("M-z", sendMessage MirrorShrink) , ("M-s", sendMessage ToggleStruts) --, ("M-f", sendMessage $ JumpToLayout "Full") --, ("M-t", sendMessage $ JumpToLayout "Tall") , ("M-g", sendMessage $ JumpToLayout "Grid") --, ("M-b", sendMessage $ JumpToLayout "BSP") , ("M-w", spawn "rofi -show run") -- dmenu , ("M-" ++ , withFocused $ windows . W.sink) -- flatten floating window to tiled -- , ("M1-C-l", spawn "loginctl lock-session") -- , ("M-S-p", spawn "passmenu") -- , ("C-M1-w", spawn "~/bin/wallpaper.sh -s") -- , ("M-e", spawn "emojimenu") -- , ("M-S-l", spawn "bin/lastpass-dmenu copy") -- , ("M-S-o", spawn "bin/nitro-otp") -- , ("M1-C-n", spawn "bin/showdeadd") -- , ("M-C-n", namedScratchpadAction scratchpads "notepad") ] ------------------------------------------------------------------------ -- Mouse bindings: default actions bound to mouse events -- -- myMouseBindings XConfig {XMonad.modMask = modm} = M.fromList -- mod-button1, Set the window to floating mode and move by dragging -- [ ((modm, button1), \w -> focus w >> mouseMoveWindow w -- >> windows W.shiftMaster) -- mod-button2, Raise the window to the top of the stack --, ((modm, button2), \w -> focus w >> windows W.shiftMaster) -- mod-button3, Set the window to floating mode and resize by dragging --, ((modm, button3), \w -> focus w >> mouseResizeWindow w -- >> windows W.shiftMaster) -- you may also bind events to the mouse scroll wheel (button4 and button5) --] ------------------------------------------------------------------------ -- Layouts: -- You can specify and transform your layouts by modifying these values. -- If you change layout bindings be sure to use 'mod-shift-space' after -- restarting (with 'mod-q') to reset your layout state to the new -- defaults, as xmonad preserves your old layout settings by default. -- -- The available layouts. Note that each layout is separated by |||, -- which denotes layout choice. -- myLayout = GridRatio (16/9) ||| Grid ------------------------------------------------------------------------ -- Window rules: -- Execute arbitrary actions and WindowSet manipulations when managing -- a new window. You can use this to, for example, always float a -- particular program, or have a client always appear on a particular -- workspace. -- -- To find the property name associated with a program, use -- > xprop | grep WM_CLASS -- and click on the client you're interested in. -- -- To match on the WM_NAME, you can use 'title' in the same way that -- 'className' and 'resource' are used below. myManageHook = composeAll [ className =? "MPlayer" --> doFloat , className =? "Gimp" --> doFloat , className =? "Shadow" --> doCenterFloat , resource =? "desktop_window" --> doIgnore , resource =? "kdesktop" --> doIgnore , isDialog --> doCenterFloat ] ------------------------------------------------------------------------ -- Startup hook -- Perform an arbitrary action each time xmonad starts or is restarted -- with mod-q. Used by, e.g., XMonad.Layout.PerWorkspace to initialize -- per-workspace layout choices. -- -- By default, do nothing. myStartupHook :: X () myStartupHook = do spawn "~/.xmonad/.startup.sh" ------------------------------------------------------------------------ -- Now run xmonad with all the defaults we set up. -- Run xmonad with the settings you specify. No need to modify this. -- main :: IO () main = do -- xmproc0 <- spawnPipe "xmobar " { manageHook = namedScratchpadManageHook scratchpads <+> manageSpawn <+> manageDocks <+> myManageHook <+> manageHook desktopConfig , startupHook = myStartupHook , layoutHook = spacingRaw True (Border 0 2 0 2) True (Border 2 0 2 0) True $ smartBorders ||| Grid , handleEventHook = handleEventHook desktopConfig <+> fullscreenEventHook <-> focusOnMouseMove , workspaces = myWorkspaces , borderWidth = myBorderWidth , terminal = myTerminal , modMask = myModMask , normalBorderColor = myNormalBorderColor , focusedBorderColor = myFocusedBorderColor -- , logHook = dynamicLogWithPP xmobarPP -- { ppOutput = \x -> hPutStrLn xmproc0 x >> hPutStrLn xmproc1 x >> hPutStrLn xmproc2 x -- , ppCurrent = xmobarColor myppCurrent "" . wrap "[" "]" -- Current workspace in xmobar -- , ppVisible = xmobarColor myppVisible "" -- Visible but not current workspace -- , ppHidden = xmobarColor myppHidden "" . wrap "+" "" -- Hidden workspaces in xmobar -- , ppHiddenNoWindows = xmobarColor myppHiddenNoWindows "" -- Hidden workspaces (no windows) -- , ppTitle = xmobarColor myppTitle "" . shorten 80 -- Title of active window in xmobar -- , ppSep = " | " -- Separators in xmobar -- , ppUrgent = xmobarColor myppUrgent "" . wrap "!" "!" -- Urgent workspace -- , ppExtras = [windowCount] -- # of windows current workspace -- , ppOrder = \(ws:l:t:ex) -> [ws,l]++ex++[t] -- } } `additionalKeysP` myKeys ```