{-# LANGUAGE CPP, FlexibleInstances, MultiParamTypeClasses, PatternGuards #-}
#ifdef TESTING
{-# OPTIONS_GHC -Wno-duplicate-exports #-}
#endif
module XMonad.Layout.LimitWindows (
limitWindows,limitSlice,limitSelect,
increaseLimit,decreaseLimit,setLimit,
#ifdef TESTING
select,update,Selection(..),updateAndSelect,
#endif
LimitWindows, Selection,
) where
import XMonad
import XMonad.Layout.LayoutModifier
import XMonad.Prelude (fromJust, guard, (<=<))
import qualified XMonad.StackSet as W
increaseLimit :: X ()
increaseLimit :: X ()
increaseLimit = forall a. Message a => a -> X ()
sendMessage forall a b. (a -> b) -> a -> b
$ (Int -> Int) -> LimitChange
LimitChange forall a. Enum a => a -> a
succ
decreaseLimit :: X ()
decreaseLimit :: X ()
decreaseLimit = forall a. Message a => a -> X ()
sendMessage forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int) -> LimitChange
LimitChange forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> a -> a
max Int
1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Enum a => a -> a
pred
setLimit :: Int -> X ()
setLimit :: Int -> X ()
setLimit Int
tgt = forall a. Message a => a -> X ()
sendMessage forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> Int) -> LimitChange
LimitChange forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const Int
tgt
limitWindows :: Int -> l a -> ModifiedLayout LimitWindows l a
limitWindows :: forall (l :: * -> *) a.
Int -> l a -> ModifiedLayout LimitWindows l a
limitWindows Int
n = forall (m :: * -> *) (l :: * -> *) a.
m a -> l a -> ModifiedLayout m l a
ModifiedLayout (forall a. SliceStyle -> Int -> LimitWindows a
LimitWindows SliceStyle
FirstN Int
n)
limitSlice :: Int -> l a -> ModifiedLayout LimitWindows l a
limitSlice :: forall (l :: * -> *) a.
Int -> l a -> ModifiedLayout LimitWindows l a
limitSlice Int
n = forall (m :: * -> *) (l :: * -> *) a.
m a -> l a -> ModifiedLayout m l a
ModifiedLayout (forall a. SliceStyle -> Int -> LimitWindows a
LimitWindows SliceStyle
Slice Int
n)
limitSelect :: Int -> Int -> l a -> ModifiedLayout Selection l a
limitSelect :: forall (l :: * -> *) a.
Int -> Int -> l a -> ModifiedLayout Selection l a
limitSelect Int
m Int
r = forall (m :: * -> *) (l :: * -> *) a.
m a -> l a -> ModifiedLayout m l a
ModifiedLayout Sel{ nMaster :: Int
nMaster=Int
m, start :: Int
start=Int
m, nRest :: Int
nRest=Int
r }
data LimitWindows a = LimitWindows SliceStyle Int deriving (ReadPrec [LimitWindows a]
ReadPrec (LimitWindows a)
ReadS [LimitWindows a]
forall a. ReadPrec [LimitWindows a]
forall a. ReadPrec (LimitWindows a)
forall a. Int -> ReadS (LimitWindows a)
forall a. ReadS [LimitWindows a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [LimitWindows a]
$creadListPrec :: forall a. ReadPrec [LimitWindows a]
readPrec :: ReadPrec (LimitWindows a)
$creadPrec :: forall a. ReadPrec (LimitWindows a)
readList :: ReadS [LimitWindows a]
$creadList :: forall a. ReadS [LimitWindows a]
readsPrec :: Int -> ReadS (LimitWindows a)
$creadsPrec :: forall a. Int -> ReadS (LimitWindows a)
Read,Int -> LimitWindows a -> ShowS
forall a. Int -> LimitWindows a -> ShowS
forall a. [LimitWindows a] -> ShowS
forall a. LimitWindows a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LimitWindows a] -> ShowS
$cshowList :: forall a. [LimitWindows a] -> ShowS
show :: LimitWindows a -> String
$cshow :: forall a. LimitWindows a -> String
showsPrec :: Int -> LimitWindows a -> ShowS
$cshowsPrec :: forall a. Int -> LimitWindows a -> ShowS
Show)
data SliceStyle = FirstN | Slice deriving (ReadPrec [SliceStyle]
ReadPrec SliceStyle
Int -> ReadS SliceStyle
ReadS [SliceStyle]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SliceStyle]
$creadListPrec :: ReadPrec [SliceStyle]
readPrec :: ReadPrec SliceStyle
$creadPrec :: ReadPrec SliceStyle
readList :: ReadS [SliceStyle]
$creadList :: ReadS [SliceStyle]
readsPrec :: Int -> ReadS SliceStyle
$creadsPrec :: Int -> ReadS SliceStyle
Read,Int -> SliceStyle -> ShowS
[SliceStyle] -> ShowS
SliceStyle -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SliceStyle] -> ShowS
$cshowList :: [SliceStyle] -> ShowS
show :: SliceStyle -> String
$cshow :: SliceStyle -> String
showsPrec :: Int -> SliceStyle -> ShowS
$cshowsPrec :: Int -> SliceStyle -> ShowS
Show)
newtype LimitChange = LimitChange { LimitChange -> Int -> Int
unLC :: Int -> Int }
instance Message LimitChange
instance LayoutModifier LimitWindows a where
pureMess :: LimitWindows a -> SomeMessage -> Maybe (LimitWindows a)
pureMess (LimitWindows SliceStyle
s Int
n) =
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. SliceStyle -> Int -> LimitWindows a
LimitWindows SliceStyle
s) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {m :: * -> *} {b}.
(Monad m, Alternative m, Ord b, Num b) =>
b -> m b
pos forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< (forall {m :: * -> *} {b}.
(Monad m, Alternative m, Eq b) =>
(b -> b) -> b -> m b
`app` Int
n) forall b c a. (b -> c) -> (a -> b) -> a -> c
. LimitChange -> Int -> Int
unLC forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall m. Message m => SomeMessage -> Maybe m
fromMessage
where pos :: b -> m b
pos b
x = forall (f :: * -> *). Alternative f => Bool -> f ()
guard (b
xforall a. Ord a => a -> a -> Bool
>=b
1) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return b
x
app :: (b -> b) -> b -> m b
app b -> b
f b
x = forall (f :: * -> *). Alternative f => Bool -> f ()
guard (b -> b
f b
x forall a. Eq a => a -> a -> Bool
/= b
x) forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return (b -> b
f b
x)
modifyLayout :: forall (l :: * -> *).
LayoutClass l a =>
LimitWindows a
-> Workspace String (l a) a
-> Rectangle
-> X ([(a, Rectangle)], Maybe (l a))
modifyLayout (LimitWindows SliceStyle
style Int
n) Workspace String (l a) a
ws =
forall (layout :: * -> *) a.
LayoutClass layout a =>
Workspace String (layout a) a
-> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
runLayout Workspace String (l a) a
ws { stack :: Maybe (Stack a)
W.stack = forall {a}. Int -> Stack a -> Stack a
f Int
n forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall i l a. Workspace i l a -> Maybe (Stack a)
W.stack Workspace String (l a) a
ws }
where f :: Int -> Stack a -> Stack a
f = case SliceStyle
style of
SliceStyle
FirstN -> forall {a}. Int -> Stack a -> Stack a
firstN
SliceStyle
Slice -> forall {a}. Int -> Stack a -> Stack a
slice
firstN :: Int -> W.Stack a -> W.Stack a
firstN :: forall {a}. Int -> Stack a -> Stack a
firstN Int
n Stack a
st = forall {a}. Stack a -> Stack a
upfocus forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => Maybe a -> a
fromJust forall a b. (a -> b) -> a -> b
$ forall a. [a] -> Maybe (Stack a)
W.differentiate forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> [a]
take (forall a. Ord a => a -> a -> a
max Int
1 Int
n) forall a b. (a -> b) -> a -> b
$ forall a. Stack a -> [a]
W.integrate Stack a
st
where upfocus :: Stack a -> Stack a
upfocus = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr forall b c a. (b -> c) -> (a -> b) -> a -> c
(.) forall a. a -> a
id forall a b. (a -> b) -> a -> b
$ forall a. Int -> a -> [a]
replicate (forall (t :: * -> *) a. Foldable t => t a -> Int
length (forall a. Stack a -> [a]
W.up Stack a
st)) forall {a}. Stack a -> Stack a
W.focusDown'
slice :: Int -> W.Stack t -> W.Stack t
slice :: forall {a}. Int -> Stack a -> Stack a
slice Int
n (W.Stack t
f [t]
u [t]
d) =
forall a. a -> [a] -> [a] -> Stack a
W.Stack t
f (forall a. Int -> [a] -> [a]
take (Int
nu forall a. Num a => a -> a -> a
+ Int
unusedD) [t]
u)
(forall a. Int -> [a] -> [a]
take (Int
nd forall a. Num a => a -> a -> a
+ Int
unusedU) [t]
d)
where unusedD :: Int
unusedD = forall a. Ord a => a -> a -> a
max Int
0 forall a b. (a -> b) -> a -> b
$ Int
nd forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length [t]
d
unusedU :: Int
unusedU = forall a. Ord a => a -> a -> a
max Int
0 forall a b. (a -> b) -> a -> b
$ Int
nu forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length [t]
u
nd :: Int
nd = forall a. Integral a => a -> a -> a
div (Int
n forall a. Num a => a -> a -> a
- Int
1) Int
2
nu :: Int
nu = forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry forall a. Num a => a -> a -> a
(+) forall a b. (a -> b) -> a -> b
$ forall a. Integral a => a -> a -> (a, a)
divMod (Int
n forall a. Num a => a -> a -> a
- Int
1) Int
2
data Selection a = Sel { forall a. Selection a -> Int
nMaster :: Int, forall a. Selection a -> Int
start :: Int, forall a. Selection a -> Int
nRest :: Int }
deriving (ReadPrec [Selection a]
ReadPrec (Selection a)
ReadS [Selection a]
forall a. ReadPrec [Selection a]
forall a. ReadPrec (Selection a)
forall a. Int -> ReadS (Selection a)
forall a. ReadS [Selection a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Selection a]
$creadListPrec :: forall a. ReadPrec [Selection a]
readPrec :: ReadPrec (Selection a)
$creadPrec :: forall a. ReadPrec (Selection a)
readList :: ReadS [Selection a]
$creadList :: forall a. ReadS [Selection a]
readsPrec :: Int -> ReadS (Selection a)
$creadsPrec :: forall a. Int -> ReadS (Selection a)
Read, Int -> Selection a -> ShowS
forall a. Int -> Selection a -> ShowS
forall a. [Selection a] -> ShowS
forall a. Selection a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Selection a] -> ShowS
$cshowList :: forall a. [Selection a] -> ShowS
show :: Selection a -> String
$cshow :: forall a. Selection a -> String
showsPrec :: Int -> Selection a -> ShowS
$cshowsPrec :: forall a. Int -> Selection a -> ShowS
Show, Selection a -> Selection a -> Bool
forall a. Selection a -> Selection a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Selection a -> Selection a -> Bool
$c/= :: forall a. Selection a -> Selection a -> Bool
== :: Selection a -> Selection a -> Bool
$c== :: forall a. Selection a -> Selection a -> Bool
Eq)
instance LayoutModifier Selection a where
modifyLayout :: forall (l :: * -> *).
LayoutClass l a =>
Selection a
-> Workspace String (l a) a
-> Rectangle
-> X ([(a, Rectangle)], Maybe (l a))
modifyLayout Selection a
s Workspace String (l a) a
w =
forall (layout :: * -> *) a.
LayoutClass layout a =>
Workspace String (layout a) a
-> Rectangle -> X ([(a, Rectangle)], Maybe (layout a))
runLayout (Workspace String (l a) a
w { stack :: Maybe (Stack a)
W.stack = forall l a. Selection l -> Stack a -> Stack a
updateAndSelect Selection a
s forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall i l a. Workspace i l a -> Maybe (Stack a)
W.stack Workspace String (l a) a
w })
pureModifier :: Selection a
-> Rectangle
-> Maybe (Stack a)
-> [(a, Rectangle)]
-> ([(a, Rectangle)], Maybe (Selection a))
pureModifier Selection a
sel Rectangle
_ Maybe (Stack a)
stk [(a, Rectangle)]
wins = ([(a, Rectangle)]
wins, forall l a. Selection l -> Stack a -> Selection a
update Selection a
sel forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Stack a)
stk)
pureMess :: Selection a -> SomeMessage -> Maybe (Selection a)
pureMess Selection a
sel SomeMessage
m
| Just Int -> Int
f <- LimitChange -> Int -> Int
unLC forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m =
forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Selection a
sel { nRest :: Int
nRest = forall a. Ord a => a -> a -> a
max Int
0 (Int -> Int
f (forall a. Selection a -> Int
nMaster Selection a
sel forall a. Num a => a -> a -> a
+ forall a. Selection a -> Int
nRest Selection a
sel) forall a. Num a => a -> a -> a
- forall a. Selection a -> Int
nMaster Selection a
sel) }
| Just (IncMasterN Int
n) <- forall m. Message m => SomeMessage -> Maybe m
fromMessage SomeMessage
m =
forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Selection a
sel { nMaster :: Int
nMaster = forall a. Ord a => a -> a -> a
max Int
0 (forall a. Selection a -> Int
nMaster Selection a
sel forall a. Num a => a -> a -> a
+ Int
n) }
| Bool
otherwise =
forall a. Maybe a
Nothing
select :: Selection l -> W.Stack a -> W.Stack a
select :: forall l a. Selection l -> Stack a -> Stack a
select Selection l
s Stack a
stk
| Int
lups forall a. Ord a => a -> a -> Bool
< forall a. Selection a -> Int
nMaster Selection l
s
= Stack a
stk { down :: [a]
W.down=forall a. Int -> [a] -> [a]
take (forall a. Selection a -> Int
nMaster Selection l
s forall a. Num a => a -> a -> a
- Int
lups forall a. Num a => a -> a -> a
- Int
1) [a]
downs forall a. [a] -> [a] -> [a]
++
(forall a. Int -> [a] -> [a]
take (forall a. Selection a -> Int
nRest Selection l
s) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Int -> [a] -> [a]
drop (forall a. Selection a -> Int
start Selection l
s forall a. Num a => a -> a -> a
- Int
lups forall a. Num a => a -> a -> a
- Int
1) forall a b. (a -> b) -> a -> b
$ [a]
downs) }
| Bool
otherwise
= Stack a
stk { up :: [a]
W.up=forall a. [a] -> [a]
reverse (forall a. Int -> [a] -> [a]
take (forall a. Selection a -> Int
nMaster Selection l
s) [a]
ups forall a. [a] -> [a] -> [a]
++ forall a. Int -> [a] -> [a]
drop (forall a. Selection a -> Int
start Selection l
s) [a]
ups),
down :: [a]
W.down=forall a. Int -> [a] -> [a]
take (forall a. Selection a -> Int
nRest Selection l
s forall a. Num a => a -> a -> a
- (Int
lups forall a. Num a => a -> a -> a
- forall a. Selection a -> Int
start Selection l
s) forall a. Num a => a -> a -> a
- Int
1) [a]
downs }
where
downs :: [a]
downs = forall a. Stack a -> [a]
W.down Stack a
stk
ups :: [a]
ups = forall a. [a] -> [a]
reverse forall a b. (a -> b) -> a -> b
$ forall a. Stack a -> [a]
W.up Stack a
stk
lups :: Int
lups = forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
ups
updateStart :: Selection l -> W.Stack a -> Int
updateStart :: forall l a. Selection l -> Stack a -> Int
updateStart Selection l
s Stack a
stk
| Int
lups forall a. Ord a => a -> a -> Bool
< forall a. Selection a -> Int
nMaster Selection l
s
= forall a. Selection a -> Int
start Selection l
s forall a. Ord a => a -> a -> a
`min` (Int
lups forall a. Num a => a -> a -> a
+ Int
ldown forall a. Num a => a -> a -> a
- forall a. Selection a -> Int
nRest Selection l
s forall a. Num a => a -> a -> a
+ Int
1) forall a. Ord a => a -> a -> a
`max` forall a. Selection a -> Int
nMaster Selection l
s
| Bool
otherwise
= forall a. Selection a -> Int
start Selection l
s forall a. Ord a => a -> a -> a
`min` Int
lups
forall a. Ord a => a -> a -> a
`max` (Int
lups forall a. Num a => a -> a -> a
- forall a. Selection a -> Int
nRest Selection l
s forall a. Num a => a -> a -> a
+ Int
1)
forall a. Ord a => a -> a -> a
`min` (Int
lups forall a. Num a => a -> a -> a
+ Int
ldown forall a. Num a => a -> a -> a
- forall a. Selection a -> Int
nRest Selection l
s forall a. Num a => a -> a -> a
+ Int
1)
forall a. Ord a => a -> a -> a
`max` forall a. Selection a -> Int
nMaster Selection l
s
where
lups :: Int
lups = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ forall a. Stack a -> [a]
W.up Stack a
stk
ldown :: Int
ldown = forall (t :: * -> *) a. Foldable t => t a -> Int
length forall a b. (a -> b) -> a -> b
$ forall a. Stack a -> [a]
W.down Stack a
stk
update :: Selection l -> W.Stack a -> Selection a
update :: forall l a. Selection l -> Stack a -> Selection a
update Selection l
sel Stack a
stk = Selection l
sel { start :: Int
start=forall l a. Selection l -> Stack a -> Int
updateStart Selection l
sel Stack a
stk }
updateAndSelect :: Selection l -> W.Stack a -> W.Stack a
updateAndSelect :: forall l a. Selection l -> Stack a -> Stack a
updateAndSelect Selection l
sel Stack a
stk = forall l a. Selection l -> Stack a -> Stack a
select (forall l a. Selection l -> Stack a -> Selection a
update Selection l
sel Stack a
stk) Stack a
stk