{-# OPTIONS -fglasgow-exts #-} ----------------------------------------------------------------------------- -- | -- Module : XMonad.Layout.ScratchWorkspace -- Copyright : (c) Braden Shepherdson, David Roundy 2008 -- License : BSD-style (as xmonad) -- -- Maintainer : Braden.Shepherdson@gmail.com -- Stability : unstable -- Portability : unportable module XMonad.Layout.ScratchWorkspace ( toggleScratchWorkspace ) where import Data.Maybe ( listToMaybe, catMaybes ) import Control.Monad ( guard, when ) import XMonad import XMonad.Core import qualified XMonad.StackSet as W toggleScratchWorkspace :: LayoutClass l Int => l Int -> X () toggleScratchWorkspace l = do s <- gets windowset when (scratchName `W.tagMember` s) $ case visibleScratch s of Just oldscratch -> do srs <- withDisplay getCleanedScreenInfo when (length srs == length (W.visible s)) $ do ml <- handleMessage (W.layout $ W.workspace oldscratch) (SomeMessage Hide) let scratch = case ml of Nothing -> oldscratch Just l' -> oldscratch { W.workspace = (W.workspace oldscratch) { W.layout = l' } } mapM_ hide $ W.integrate' $ W.stack $ W.workspace scratch let modscr scr = do guard $ scratchName /= W.tag (W.workspace scr) Just $ scr { W.screenDetail = newDetail } where newDetail = (W.screenDetail scr) { screenRect = pickRect (W.screen scr) srs } pickRect _ [z] = z pickRect i (z:zs) | i < 1 = z | otherwise = pickRect (i-1) zs pickRect _ [] = error "XMonad.Layout.ScratchWorkspace.toggleScratchWorkspace: internal error" s' = case catMaybes $ map modscr $ W.current s : W.visible s of newc:newv -> s { W.current = newc, W.visible = newv, W.hidden = W.workspace scratch : W.hidden s} [] -> error "XMonad.Layout.ScratchWorkspace.toggleScratchWorkspace: internal error" modify $ \st -> st { windowset = s' } refresh Nothing -> case hiddenScratch s of Nothing -> return () Just hs -> do r <- gets (screenRect . W.screenDetail . W.current . windowset) (rs,_) <- doLayout l r (W.Stack 0 [1] []) let (r0, r1) = case rs of [(0,ra),(1,rb)] -> (ra,rb) [(1,ra),(0,rb)] -> (rb,ra) [(1,ra)] -> (r,ra) [(0,ra)] -> (ra,r) _ -> (r,r) c' = (W.current s) { W.screenDetail = (W.screenDetail (W.current s)) { screenRect = r1 }} let s' = s { W.current = W.Screen hs (-1) (SD r0 (0,0,0,0)), W.visible = c': W.visible s, W.hidden = filter (not . isScratchW) $ W.hidden s } modify $ \st -> st { windowset = s' } refresh where visibleScratch s = listToMaybe $ filter isScratch $ W.current s : W.visible s hiddenScratch s = listToMaybe $ filter isScratchW $ W.hidden s isScratchW w = scratchName == W.tag w isScratch scr = scratchName == W.tag (W.workspace scr) -- notScratch scr = scratchName /= W.tag (W.workspace scr) scratchName :: String scratchName = "*scratch*" -- isScratchVisible :: X Bool -- isScratchVisible = gets (elem scratchName . map (W.tag . W.workspace) . W.visible . windowset)