Difference between revisions of "Xmonad/Config archive/Thomas ten Cate's xmonad.hs"

From HaskellWiki
Jump to navigation Jump to search
m
(Deleting page that hasn't been edited for over 10 years)
Line 1: Line 1:
[[Category:XMonad configuration]]
 
<haskell>
 
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, TypeSynonymInstances, FlexibleContexts, NoMonomorphismRestriction #-}
 
 
-- XMonad configuration file by Thomas ten Cate <ttencate@gmail.com>
 
--
 
-- Works on xmonad-0.8, NOT on 0.7 or below; and of course
 
-- xmonad-contrib needs to be installed as well
 
--
 
-- This is designed to play nice with a standard Ubuntu Hardy installation.
 
-- It gives you 10 workspaces, available through Alt+F1..F10. You can move
 
-- windows to a workspace with Win+F1..F10 (and you will automatically switch
 
-- to that workspace too).
 
--
 
-- All workspaces except F9 respect panels and docks.
 
-- F9 is the fullscreen workspace (for mplayer, etc.).
 
-- F10 is the instant messaging workspace.
 
--
 
-- Pidgin and Skype windows are automatically placed onto the IM workspace.
 
-- Their contact lists each get a column on the right side of the screen,
 
-- and all their other windows (chat windows, etc.) go into a grid layout
 
-- in the remaining space.
 
-- (This uses a copied and modified version of XMonad.Layout.IM.)
 
--
 
-- Keybindings mostly use the Windows key, but some use Alt to mimic other
 
-- window managers. In general: Alt is used for navigation, Win for modification.
 
-- Some of the bindings resemble the XMonad defaults, but most don't.
 
-- The bindings are set up to be comfortable to use on a dvorak keyboard layout.
 
--
 
-- Navigation:
 
-- Alt+F1..F10 switch to workspace
 
-- Ctrl+Alt+Left/Right switch to previous/next workspace
 
-- Alt+Tab focus next window
 
-- Alt+Shift+Tab focus previous window
 
--
 
-- Window management:
 
-- Win+F1..F10 move window to workspace
 
-- Win+Up/Down move window up/down
 
-- Win+C close window
 
-- Alt+ScrollUp/Down move focused window up/down
 
-- Win+M move window to master area
 
-- Win+N refresh the current window
 
-- Alt+LMB move floating window
 
-- Alt+MMB resize floating window
 
-- Alt+RMB unfloat floating window
 
-- Win+T unfloat floating window
 
--
 
-- Layout management:
 
-- Win+Left/Right shrink/expand master area
 
-- Win+W/V move more/less windows into master area
 
-- Win+Space cycle layouts
 
--
 
-- Other:
 
-- Win+Enter start a terminal
 
-- Win+R open the Gnome run dialog
 
-- Win+Q restart XMonad
 
-- Win+Shift+Q display Gnome shutdown dialog
 
 
import XMonad
 
import XMonad.Util.EZConfig
 
import qualified XMonad.StackSet as S
 
import XMonad.Actions.CycleWS
 
import XMonad.Config.Gnome
 
import XMonad.Hooks.EwmhDesktops
 
import XMonad.Hooks.ManageDocks
 
import XMonad.Layout.Combo
 
import XMonad.Layout.Grid
 
import XMonad.Layout.LayoutModifier
 
import XMonad.Layout.Named
 
import XMonad.Layout.NoBorders
 
import XMonad.Layout.PerWorkspace
 
import XMonad.Layout.Reflect
 
import XMonad.Layout.TwoPane
 
import XMonad.Layout.WindowNavigation
 
import XMonad.Util.WindowProperties
 
import Control.Monad
 
import Data.Ratio
 
import qualified Data.Map as M
 
 
-- defaults on which we build
 
-- use e.g. defaultConfig or gnomeConfig
 
myBaseConfig = gnomeConfig
 
 
-- display
 
-- replace the bright red border with a more stylish colour
 
myBorderWidth = 2
 
myNormalBorderColor = "#202030"
 
myFocusedBorderColor = "#A0A0D0"
 
 
-- workspaces
 
myWorkspaces = ["web", "editor", "terms"] ++ (miscs 5) ++ ["fullscreen", "im"]
 
where miscs = map (("misc" ++) . show) . (flip take) [1..]
 
isFullscreen = (== "fullscreen")
 
 
-- layouts
 
basicLayout = Tall nmaster delta ratio where
 
nmaster = 1
 
delta = 3/100
 
ratio = 1/2
 
tallLayout = named "tall" $ avoidStruts $ basicLayout
 
wideLayout = named "wide" $ avoidStruts $ Mirror basicLayout
 
singleLayout = named "single" $ avoidStruts $ noBorders Full
 
fullscreenLayout = named "fullscreen" $ noBorders Full
 
imLayout = avoidStruts $ reflectHoriz $ withIMs ratio rosters chatLayout where
 
chatLayout = Grid
 
ratio = 1%6
 
rosters = [skypeRoster, pidginRoster]
 
pidginRoster = And (ClassName "Pidgin") (Role "buddy_list")
 
skypeRoster = (ClassName "Skype") `And` (Not (Title "Options")) `And` (Not (Role "Chats")) `And` (Not (Role "CallWindowForm"))
 
 
myLayoutHook = fullscreen $ im $ normal where
 
normal = tallLayout ||| wideLayout ||| singleLayout
 
fullscreen = onWorkspace "fullscreen" fullscreenLayout
 
im = onWorkspace "im" imLayout
 
 
-- special treatment for specific windows:
 
-- put the Pidgin and Skype windows in the im workspace
 
myManageHook = imManageHooks <+> manageHook myBaseConfig
 
imManageHooks = composeAll [isIM --> moveToIM] where
 
isIM = foldr1 (<||>) [isPidgin, isSkype]
 
isPidgin = className =? "Pidgin"
 
isSkype = className =? "Skype"
 
moveToIM = doF $ S.shift "im"
 
 
-- Mod4 is the Super / Windows key
 
myModMask = mod4Mask
 
altMask = mod1Mask
 
 
-- better keybindings for dvorak
 
myKeys conf = M.fromList $
 
[ ((myModMask , xK_Return), spawn $ XMonad.terminal conf)
 
, ((myModMask , xK_r ), gnomeRun)
 
, ((myModMask , xK_c ), kill)
 
, ((myModMask , xK_space ), sendMessage NextLayout)
 
, ((myModMask , xK_n ), refresh)
 
, ((myModMask , xK_m ), windows S.swapMaster)
 
, ((altMask , xK_Tab ), windows S.focusDown)
 
, ((altMask .|. shiftMask , xK_Tab ), windows S.focusUp)
 
, ((myModMask , xK_Down ), windows S.swapDown)
 
, ((myModMask , xK_Up ), windows S.swapUp)
 
, ((myModMask , xK_Left ), sendMessage Shrink)
 
, ((myModMask , xK_Right ), sendMessage Expand)
 
, ((myModMask , xK_t ), withFocused $ windows . S.sink)
 
, ((myModMask , xK_w ), sendMessage (IncMasterN 1))
 
, ((myModMask , xK_v ), sendMessage (IncMasterN (-1)))
 
, ((myModMask , xK_q ), broadcastMessage ReleaseResources >> restart "xmonad" True)
 
, ((myModMask .|. shiftMask, xK_q ), spawn "gnome-session-save --kill")
 
, ((altMask .|. controlMask, xK_Left ), prevWS)
 
, ((altMask .|. controlMask, xK_Right ), nextWS)
 
] ++
 
-- Alt+F1..F10 switches to workspace
 
-- (Alt is in a nicer location for the thumb than the Windows key,
 
-- and 1..9 keys are already in use by Firefox, irssi, ...)
 
[ ((altMask, k), windows $ S.greedyView i)
 
| (i, k) <- zip myWorkspaces workspaceKeys
 
] ++
 
-- mod+F1..F10 moves window to workspace and switches to that workspace
 
[ ((myModMask, k), (windows $ S.shift i) >> (windows $ S.greedyView i))
 
| (i, k) <- zip myWorkspaces workspaceKeys
 
]
 
where workspaceKeys = [xK_F1 .. xK_F10]
 
 
-- mouse bindings that mimic Gnome's
 
myMouseBindings (XConfig {XMonad.modMask = modMask}) = M.fromList $
 
[ ((altMask, button1), (\w -> focus w >> mouseMoveWindow w))
 
, ((altMask, button2), (\w -> focus w >> mouseResizeWindow w))
 
, ((altMask, button3), (\w -> focus w >> (withFocused $ windows . S.sink)))
 
, ((altMask, button4), (const $ windows S.swapUp))
 
, ((altMask, button5), (const $ windows S.swapDown))
 
]
 
 
-- put it all together
 
main = xmonad $ myBaseConfig
 
{ modMask = myModMask
 
, workspaces = myWorkspaces
 
, layoutHook = myLayoutHook
 
, manageHook = myManageHook
 
, borderWidth = myBorderWidth
 
, normalBorderColor = myNormalBorderColor
 
, focusedBorderColor = myFocusedBorderColor
 
, keys = myKeys
 
, mouseBindings = myMouseBindings
 
}
 
 
-- modified version of XMonad.Layout.IM --
 
 
-- | Data type for LayoutModifier which converts given layout to IM-layout
 
-- (with dedicated space for the roster and original layout for chat windows)
 
data AddRosters a = AddRosters Rational [Property] deriving (Read, Show)
 
 
instance LayoutModifier AddRosters Window where
 
modifyLayout (AddRosters ratio props) = applyIMs ratio props
 
modifierDescription _ = "IMs"
 
 
-- | Modifier which converts given layout to IMs-layout (with dedicated
 
-- space for rosters and original layout for chat windows)
 
withIMs :: LayoutClass l a => Rational -> [Property] -> l a -> ModifiedLayout AddRosters l a
 
withIMs ratio props = ModifiedLayout $ AddRosters ratio props
 
 
-- | IM layout modifier applied to the Grid layout
 
gridIMs :: Rational -> [Property] -> ModifiedLayout AddRosters Grid a
 
gridIMs ratio props = withIMs ratio props Grid
 
 
hasAnyProperty :: [Property] -> Window -> X Bool
 
hasAnyProperty [] _ = return False
 
hasAnyProperty (p:ps) w = do
 
b <- hasProperty p w
 
if b then return True else hasAnyProperty ps w
 
 
-- | Internal function for placing the rosters specified by
 
-- the properties and running original layout for all chat windows
 
applyIMs :: (LayoutClass l Window) =>
 
Rational
 
-> [Property]
 
-> S.Workspace WorkspaceId (l Window) Window
 
-> Rectangle
 
-> X ([(Window, Rectangle)], Maybe (l Window))
 
applyIMs ratio props wksp rect = do
 
let stack = S.stack wksp
 
let ws = S.integrate' $ stack
 
rosters <- filterM (hasAnyProperty props) ws
 
let n = fromIntegral $ length rosters
 
let (rostersRect, chatsRect) = splitHorizontallyBy (n * ratio) rect
 
let rosterRects = splitHorizontally n rostersRect
 
let filteredStack = stack >>= S.filter (`notElem` rosters)
 
(a,b) <- runLayout (wksp {S.stack = filteredStack}) chatsRect
 
return (zip rosters rosterRects ++ a, b)
 
</haskell>
 

Revision as of 11:43, 6 February 2021