Created
December 31, 2018 13:16
-
-
Save fffe/48e2c05c856a3f9c0b70e31e9254a79b to your computer and use it in GitHub Desktop.
xmonad.hs for xinerama with per-screen status bars
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import XMonad | |
import qualified XMonad.StackSet as S | |
import XMonad.Config.Desktop | |
import XMonad.Layout.WindowNavigation | |
import XMonad.Layout.Minimize | |
import XMonad.Layout.Reflect | |
import XMonad.Actions.GroupNavigation | |
import XMonad.Actions.CycleWS | |
import XMonad.Actions.CycleRecentWS | |
import XMonad.Actions.WindowBringer | |
import XMonad.Actions.PhysicalScreens | |
import XMonad.Actions.NoBorders | |
import XMonad.Layout.IM | |
import XMonad.Layout.Grid | |
import XMonad.Layout.NoBorders | |
import XMonad.Layout.PerWorkspace (onWorkspace) | |
import XMonad.Layout.ToggleLayouts | |
import XMonad.Layout.NoFrillsDecoration | |
import XMonad.Hooks.SetWMName (setWMName) | |
import XMonad.Hooks.DynamicLog hiding (xmobar) | |
import XMonad.Hooks.ManageDocks (avoidStruts, manageDocks) | |
import XMonad.Hooks.UrgencyHook | |
import XMonad.Hooks.EwmhDesktops (ewmh, fullscreenEventHook) | |
import XMonad.Hooks.ManageHelpers | |
import XMonad.Util.Run (spawnPipe, hPutStrLn) | |
import XMonad.Util.EZConfig | |
import XMonad.Util.NamedWindows (getName) | |
import Data.Ord (comparing) | |
import Data.List (intercalate, sortBy, isInfixOf) | |
import Data.Maybe (isJust, catMaybes) | |
import Data.Ratio ((%)) | |
import Data.Monoid (All(All), mappend) | |
import Codec.Binary.UTF8.String (encodeString) | |
import Control.Monad (when, zipWithM_, liftM2) | |
import System.Exit (ExitCode(ExitSuccess), exitWith) | |
myTerminal = "urxvt" | |
myActiveColor = "GoldenRod" | |
myInactiveColor = "DimGrey" | |
myTextColor = "Black" | |
myFont = "xft:DejaVu Sans-10:bold" | |
myScreenShotPath = "~/Screenshots/`date +%s%3N`.png" | |
myDmenu = "dmenu -i -nf " ++ myActiveColor ++ " -nb " ++ myTextColor ++ " -sf " ++ myTextColor ++ " -sb " ++ myActiveColor ++ " -fn '" ++ myFont ++ "' -p '>'" | |
main = do | |
xmobar0 <- xmobar 0 "%StdinReader%}{%date%" | |
"[Run StdinReader, Run Date \"%a %b %_d, %r\" \"date\" 10]" | |
xmobar1 <- xmobar 1 "%StdinReader%}{" | |
"[Run StdinReader]" | |
xmonad $ withUrgencyHook NoUrgencyHook desktopConfig { | |
focusFollowsMouse = False | |
, borderWidth = 1 | |
, focusedBorderColor = myActiveColor | |
, normalBorderColor = myInactiveColor | |
, terminal = myTerminal | |
, modMask = mod1Mask | |
, logHook = myLogHook [ pp { ppOutput = hPutStrLn xmobar0 } | |
, pp { ppOutput = hPutStrLn xmobar1 } | |
] | |
, workspaces = myWorkspaces | |
, layoutHook = myLayoutHook | |
, manageHook = myManageHook | |
, startupHook = startupHook desktopConfig >> setWMName "LG3D" -- makes (old?) java applets actually work. | |
, handleEventHook = fullscreenEventHook `mappend` handleEventHook def | |
} | |
`additionalKeysP` | |
[ | |
("M-x c", spawn "google-chrome"), | |
("M-x x", spawn $ "j4-dmenu-desktop --term=" ++ myTerminal ++ " --dmenu=\"" ++ myDmenu ++ "\""), | |
("C-M-l", spawn "xscreensaver-command -lock"), | |
("C-M-k", spawn "keepassx"), | |
("<Print>", spawn $ "scrot -u " ++ myScreenShotPath), | |
("<F12>", spawn $ "scrot -u " ++ myScreenShotPath), | |
("M-<Print>", spawn $ "scrot -s " ++ myScreenShotPath), | |
("M-<F12>", spawn $ "scrot " ++ myScreenShotPath), | |
("M-x <Space>", spawn myTerminal), | |
("C-M-w", gotoMenu), | |
("C-M-s", bringMenu), | |
("M-`", nextMatchWithThis Forward className), | |
("M-S-`", nextMatchWithThis Backward className), | |
("<XF86AudioMute>", spawn "pactl set-sink-mute 1 toggle"), | |
("<XF86AudioLowerVolume>", spawn "pactl -- set-sink-volume 1 -5%"), | |
("<XF86AudioRaiseVolume>", spawn "pactl -- set-sink-volume 1 +5%"), | |
("C-M-<Right>", sendMessage $ Swap R), | |
("C-M-<Left>", sendMessage $ Swap L), | |
("C-M-<Up>", sendMessage $ Swap U), | |
("C-M-<Down>", sendMessage $ Swap D), | |
("C-M-<Pause>", io (exitWith ExitSuccess)) | |
] | |
`additionalKeys` | |
[ | |
((mod1Mask .|. mask, key), f sc) | |
| (key, sc) <- zip [xK_w, xK_e] [0..] -- map M-w to screen 1, M-e to screen 2, ... | |
, (f, mask) <- [(viewScreen, 0), (sendToScreen, shiftMask)] -- M-S-w = move to screen 1, ... | |
] | |
`removeKeys` | |
[ | |
((mod1Mask .|. shiftMask, xK_q)) | |
] | |
-- if you use 'windowNavigation' instead of 'configurableNavigation noNavigateBorders', | |
-- you'll get weird coloring/shading of inactive window borders. | |
myLayoutHook = | |
configurableNavigation noNavigateBorders | |
-- No borders around single-window-on-screen, with Xinerama (smartBorders doesn't work in that case) | |
$ lessBorders (Combine Difference Screen OnlyFloat) | |
$ defaultLayout | |
where | |
defaultLayout | |
= avoidStruts | |
$ noFrillsDeco shrinkText myTheme | |
$ onWorkspace "4:im" chatLayout | |
$ minimize | |
$ layoutHook def | |
chatLayout = reflectHoriz $ noBorders $ withIM (1%6) pidginRoster Grid | |
pidginRoster = And (ClassName "Pidgin") (Role "buddy_list") | |
-- Theme for window decorations | |
myTheme = def { | |
activeColor = myActiveColor | |
, activeTextColor = myTextColor | |
, activeBorderColor = myActiveColor | |
, inactiveColor = myInactiveColor | |
, inactiveBorderColor = myInactiveColor | |
, fontName = myFont | |
} | |
-- Set up a mix of 9 named/unnamed workspaces | |
myWorkspaces = ["1:term", "2:web", "3:local", "4:im", "5:vm", "6:files", "7:gimp"] ++ map show [8..9] | |
myManageHook = manageDocks <+> manageFloats <+> manageApps | |
where manageFloats = composeOne [ isFullscreen -?> doFullFloat | |
, isDialog -?> doFloat | |
] | |
manageApps = composeAll [ | |
className =? "URxvt" --> moveTo "1:term", | |
className =? "Google-chrome" --> moveTo "2:web", | |
className =? "Psi-plus" --> moveTo "4:im", | |
className =? "Pidgin" --> moveTo "4:im", | |
className =? "Virt-manager" --> moveTo "5:vm", | |
className =? "Remote-viewer" --> moveTo "5:vm", | |
className =? "Thunar" --> moveTo "6:files", | |
className =? "Gimp" --> moveTo "7:gimp", | |
className =? "Keepassx" --> doFloat | |
] | |
moveTo = doF . liftM2 (.) S.view S.shift | |
xmobar screen template commands = spawnPipe . unwords $ options | |
where options = [ "xmobar" | |
, "-x" | |
, show screen | |
, "-t" | |
, wrap "'" "'" template | |
, "-c" | |
, wrap "'" "'" commands | |
] | |
-- Tweak pretty printer for xmobar output | |
pp = def { | |
ppHiddenNoWindows = xmobarColor myInactiveColor "" . pad | |
, ppCurrent = xmobarColor "White" myInactiveColor . pad | |
, ppVisible = pad | |
, ppHidden = pad | |
, ppUrgent = xmobarColor "Black" myActiveColor . xmobarStrip | |
, ppLayout = xmobarColor "LightSkyBlue" "" . pad . iconify | |
, ppTitle = xmobarColor "White" "" . pad . xmobarStrip . shorten 200 | |
, ppWsSep = "" | |
, ppSep = "" | |
} | |
where | |
iconify l | "Mirror" `isInfixOf` l = "[-]" -- text icon for each layout | |
| "Grid" `isInfixOf` l = "[+]" | |
| "Tall" `isInfixOf` l = "[|]" | |
| "Full" `isInfixOf` l = "[ ]" | |
| otherwise = l | |
-- A whole lot of hateful magicke for per-screen active window titles in the taskbar. | |
myLogHook pps = do | |
screens <- (sortBy (comparing S.screen) . S.screens) `fmap` gets windowset | |
zipWithM_ dynamicLogWithPP' screens pps | |
-- Extract the focused window from the stack of windows on the given screen. | |
-- Return Just that window, or Nothing for an empty stack. | |
focusedWindow = maybe Nothing (return . S.focus) . S.stack . S.workspace | |
-- The functions dynamicLogWithPP', dynamicLogString', and pprWindowSet' below | |
-- are similar to their undashed versions, with the difference being that the | |
-- latter operate on the current screen, whereas the former take the screen to | |
-- operate on as the first argument. | |
dynamicLogWithPP' screen pp = dynamicLogString' screen pp >>= io . ppOutput pp | |
dynamicLogString' screen pp = do | |
winset <- gets windowset | |
urgents <- readUrgents | |
sort' <- ppSort pp | |
-- layout description | |
let ld = description . S.layout . S.workspace $ screen | |
-- workspace list | |
let ws = pprWindowSet' screen sort' urgents pp winset | |
-- window title | |
wt <- maybe (return "") (fmap show . getName) $ focusedWindow screen | |
-- run extra loggers, ignoring any that generate errors. | |
extras <- mapM (`catchX` return Nothing) $ ppExtras pp | |
return $ encodeString $ sepBy (ppSep pp) . ppOrder pp $ | |
[ ws | |
, ppLayout pp ld | |
, ppTitle pp wt | |
] | |
++ catMaybes extras | |
pprWindowSet' screen sort' urgents pp s = sepBy (ppWsSep pp) . map fmt . sort' $ S.workspaces s | |
where this = S.tag . S.workspace $ screen | |
visibles = map (S.tag . S.workspace) (S.current s : S.visible s) | |
fmt w = printer pp (S.tag w) | |
where printer | S.tag w == this = ppCurrent | |
| S.tag w `elem` visibles = ppVisible | |
| any (\x -> maybe False (== S.tag w) (S.findTag x s)) urgents = \ppC -> ppUrgent ppC . ppHidden ppC | |
| isJust (S.stack w) = ppHidden | |
| otherwise = ppHiddenNoWindows | |
sepBy :: String -> [String] -> String | |
sepBy sep = intercalate sep . filter (not . null) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
export SSH_ASKPASS=/usr/bin/ssh-askpass | |
# fuck. middle. mouse. paste. | |
xmodmap -e "pointer = 1 25 3 4 5 6 7 8 9 10 11 12 13 14 15 16" | |
# load prefs | |
xrdb -merge $HOME/.Xresources | |
# black background | |
xsetroot -solid black | |
# sound | |
pulseaudio --start | |
# color calibration | |
xcalib $HOME/.monitor/monitor.icm | |
# compositing | |
compton -bCG | |
# xscreensaver | |
/usr/share/xscreensaver/xscreensaver-wrapper.sh -nosplash & | |
# background | |
feh --bg-fill --no-fehbg $HOME/Wallpapers/bg.jpg | |
# systray | |
stalonetray -i 16 --icon-gravity E --geometry 8x1-1920+1060 --sticky --skip-taskbar --background black & | |
# sound applet for systray | |
pasystray & | |
exec xmonad |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment