From 7bd59751a820dbdfb132ae2f06be518bd2f7fad4 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Fri, 7 Feb 2020 14:59:09 -0700 Subject: Add LayoutModifier that ollows windows to be zoomed on with modm-z. When this happens, the window will float in the middle of the screen. --- src/Internal/Layout.hs | 112 ++++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 47 deletions(-) (limited to 'src/Internal/Layout.hs') diff --git a/src/Internal/Layout.hs b/src/Internal/Layout.hs index bdac6d1..57102c6 100644 --- a/src/Internal/Layout.hs +++ b/src/Internal/Layout.hs @@ -1,59 +1,77 @@ {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} module Internal.Layout where +import Control.Applicative +import XMonad.Layout.Spacing +import Data.List import XMonad.Layout.Spiral import XMonad.Layout.ThreeColumns import XMonad.Layout.Grid import XMonad.Layout +import XMonad.Layout.LayoutModifier import XMonad +import XMonad.Core import qualified XMonad.StackSet as W myLayout = - spiral (6/7) ||| - Tall 1 (3/100) (1/2) ||| - ThreeCol 1 (3/100) (1/2) ||| - Grid - -data Manual = Manual RectSet - -data RectSet = - RectSet { - rectSetWidth :: Float -- 0.0 - 1.0 fraction of the float. - , rectSetHeight :: Float - , subRects :: RectChildren - } - -data RectChildren = - Leaf { boundWindow :: Maybe Window } | - Children { children :: [RectSet] } - -data RectSetD = - LeafD { - boundWindowD :: Maybe Window - , parent :: RectParentD - } | - Parent { self :: RectParentD } - -data RectParentD = - RectParentD { - currentChild :: RectSetD - - , leftChildren :: [RectSetD] - , rightChildren :: [RectSetD] - - , rectSetDWidth :: Float - , rectSetDHeight :: Float - - , parentRect :: Maybe RectParentD - } - -derive :: RectSet -> Window -> Maybe RectSetD -derive (RectSet w h sub) = undefined - -getWindowRect :: Window -> X (Maybe Rectangle) -getWindowRect win = withDisplay $ \dpy -> do - (_, x, y, w, h, bw, _) <- liftIO $ getGeometry dpy win - catchX - (return $ Just $ Rectangle x y (w + 2 * bw) (h + 2 * bw)) - (return Nothing) + ModifiedLayout (Zoomable False 0.05 0.05) $ + spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True $ + spiral (6/7) ||| + Tall 1 (3/100) (1/2) ||| + ThreeCol 1 (3/100) (1/2) ||| + Grid + +data ResizeZoom = ShrinkZoom | ExpandZoom deriving (Typeable) + +instance Message ResizeZoom where + +data Zoomable a = Zoomable Bool Float Float -- True if zooming in on the focused window. + deriving (Show, Read) + +data ToggleZoom = ToggleZoom + deriving (Typeable) + +data AlterZoom = AlterZoom Float Float + deriving (Typeable) + +instance Message ToggleZoom where + +instance Message AlterZoom where + +instance (Eq a) => LayoutModifier Zoomable a where + redoLayout (Zoomable doit ws hs) (Rectangle x y w h) stack returned = + if doit + then + let focused = W.focus <$> stack + (zoomed, rest) = partition ((==focused) . Just . fst) returned + in case zoomed of + [] -> return (rest, Nothing) + ((fwin, _):_) -> return $ ((fwin, Rectangle (x + wp) (y + hp) (w - fromIntegral (wp * 2)) (h - fromIntegral (hp * 2))) : rest, Nothing) + + else return (returned, Nothing) + where + wp = floor $ (fromIntegral w) * ws + hp = floor $ (fromIntegral h) * hs + + handleMessOrMaybeModifyIt self@(Zoomable showing sw sh) mess = + return $ + (handleResize <$> fromMessage mess) + <|> ((Left . handleZoom) <$> fromMessage mess) + where + handleResize r = + if showing + then Left $ Zoomable showing (guard $ sw + d) (guard $ sh + d) + else Right $ case r of + ShrinkZoom -> SomeMessage Shrink + ExpandZoom -> SomeMessage Expand + + where d = (case r of + ShrinkZoom -> -1 + ExpandZoom -> 1) * 0.02 + + handleZoom ToggleZoom = Zoomable (not showing) sw sh + + guard f | f > 1 = 1 + | f < 0 = 0 + | otherwise = f -- cgit