module Rahm.Desktop.Layout where import Control.Applicative import Control.Arrow (second) import Data.List import qualified Data.Map as M import Data.Proxy (Proxy (..)) import Data.Typeable (cast) import GHC.TypeLits import Rahm.Desktop.Layout.Bordering import Rahm.Desktop.Layout.ConsistentMosaic import Rahm.Desktop.Layout.CornerLayout (Corner (..)) import Rahm.Desktop.Layout.Flip import Rahm.Desktop.Layout.Hole import Rahm.Desktop.Layout.List import Rahm.Desktop.Layout.Pop import Rahm.Desktop.Layout.Redescribe import Rahm.Desktop.Layout.ReinterpretMessage import Rahm.Desktop.Layout.Rotate import qualified Rahm.Desktop.StackSet as W import XMonad import XMonad.Core import XMonad.Hooks.ManageDocks import XMonad.Layout import XMonad.Layout.Accordion import XMonad.Layout.Circle import XMonad.Layout.Dishes import qualified XMonad.Layout.Dwindle as D import XMonad.Layout.Fullscreen import XMonad.Layout.Grid import XMonad.Layout.LayoutModifier import XMonad.Layout.MosaicAlt import XMonad.Layout.NoBorders (noBorders, smartBorders) import XMonad.Layout.Spacing import XMonad.Layout.Spiral import XMonad.Layout.ThreeColumns myLayout = fullscreenFull $ avoidStruts myLayoutList mySpacing = spacingRaw True (Border 5 5 5 5) True (Border 5 5 5 5) True mods = bordering . mySpacing . poppable . flippable . rotateable . hole myLayoutList = layoutList $ mods (reinterpretIncMaster $ spiral (6 / 7)) |: mods (MosaicWrap $ modifyMosaic (MosaicAlt M.empty :: MosaicAlt Window)) |: mods (reinterpretIncMaster $ Corner (3 / 4) (3 / 100)) |: mods (Redescribe UsingTall (Tall 1 (3 / 100) (1 / 2))) |: mods (Redescribe UsingThreeCol (ThreeCol 1 (3 / 100) (1 / 2))) |: mods Grid |: mods (Dishes 2 (1 / 6)) |: mods (reinterpretIncMaster $ D.Dwindle D.R D.CW 1.5 1.1) |: nil nLayouts :: Int nLayouts = layoutListLength myLayoutList -- Mosaic doesn't have the concept of a "Master Space", so reinterpret messages -- intended to modify the master space and instead have those messages expand -- and shrink the current window. -- -- "ForMosaic" is an instance of the Symbol kind. This is some neat type-system -- hacking one can do in Haskell. instance DoReinterpret "ForMosaic" where -- IncMaster message reinterpretMessage _ (fromMessage -> Just (IncMasterN n)) = do Just . SomeMessage <$> ( if n > 0 then expandPositionAlt else shrinkPositionAlt ) -- ResizeMaster message reinterpretMessage _ (fromMessage -> Just m) = do Just . SomeMessage <$> ( case m of Expand -> expandPositionAlt Shrink -> shrinkPositionAlt ) -- Messages that don't match the above, just leave it unmodified. reinterpretMessage _ m = return (Just m) instance DoReinterpret "IncMasterToResizeMaster" where reinterpretMessage _ (fromMessage -> Just (IncMasterN n)) = return $ Just $ if n > 0 then SomeMessage Expand else SomeMessage Shrink reinterpretMessage _ m = return (Just m) modifyMosaic :: l a -> ModifiedLayout (ReinterpretMessage "ForMosaic") l a modifyMosaic = ModifiedLayout ReinterpretMessage reinterpretIncMaster :: l a -> ModifiedLayout (ReinterpretMessage "IncMasterToResizeMaster") l a reinterpretIncMaster = ModifiedLayout ReinterpretMessage data UsingTall = UsingTall deriving (Read, Show) instance Describer UsingTall Tall where newDescription _ (Tall mast _ _) _ = "Tall(" ++ show mast ++ ")" data UsingThreeCol = UsingThreeCol deriving (Read, Show) instance Describer UsingThreeCol ThreeCol where newDescription _ (ThreeCol mast _ _) _ = "ThreeCol(" ++ show mast ++ ")" newDescription _ (ThreeColMid mast _ _) _ = "ThreeColMid(" ++ show mast ++ ")"