{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-} import XMonad import XMonad.Core import XMonad.Layout.LayoutModifier import qualified XMonad.StackSet as W --------------------- -- Random util stuff --------------------- safeSplit :: [a] -> (Maybe a, [a]) safeSplit [] = (Nothing, []) safeSplit (x:xs) = (Just x, xs) --------------- -- PiP class -- --------------- makeInsetRect (Rectangle x y w h) s = Rectangle x y sw sh where sw = floor $ fromIntegral w * s sh = floor $ fromIntegral h * s data PictureInPicture a = PictureInPicture { insetScale :: Rational } deriving (Read, Show) instance LayoutModifier PictureInPicture Window where modifyLayout (PictureInPicture ratio) = runPip ratio modifierDescription = show runPip :: (LayoutClass l Window) => Rational -> W.Workspace WorkspaceId (l Window) Window -> Rectangle -> X ([(Window, Rectangle)], Maybe (l Window)) runPip scale wksp rect = do let stack = W.stack wksp let ws = W.integrate' stack let (inset, rest) = safeSplit ws case inset of Just insetWin -> do let filteredStack = stack >>= W.filter (insetWin /=) let pipRect = makeInsetRect rect scale wrs <- runLayout (wksp {W.stack = filteredStack}) rect return ((insetWin, pipRect) : fst wrs, snd wrs) Nothing -> runLayout wksp rect withPip s = ModifiedLayout $ PictureInPicture s myLayoutHook = withPip (1/4) Full -- And the main config main :: IO () main = xmonad $ defaultConfig { terminal = "xterm" , layoutHook = myLayoutHook , modMask = mod4Mask }