HintedTile:

- code formatting
 - refactoring, based on TilePrime work by Eric Mertens
 - use the current border width of the window, this improves interaction with
   the No/SmartBorders extensions
This commit is contained in:
Spencer Janssen
2007-11-22 05:11:57 +00:00
parent 1519612c23
commit bb74a0bc0d

View File

@@ -21,11 +21,12 @@ module XMonad.Layout.HintedTile (
HintedTile(..), Orientation(..)) where HintedTile(..), Orientation(..)) where
import XMonad import XMonad
import XMonad.Layouts ( Resize(..), IncMasterN(..) ) import XMonad.Layouts (Resize(..), IncMasterN(..))
import XMonad.Operations ( applySizeHints ) import XMonad.Operations (applySizeHints, D)
import qualified XMonad.StackSet as W import qualified XMonad.StackSet as W
import Graphics.X11.Xlib import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras import Graphics.X11.Xlib.Extras
import Control.Applicative ((<$>))
import Control.Monad.Reader import Control.Monad.Reader
-- $usage -- $usage
@@ -51,61 +52,66 @@ data HintedTile a = HintedTile
data Orientation = Wide | Tall deriving ( Show, Read ) data Orientation = Wide | Tall deriving ( Show, Read )
instance LayoutClass HintedTile Window where instance LayoutClass HintedTile Window where
doLayout c rect w' = let w = W.integrate w' doLayout c rect w' = do
in do { hints <- sequence (map getHints w) bhs <- mapM getHints w
; b <- asks (borderWidth . config) let (masters, slaves) = splitAt (nmaster c) bhs
; return (zip w (tiler b (frac c) rect `uncurry` splitAt (nmaster c) hints) return (zip w (tiler (frac c) rect masters slaves), Nothing)
, Nothing) } where
where w = W.integrate w'
(split, divide) = (split, divide) = case orientation c of
case orientation c of Tall -> (splitHorizontally, divideVertically)
Tall -> (splitHorizontally, divideVertically) Wide -> (splitVertically, divideHorizontally)
Wide -> (splitVertically, divideHorizontally) tiler f r masters slaves
tiler b f r masters slaves = | null masters || null slaves = divide (masters ++ slaves) r
if null masters || null slaves | otherwise = split f r (divide masters) (divide slaves)
then divide b (masters ++ slaves) r
else split f r (divide b masters) (divide b slaves)
pureMessage c m = fmap resize (fromMessage m) `mplus` pureMessage c m = fmap resize (fromMessage m) `mplus`
fmap incmastern (fromMessage m) fmap incmastern (fromMessage m)
where where
resize Shrink = c { frac = max 0 $ frac c - delta c } resize Shrink = c { frac = max 0 $ frac c - delta c }
resize Expand = c { frac = min 1 $ frac c + delta c } resize Expand = c { frac = min 1 $ frac c + delta c }
incmastern (IncMasterN d) = c { nmaster = max 0 $ nmaster c + d } incmastern (IncMasterN d) = c { nmaster = max 0 $ nmaster c + d }
description l = "HintedTile " ++ show (orientation l) description l = "HintedTile " ++ show (orientation l)
addBorder, substractBorder :: Dimension -> (Dimension, Dimension) -> (Dimension, Dimension) adjBorder :: Dimension -> Dimension -> D -> D
addBorder b (w, h) = (w + 2 * b, h + 2 * b) adjBorder n b (w, h) = (w + n * 2 * b, h + n * 2 * b)
substractBorder b (w, h) = (w - 2 * b, h - 2 * b)
getHints :: Window -> X SizeHints -- | Transform a function on dimensions into one without regard for borders
getHints w = withDisplay $ \d -> io $ getWMNormalHints d w hintsUnderBorder :: (Dimension, SizeHints) -> D -> D
hintsUnderBorder (bW, h) = adjBorder bW 1 . applySizeHints h . adjBorder bW (-1)
getHints :: Window -> X (Dimension, SizeHints)
getHints w = withDisplay $ \d -> io $ liftM2 (,)
(fromIntegral . wa_border_width <$> getWindowAttributes d w)
(getWMNormalHints d w)
-- Divide the screen vertically (horizontally) into n subrectangles -- Divide the screen vertically (horizontally) into n subrectangles
divideVertically, divideHorizontally :: Dimension -> [SizeHints] -> Rectangle -> [Rectangle] divideVertically, divideHorizontally :: [(Dimension, SizeHints)] -> Rectangle -> [Rectangle]
divideVertically _ [] _ = [] -- there's a fold here, struggling to get out divideVertically [] _ = [] -- there's a fold here, struggling to get out
divideVertically b (hints:rest) (Rectangle sx sy sw sh) = (Rectangle sx sy w h) : divideVertically (bh:bhs) (Rectangle sx sy sw sh) = (Rectangle sx sy w h) :
(divideVertically b rest (Rectangle sx (sy + fromIntegral h) sw (sh - h))) (divideVertically bhs (Rectangle sx (sy + fromIntegral h) sw (sh - h)))
where (w, h) = addBorder b $ applySizeHints hints $ substractBorder b where (w, h) = hintsUnderBorder bh (sw, sh `div` fromIntegral (1 + (length bhs)))
(sw, sh `div` fromIntegral (1 + (length rest)))
divideHorizontally _ [] _ = [] divideHorizontally [] _ = []
divideHorizontally b (hints:rest) (Rectangle sx sy sw sh) = (Rectangle sx sy w h) : divideHorizontally (bh:bhs) (Rectangle sx sy sw sh) = (Rectangle sx sy w h) :
(divideHorizontally b rest (Rectangle (sx + fromIntegral w) sy (sw - w) sh)) (divideHorizontally bhs (Rectangle (sx + fromIntegral w) sy (sw - w) sh))
where (w, h) = addBorder b $ applySizeHints hints $ substractBorder b where
(sw `div` fromIntegral (1 + (length rest)), sh) (w, h) = hintsUnderBorder bh (sw `div` fromIntegral (1 + (length bhs)), sh)
-- Split the screen into two rectangles, using a rational to specify the ratio -- Split the screen into two rectangles, using a rational to specify the ratio
splitHorizontally, splitVertically :: Rational -> Rectangle -> (Rectangle -> [Rectangle]) -> (Rectangle -> [Rectangle]) -> [Rectangle] splitHorizontally, splitVertically :: Rational -> Rectangle -> (Rectangle -> [Rectangle])
-> (Rectangle -> [Rectangle]) -> [Rectangle]
splitHorizontally f (Rectangle sx sy sw sh) left right = leftRects ++ rightRects splitHorizontally f (Rectangle sx sy sw sh) left right = leftRects ++ rightRects
where leftw = floor $ fromIntegral sw * f where
leftRects = left $ Rectangle sx sy leftw sh leftw = floor $ fromIntegral sw * f
rightx = (maximum . map rect_width) leftRects leftRects = left $ Rectangle sx sy leftw sh
rightRects = right $ Rectangle (sx + fromIntegral rightx) sy (sw - rightx) sh rightx = (maximum . map rect_width) leftRects
rightRects = right $ Rectangle (sx + fromIntegral rightx) sy (sw - rightx) sh
splitVertically f (Rectangle sx sy sw sh) top bottom = topRects ++ bottomRects splitVertically f (Rectangle sx sy sw sh) top bottom = topRects ++ bottomRects
where toph = floor $ fromIntegral sh * f where
topRects = top $ Rectangle sx sy sw toph toph = floor $ fromIntegral sh * f
bottomy = (maximum . map rect_height) topRects topRects = top $ Rectangle sx sy sw toph
bottomRects = bottom $ Rectangle sx (sy + fromIntegral bottomy) sw (sh - bottomy) bottomy = (maximum . map rect_height) topRects
bottomRects = bottom $ Rectangle sx (sy + fromIntegral bottomy) sw (sh - bottomy)