----------------------------------------------------------------------------- -- | -- Module : XMonadContrib.DragPane -- Copyright : (c) Spencer Janssen -- David Roundy , -- License : BSD3-style (see LICENSE) -- -- Maintainer : David Roundy -- Stability : unstable -- Portability : unportable -- -- Layouts that splits the screen either horizontally or vertically and -- shows two windows. The first window is always the master window, and -- the other is either the currently focused window or the second window in -- layout order. ----------------------------------------------------------------------------- module XMonadContrib.DragPane ( -- * Usage -- $usage dragPane, dragUpDownPane ) where import Control.Monad.Reader ( asks ) import Graphics.X11.Xlib ( Rectangle( Rectangle ) ) import XMonad import XMonadContrib.Decoration ( newDecoration ) import Operations ( Resize(..), splitHorizontallyBy, splitVerticallyBy, initColor, mouseDrag, sendMessage ) import StackSet ( focus, up, down) -- $usage -- -- You can use this module with the following in your Config.hs file: -- -- > import XMonadContrib.DragPane -- -- and add, to the list of layouts: -- -- > dragPane "" (fromRational delta) (fromRational delta) halfHandleWidth :: Integral a => a halfHandleWidth = 2 handleColor :: String handleColor = "#000000" dragPane :: String -> Double -> Double -> Layout a dragPane ident delta split = Layout { doLayout = dolay, modifyLayout = return . message } where dolay r s = do handlec <- withDisplay $ \dpy -> io $ initColor dpy handleColor root <- asks theRoot let (left', right') = splitHorizontallyBy split r leftmost = fromIntegral $ case r of Rectangle x _ _ _ -> x widt = fromIntegral $ case r of Rectangle _ _ w _ -> w left = case left' of Rectangle x y w h -> Rectangle x y (w-halfHandleWidth) h right = case right' of Rectangle x y w h -> Rectangle (x+halfHandleWidth) y (w-halfHandleWidth) h handr = case left' of Rectangle x y w h -> Rectangle (x + fromIntegral w - halfHandleWidth) y (2*halfHandleWidth) h wrs = case reverse (up s) of (master:_) -> [(master,left),(focus s,right)] [] -> case down s of (next:_) -> [(focus s,left),(next,right)] [] -> [(focus s, r)] handle = newDecoration root handr 0 handlec handlec "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*" (const $ const $ const $ const $ return ()) (doclick) doclick = mouseDrag (\ex _ -> sendMessage (SetFrac ident ((fromIntegral ex - leftmost)/widt))) (return ()) ml' <- if length wrs > 1 then Just `fmap` handle (dragPane ident delta split) else return Nothing return (wrs, ml') message x | Just Shrink <- fromMessage x = Just (dragPane ident delta (split - delta)) | Just Expand <- fromMessage x = Just (dragPane ident delta (split + delta)) | Just (SetFrac ident' frac) <- fromMessage x, ident' == ident = Just (dragPane ident delta frac) message _ = Nothing dragUpDownPane :: String -> Double -> Double -> Layout a dragUpDownPane ident delta split = Layout { doLayout = dolay, modifyLayout = return . message } where dolay r s = do handlec <- withDisplay $ \dpy -> io $ initColor dpy handleColor root <- asks theRoot let (left', right') = splitVerticallyBy split r leftmost = fromIntegral $ case r of Rectangle _ x _ _ -> x widt = fromIntegral $ case r of Rectangle _ _ _ w -> w left = case left' of Rectangle x y w h -> Rectangle x y w (h-halfHandleWidth) right = case right' of Rectangle x y w h -> Rectangle x (y+halfHandleWidth) w (h-halfHandleWidth) handr = case left' of Rectangle x y w h -> Rectangle x (y + fromIntegral h - halfHandleWidth) w (2*halfHandleWidth) wrs = case reverse (up s) of (master:_) -> [(master,left),(focus s,right)] [] -> case down s of (next:_) -> [(focus s,left),(next,right)] [] -> [(focus s, r)] handle = newDecoration root handr 0 handlec handlec "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*" (const $ const $ const $ const $ return ()) (doclick) doclick = mouseDrag (\_ ey -> sendMessage (SetFrac ident ((fromIntegral ey - leftmost)/widt))) (return ()) ml' <- if length wrs > 1 then Just `fmap` handle (dragUpDownPane ident delta split) else return Nothing return (wrs, ml') message x | Just Shrink <- fromMessage x = Just (dragUpDownPane ident delta (split - delta)) | Just Expand <- fromMessage x = Just (dragUpDownPane ident delta (split + delta)) | Just (SetFrac ident' frac) <- fromMessage x, ident' == ident = Just (dragUpDownPane ident delta frac) message _ = Nothing data SetFrac = SetFrac String Double deriving ( Show, Read, Eq, Typeable ) instance Message SetFrac