Fix render order of LayoutHints and MultiColumns

Before this fix, when using layoutHintsToCenter together with
MultiColumns, in certain situations XMonad would render the border of
the focused window below a border of unfocused windows. This looks odd
and is here fixed by changing MultiColumns to always place the focused
window in front (even though they should not really overlap) and making
LayoutHints preserve the order returned from the underlying layout,
except for the focused window that is placed on top.

This is a good idea since layoutHintsToCenter requires the focused
window to be on top for good rendering, even if that is not really
required when the underlying layout is used on its own. This way
layoutHintsToCenter requires less of the layout that is modified and
MultiColumns is more compatible with future layout modifiers that are
not so considerate.
This commit is contained in:
Anders Engström 2017-05-22 08:36:14 +02:00
parent ade890ac63
commit cff3343a8c
3 changed files with 26 additions and 3 deletions

View File

@ -58,6 +58,19 @@
### Bug Fixes and Minor Changes
* `XMonad.Layout.LayoutHints`
Preserve the window order of the modified layout, except for the focused
window that is placed on top. This fixes an issue where the border of the
focused window in certain situations could be rendered below borders of
unfocused windows. It also has a lower risk of interfering with the
modified layout.
* `XMonad.Layout.MultiColumns`
The focused window is placed above the other windows if they would be made to
overlap due to a layout modifier. (As long as it preserves the window order.)
* `XMonad.Actions.GridSelect`
- The vertical centring of text in each cell has been improved.

View File

@ -44,6 +44,7 @@ import Data.Monoid(All(..))
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Maybe(fromJust)
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
@ -147,10 +148,15 @@ instance LayoutModifier LayoutHintsToCenter Window where
modifyLayout _ ws@(W.Workspace _ _ (Just st)) r = do
(arrs,ol) <- runLayout ws r
flip (,) ol
. changeOrder (W.focus st : (filter (/= W.focus st) $ map fst arrs))
. head . reverse . sortBy (compare `on` (fitting . map snd))
. map (applyHints st r) . applyOrder r
<$> mapM (\x -> fmap ((,) x) $ mkAdjust (fst x)) arrs
changeOrder :: [Window] -> [(Window, Rectangle)] -> [(Window, Rectangle)]
changeOrder w wr = zip w' $ map (fromJust . flip lookup wr) w'
where w' = filter (`elem` map fst wr) w
-- apply hints to first, grow adjacent windows
applyHints :: W.Stack Window -> Rectangle -> [((Window, Rectangle),(D -> D))] -> [(Window, Rectangle)]
applyHints _ _ [] = []

View File

@ -77,10 +77,9 @@ data MultiCol a = MultiCol
} deriving (Show,Read,Eq)
instance LayoutClass MultiCol a where
doLayout l r s = return (zip w rlist, resl)
doLayout l r s = return (combine s rlist, resl)
where rlist = doL (multiColNWin l') (multiColSize l') r wlen
w = W.integrate s
wlen = length w
wlen = length $ W.integrate s
-- Make sure the list of columns is big enough and update active column
nw = multiColNWin l ++ repeat (multiColDefWin l)
l' = l { multiColNWin = take (max (length $ multiColNWin l) $ getCol (wlen-1) nw + 1) nw
@ -90,6 +89,7 @@ instance LayoutClass MultiCol a where
resl = if l'==l
then Nothing
else Just l'
combine (W.Stack foc left right) rs = zip (foc : reverse left ++ right) $ raiseFocused (length left) rs
handleMessage l m =
return $ msum [fmap resize (fromMessage m)
,fmap incmastern (fromMessage m)]
@ -104,6 +104,10 @@ instance LayoutClass MultiCol a where
a = multiColActive l
description _ = "MultiCol"
raiseFocused :: Int -> [a] -> [a]
raiseFocused n xs = actual ++ before ++ after
where (before,rest) = splitAt n xs
(actual,after) = splitAt 1 rest
-- | Get which column a window is in, starting at 0.
getCol :: Int -> [Int] -> Int