mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 11:30:22 -07:00
X.L.MouseResizableTile: configurable gaps (dragger size and position)
(with the option of putting the draggers over window borders with no gaps at all)
This commit is contained in:
parent
2853dc65c8
commit
1e847cb65a
@ -19,7 +19,9 @@ module XMonad.Layout.MouseResizableTile (
|
|||||||
-- $usage
|
-- $usage
|
||||||
mouseResizableTile,
|
mouseResizableTile,
|
||||||
mouseResizableTileMirrored,
|
mouseResizableTileMirrored,
|
||||||
MRTMessage (ShrinkSlave, ExpandSlave)
|
MRTMessage (ShrinkSlave, ExpandSlave),
|
||||||
|
DraggerType (..),
|
||||||
|
draggerType
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import XMonad hiding (tile, splitVertically, splitHorizontallyBy)
|
import XMonad hiding (tile, splitVertically, splitHorizontallyBy)
|
||||||
@ -44,6 +46,11 @@ import Control.Applicative((<$>))
|
|||||||
-- > myLayout = mouseResizableTileMirrored ||| etc..
|
-- > myLayout = mouseResizableTileMirrored ||| etc..
|
||||||
-- > main = xmonad defaultConfig { layoutHook = myLayout }
|
-- > main = xmonad defaultConfig { layoutHook = myLayout }
|
||||||
--
|
--
|
||||||
|
-- Additionally, some parameters may be tweaked (see the rest of this document
|
||||||
|
-- for a list of them):
|
||||||
|
--
|
||||||
|
-- > myLayout = mouseResizableTile { draggerType = BordersDragger } ||| etc..
|
||||||
|
--
|
||||||
-- For more detailed instructions on editing the layoutHook see:
|
-- For more detailed instructions on editing the layoutHook see:
|
||||||
--
|
--
|
||||||
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
|
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
|
||||||
@ -72,11 +79,26 @@ data DraggerInfo = MasterDragger Position Rational
|
|||||||
type DraggerWithRect = (Rectangle, Glyph, DraggerInfo)
|
type DraggerWithRect = (Rectangle, Glyph, DraggerInfo)
|
||||||
type DraggerWithWin = (Window, DraggerInfo)
|
type DraggerWithWin = (Window, DraggerInfo)
|
||||||
|
|
||||||
|
-- | Specifies the size of the clickable area between windows.
|
||||||
|
data DraggerType = FixedDragger
|
||||||
|
{ gapWidth :: Dimension -- ^ width of a gap between windows
|
||||||
|
, draggerWidth :: Dimension -- ^ width of the dragger itself
|
||||||
|
-- (will overlap windows if greater than gap)
|
||||||
|
}
|
||||||
|
| BordersDragger -- ^ no gaps, draggers overlap window borders
|
||||||
|
deriving (Show, Read)
|
||||||
|
type DraggerGeometry = (Position, Dimension, Position, Dimension)
|
||||||
|
|
||||||
data MouseResizableTile a = MRT { nmaster :: Int,
|
data MouseResizableTile a = MRT { nmaster :: Int,
|
||||||
masterFrac :: Rational,
|
masterFrac :: Rational,
|
||||||
leftFracs :: [Rational],
|
leftFracs :: [Rational],
|
||||||
rightFracs :: [Rational],
|
rightFracs :: [Rational],
|
||||||
draggers :: [DraggerWithWin],
|
draggers :: [DraggerWithWin],
|
||||||
|
draggerType :: DraggerType,
|
||||||
|
-- ^ Get/set dragger and gap dimensions.
|
||||||
|
-- Usage:
|
||||||
|
--
|
||||||
|
-- > mouseResizableTile { draggerType = ... }
|
||||||
focusPos :: Int,
|
focusPos :: Int,
|
||||||
numWindows :: Int,
|
numWindows :: Int,
|
||||||
isMirrored :: Bool
|
isMirrored :: Bool
|
||||||
@ -86,32 +108,30 @@ mrtFraction :: Rational
|
|||||||
mrtFraction = 0.5
|
mrtFraction = 0.5
|
||||||
mrtDelta :: Rational
|
mrtDelta :: Rational
|
||||||
mrtDelta = 0.03
|
mrtDelta = 0.03
|
||||||
mrtDraggerOffset :: Position
|
mrtDraggerGaps :: DraggerType
|
||||||
mrtDraggerOffset = 3
|
mrtDraggerGaps = FixedDragger 6 6
|
||||||
mrtDraggerSize :: Dimension
|
|
||||||
mrtDraggerSize = 6
|
|
||||||
|
|
||||||
mouseResizableTile :: MouseResizableTile a
|
mouseResizableTile :: MouseResizableTile a
|
||||||
mouseResizableTile = MRT 1 mrtFraction [] [] [] 0 0 False
|
mouseResizableTile = MRT 1 mrtFraction [] [] [] mrtDraggerGaps 0 0 False
|
||||||
|
|
||||||
mouseResizableTileMirrored :: MouseResizableTile a
|
mouseResizableTileMirrored :: MouseResizableTile a
|
||||||
mouseResizableTileMirrored= MRT 1 mrtFraction [] [] [] 0 0 True
|
mouseResizableTileMirrored = MRT 1 mrtFraction [] [] [] mrtDraggerGaps 0 0 True
|
||||||
|
|
||||||
instance LayoutClass MouseResizableTile Window where
|
instance LayoutClass MouseResizableTile Window where
|
||||||
doLayout state sr (W.Stack w l r) =
|
doLayout state sr (W.Stack w l r) = do
|
||||||
|
drg <- draggerGeometry $ draggerType state
|
||||||
let wins = reverse l ++ w : r
|
let wins = reverse l ++ w : r
|
||||||
num = length wins
|
num = length wins
|
||||||
sr' = mirrorAdjust sr (mirrorRect sr)
|
sr' = mirrorAdjust sr (mirrorRect sr)
|
||||||
(rects, preparedDraggers) = tile (nmaster state) (masterFrac state)
|
(rects, preparedDraggers) = tile (nmaster state) (masterFrac state)
|
||||||
(leftFracs state ++ repeat mrtFraction)
|
(leftFracs state ++ repeat mrtFraction)
|
||||||
(rightFracs state ++ repeat mrtFraction) sr' num
|
(rightFracs state ++ repeat mrtFraction) sr' num drg
|
||||||
rects' = map (mirrorAdjust id mirrorRect . sanitizeRectangle sr') rects
|
rects' = map (mirrorAdjust id mirrorRect . sanitizeRectangle sr') rects
|
||||||
in do
|
|
||||||
mapM_ deleteDragger $ draggers state
|
mapM_ deleteDragger $ draggers state
|
||||||
(draggerWrs, newDraggers) <- unzip <$> mapM
|
(draggerWrs, newDraggers) <- unzip <$> mapM
|
||||||
(createDragger sr . adjustForMirror (isMirrored state))
|
(createDragger sr . adjustForMirror (isMirrored state))
|
||||||
preparedDraggers
|
preparedDraggers
|
||||||
return (zip wins rects' ++ draggerWrs, Just $ state { draggers = newDraggers,
|
return (draggerWrs ++ zip wins rects', Just $ state { draggers = newDraggers,
|
||||||
focusPos = length l,
|
focusPos = length l,
|
||||||
numWindows = length wins })
|
numWindows = length wins })
|
||||||
where
|
where
|
||||||
@ -146,6 +166,13 @@ instance LayoutClass MouseResizableTile Window where
|
|||||||
description state = mirror "MouseResizableTile"
|
description state = mirror "MouseResizableTile"
|
||||||
where mirror = if isMirrored state then ("Mirror " ++) else id
|
where mirror = if isMirrored state then ("Mirror " ++) else id
|
||||||
|
|
||||||
|
draggerGeometry :: DraggerType -> X DraggerGeometry
|
||||||
|
draggerGeometry (FixedDragger g d) =
|
||||||
|
return (fromIntegral $ g `div` 2, g, fromIntegral $ d `div` 2, d)
|
||||||
|
draggerGeometry BordersDragger = do
|
||||||
|
w <- asks (borderWidth . config)
|
||||||
|
return (0, 0, fromIntegral w, 2*w)
|
||||||
|
|
||||||
adjustForMirror :: Bool -> DraggerWithRect -> DraggerWithRect
|
adjustForMirror :: Bool -> DraggerWithRect -> DraggerWithRect
|
||||||
adjustForMirror False dragger = dragger
|
adjustForMirror False dragger = dragger
|
||||||
adjustForMirror True (draggerRect, draggerCursor, draggerInfo) =
|
adjustForMirror True (draggerRect, draggerCursor, draggerInfo) =
|
||||||
@ -192,24 +219,24 @@ sanitizeRectangle (Rectangle sx sy swh sht) (Rectangle x y wh ht) =
|
|||||||
within :: (Ord a) => a -> a -> a -> a
|
within :: (Ord a) => a -> a -> a -> a
|
||||||
within low high a = max low $ min high a
|
within low high a = max low $ min high a
|
||||||
|
|
||||||
tile :: Int -> Rational -> [Rational] -> [Rational] -> Rectangle -> Int -> ([Rectangle], [DraggerWithRect])
|
tile :: Int -> Rational -> [Rational] -> [Rational] -> Rectangle -> Int -> DraggerGeometry -> ([Rectangle], [DraggerWithRect])
|
||||||
tile nmaster' masterFrac' leftFracs' rightFracs' sr num
|
tile nmaster' masterFrac' leftFracs' rightFracs' sr num drg
|
||||||
| num <= nmaster' = splitVertically (take (num - 1) leftFracs') sr True 0
|
| num <= nmaster' = splitVertically (take (num - 1) leftFracs') sr True 0 drg
|
||||||
| nmaster' == 0 = splitVertically (take (num - 1) rightFracs') sr False 0
|
| nmaster' == 0 = splitVertically (take (num - 1) rightFracs') sr False 0 drg
|
||||||
| otherwise = (leftRects ++ rightRects, masterDragger : leftDraggers ++ rightDraggers)
|
| otherwise = (leftRects ++ rightRects, masterDragger : leftDraggers ++ rightDraggers)
|
||||||
where ((sr1, sr2), masterDragger) = splitHorizontallyBy masterFrac' sr
|
where ((sr1, sr2), masterDragger) = splitHorizontallyBy masterFrac' sr drg
|
||||||
(leftRects, leftDraggers) = splitVertically (take (nmaster' - 1) leftFracs') sr1 True 0
|
(leftRects, leftDraggers) = splitVertically (take (nmaster' - 1) leftFracs') sr1 True 0 drg
|
||||||
(rightRects, rightDraggers) = splitVertically (take (num - nmaster' - 1) rightFracs') sr2 False 0
|
(rightRects, rightDraggers) = splitVertically (take (num - nmaster' - 1) rightFracs') sr2 False 0 drg
|
||||||
|
|
||||||
splitVertically :: RealFrac r => [r] -> Rectangle -> Bool -> Int -> ([Rectangle], [DraggerWithRect])
|
splitVertically :: RealFrac r => [r] -> Rectangle -> Bool -> Int -> DraggerGeometry -> ([Rectangle], [DraggerWithRect])
|
||||||
splitVertically [] r _ _ = ([r], [])
|
splitVertically [] r _ _ _ = ([r], [])
|
||||||
splitVertically (f:fx) (Rectangle sx sy sw sh) isLeft num =
|
splitVertically (f:fx) (Rectangle sx sy sw sh) isLeft num drg@(drOff, drSz, drOff2, drSz2) =
|
||||||
let nextRect = Rectangle sx sy sw $ smallh - div mrtDraggerSize 2
|
let nextRect = Rectangle sx sy sw $ smallh - div drSz 2
|
||||||
(otherRects, otherDragger) = splitVertically fx
|
(otherRects, otherDragger) = splitVertically fx
|
||||||
(Rectangle sx (sy + fromIntegral smallh + mrtDraggerOffset)
|
(Rectangle sx (sy + fromIntegral smallh + drOff)
|
||||||
sw (sh - smallh - div mrtDraggerSize 2))
|
sw (sh - smallh - div drSz 2))
|
||||||
isLeft (num + 1)
|
isLeft (num + 1) drg
|
||||||
draggerRect = Rectangle sx (sy + fromIntegral smallh - mrtDraggerOffset) sw mrtDraggerSize
|
draggerRect = Rectangle sx (sy + fromIntegral smallh - drOff2) sw drSz2
|
||||||
draggerInfo = if isLeft
|
draggerInfo = if isLeft
|
||||||
then LeftSlaveDragger sy (fromIntegral sh) num
|
then LeftSlaveDragger sy (fromIntegral sh) num
|
||||||
else RightSlaveDragger sy (fromIntegral sh) num
|
else RightSlaveDragger sy (fromIntegral sh) num
|
||||||
@ -217,13 +244,14 @@ splitVertically (f:fx) (Rectangle sx sy sw sh) isLeft num =
|
|||||||
in (nextRect : otherRects, nextDragger : otherDragger)
|
in (nextRect : otherRects, nextDragger : otherDragger)
|
||||||
where smallh = floor $ fromIntegral sh * f
|
where smallh = floor $ fromIntegral sh * f
|
||||||
|
|
||||||
splitHorizontallyBy :: RealFrac r => r -> Rectangle -> ((Rectangle, Rectangle), DraggerWithRect)
|
splitHorizontallyBy :: RealFrac r => r -> Rectangle -> DraggerGeometry -> ((Rectangle, Rectangle), DraggerWithRect)
|
||||||
splitHorizontallyBy f (Rectangle sx sy sw sh) = ((leftHalf, rightHalf), (draggerRect, xC_sb_h_double_arrow, draggerInfo))
|
splitHorizontallyBy f (Rectangle sx sy sw sh) (drOff, drSz, drOff2, drSz2) =
|
||||||
|
((leftHalf, rightHalf), (draggerRect, xC_sb_h_double_arrow, draggerInfo))
|
||||||
where leftw = floor $ fromIntegral sw * f
|
where leftw = floor $ fromIntegral sw * f
|
||||||
leftHalf = Rectangle sx sy (leftw - mrtDraggerSize `div` 2) sh
|
leftHalf = Rectangle sx sy (leftw - drSz `div` 2) sh
|
||||||
rightHalf = Rectangle (sx + fromIntegral leftw + mrtDraggerOffset) sy
|
rightHalf = Rectangle (sx + fromIntegral leftw + drOff) sy
|
||||||
(sw - fromIntegral leftw - mrtDraggerSize `div` 2) sh
|
(sw - fromIntegral leftw - drSz `div` 2) sh
|
||||||
draggerRect = Rectangle (sx + fromIntegral leftw - mrtDraggerOffset) sy mrtDraggerSize sh
|
draggerRect = Rectangle (sx + fromIntegral leftw - drOff2) sy drSz2 sh
|
||||||
draggerInfo = MasterDragger sx (fromIntegral sw)
|
draggerInfo = MasterDragger sx (fromIntegral sw)
|
||||||
|
|
||||||
createDragger :: Rectangle -> DraggerWithRect -> X ((Window, Rectangle), DraggerWithWin)
|
createDragger :: Rectangle -> DraggerWithRect -> X ((Window, Rectangle), DraggerWithWin)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user