atom feed5 messages in org.haskell.xmonadRe: [xmonad] workspace switching and ...
FromSent OnAttachments
Karl HasselströmJan 26, 2009 2:35 am 
Brent YorgeyJan 26, 2009 8:32 am 
Brent YorgeyJan 27, 2009 1:51 pm 
wirtwolffJan 27, 2009 4:05 pm 
Karl HasselströmJan 28, 2009 1:37 am.hs
Subject:Re: [xmonad] workspace switching and Xinerama
From:Karl Hasselström (kha-@hemma.treskal.com)
Date:Jan 28, 2009 1:37:53 am
List:org.haskell.xmonad
Attachments:
xmonad.hs - 6k

On 2009-01-27 17:06:09 -0700, wirtwolff wrote:

Since last time, regarding your layout question, I read your request backward re /unfocused/focused/ I'm hesitant to reply. ;) Hopefully I have read correctly this time.

I won't bite if you don't get my question right, honest ...

The Actions.WindowNavigation module moves focus and swaps windows across screen borders directionally nicely as far as I've seen, although it's marked experimental. (I'm running darcs version, but afaik is in 0.8 too)

It works beautifully! I can move the focus left and right even across screen borders. Moving the focus up also works.

Moving it down doesn't, though. I see the window border flashing, but nothing else happens. And shifting windows up and down took my Gnome panel down from the top of the screen and into the managed grid, which I didn't want at all. ;-)

(I almost never use the up/down movements, though, so I'll keep this config since it's much better than what I used to have.)

This is with xmonad 0.8 from the Ubuntu archives, and a config like this:

main = do let c1 = CG.gnomeConfig { modMask = mod4Mask , layoutHook = layouts , manageHook = manageHook CG.gnomeConfig <+> myManageHook , keys = \x -> M.union (M.fromList (myKeys x)) (keys CG.gnomeConfig x) , focusFollowsMouse = False , borderWidth = 2 } c2 <- WN.withWindowNavigation (xK_Up, xK_Left, xK_Down, xK_Right) c1 xmonad c2

(The complete config is attached in case someone is interested.)

-- Karl Hasselström, kh@treskal.com www.treskal.com/kalle

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses #-}

import Data.Maybe import qualified Data.Map as M import qualified Data.Set as S

import XMonad import qualified XMonad.Actions.CycleWS as CWS import qualified XMonad.Actions.WindowNavigation as WN import qualified XMonad.Config.Gnome as CG import qualified XMonad.Hooks.EwmhDesktops as ED import qualified XMonad.Hooks.ManageDocks as MD import qualified XMonad.Layout.DwmStyle as DS import qualified XMonad.Layout.LayoutCombinators as LC import qualified XMonad.Layout.NoBorders as NB import qualified XMonad.Layout.Tabbed as LT import qualified XMonad.Layout.ThreeColumns as TC import qualified XMonad.Operations as Op import qualified XMonad.StackSet as SS

data (Show a, Read a) => Sliced a = Sliced Int -- number of windows visible (Maybe a) -- focused window [Maybe a] -- visible windows deriving (Show, Read)

fillInBlanks :: [Maybe a] -> [a] -> [Maybe a] fillInBlanks [] _ = [] fillInBlanks xs [] = xs fillInBlanks ((Just x):xs) ys = (Just x):(fillInBlanks xs ys) fillInBlanks (Nothing:xs) (y:ys) = (Just y):(fillInBlanks xs ys)

instance (Eq a, Show a, Read a) => LayoutClass Sliced a where doLayout (Sliced numVisible focused visible) rect st = return (tile, Just $ next) where wasFocused w = case focused of Just f -> w == f Nothing -> False fixLength v = take numVisible $ v ++ noth where noth = Nothing : noth switchToNewFocused v = if (Just $ SS.focus st) `elem` v then v else map repl v where repl Nothing = Nothing repl (Just w) = Just (if wasFocused w then (SS.focus st) else w) replaceEmptyWithFocused v = if (Just $ SS.focus st) `elem` v then v else fillInBlanks v [SS.focus st] replaceRightmostWithFocused v = if (Just $ SS.focus st) `elem` v then v else reverse $ (Just $ SS.focus st) : (tail $ reverse v) removeDeleted v = map filt v where filt Nothing = Nothing filt (Just w) = if w `elem` (SS.integrate st) then (Just w) else Nothing fillEmptySlots v = fillInBlanks v hidden where hidden = filter (`notElem` (catMaybes v)) (SS.integrate st) visible' = fillEmptySlots $ removeDeleted $ replaceRightmostWithFocused $ replaceEmptyWithFocused $ switchToNewFocused $ fixLength visible tile = zip toDraw $ splitHorizontally (length toDraw) rect where toDraw = catMaybes visible' next = Sliced numVisible (Just $ SS.focus st) visible'

handleMessage (Sliced numVisible focused visible) x = return $ case fromMessage x of Just Shrink -> Just (Sliced (numVisible - 1) focused visible) Just Expand -> Just (Sliced (numVisible + 1) focused visible) _ -> Nothing

description _ = "Sliced"

-- Shift focus one step. shiftOne :: SS.Stack a -> SS.Stack a shiftOne (SS.Stack t ls (r:rs)) = SS.Stack r (t:ls) rs shiftOne (SS.Stack t ls []) = SS.Stack x [] xs where (x:xs) = reverse (t:ls)

-- Shift focus to next unmapped window. focusNextUnmapped :: X () focusNextUnmapped = do state <- get let visible = mapped state Op.windows $ SS.modify' $ skipWindows visible where skipWindows wins st@(SS.Stack t _ _) = if S.member t wins then skipWindows wins' st' else st where wins' = S.delete t wins st' = shiftOne st

layouts = ED.ewmhDesktopsLayout $ MD.avoidStruts -- make space for Gnome panels $ NB.smartBorders -- no border for the only window on screen ( Tall 1 (3/100) (1/2) ||| TC.ThreeCol 1 (3/100) (1/2) ||| Sliced 2 Nothing [] ||| Full)

nextWS x = x CWS.Next CWS.HiddenNonEmptyWS prevWS x = x CWS.Prev CWS.HiddenNonEmptyWS emptyWS x = x CWS.Next CWS.EmptyWS

myKeys x = -- Go to next/prev workspace. [ ((modMask x, xK_v), nextWS CWS.moveTo) , ((modMask x, xK_o), CWS.swapNextScreen) , ((modMask x, xK_k), prevWS CWS.moveTo)

-- Move focus and window to next/prev workspace. , ((modMask x .|. shiftMask, xK_v), (nextWS CWS.shiftTo) >> (nextWS CWS.moveTo)) , ((modMask x .|. shiftMask, xK_o), CWS.shiftNextScreen >> CWS.swapNextScreen) , ((modMask x .|. shiftMask, xK_k), (prevWS CWS.shiftTo) >> (prevWS CWS.moveTo))

-- Move focus to other Xinerama screen. , ((modMask x .|. controlMask, xK_o), CWS.nextScreen)

-- Move focus and window to other Xinerama screen. , ((modMask x .|. controlMask .|. shiftMask, xK_o), CWS.shiftNextScreen >> CWS.nextScreen)

-- Get an empty workspace. , ((modMask x, xK_z), emptyWS CWS.moveTo) , ((modMask x .|. shiftMask, xK_z), (emptyWS CWS.shiftTo) >> (emptyWS CWS.moveTo))

, ((modMask x, xK_BackSpace), focusNextUnmapped) ]

myManageHook = composeAll . concat $ [[ className =? c --> doFloat | c <- [ "Git-gui" , "Gitk" , "Skype.real" , "Update-manager"]]]

main = do let c1 = CG.gnomeConfig { modMask = mod4Mask , layoutHook = layouts , manageHook = manageHook CG.gnomeConfig <+> myManageHook , keys = \x -> M.union (M.fromList (myKeys x)) (keys CG.gnomeConfig x) , focusFollowsMouse = False , borderWidth = 2 } c2 <- WN.withWindowNavigation (xK_Up, xK_Left, xK_Down, xK_Right) c1 xmonad c2