mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-18 19:10:21 -07:00
With XDG support so firmly ingrained now, it's about time we stop hard-coding the configuration path in the docs.
141 lines
5.0 KiB
Haskell
141 lines
5.0 KiB
Haskell
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FlexibleContexts, PatternGuards #-}
|
|
|
|
-----------------------------------------------------------------------------
|
|
-- |
|
|
-- Module : XMonad.Layout.Master
|
|
-- Description : Layout modfier that adds a master window to another layout.
|
|
-- Copyright : (c) Ismael Carnales, Lukas Mai
|
|
-- License : BSD-style (see LICENSE)
|
|
--
|
|
-- Maintainer : Ismael Carnales <icarnales@gmail.com>
|
|
-- Stability : unstable
|
|
-- Portability : unportable
|
|
--
|
|
-- Layout modfier that adds a master window to another layout.
|
|
-----------------------------------------------------------------------------
|
|
|
|
module XMonad.Layout.Master (
|
|
-- * Usage
|
|
-- $usage
|
|
|
|
mastered,
|
|
fixMastered,
|
|
multimastered,
|
|
AddMaster,
|
|
) where
|
|
|
|
import XMonad
|
|
import qualified XMonad.StackSet as S
|
|
import XMonad.Layout.LayoutModifier
|
|
|
|
import Control.Arrow (first)
|
|
|
|
-- $usage
|
|
-- You can use this module with the following in your @xmonad.hs@:
|
|
--
|
|
-- > import XMonad.Layout.Master
|
|
--
|
|
-- Then edit your @layoutHook@ and add the Master modifier to the layout that
|
|
-- you prefer.
|
|
--
|
|
-- > mastered (1/100) (1/2) $ Grid
|
|
--
|
|
-- Or if you prefer to have a master with fixed width:
|
|
--
|
|
-- > fixMastered (1/100) (1/2) $ Grid
|
|
--
|
|
-- Or if you want multiple (here two) master windows from the beginning:
|
|
--
|
|
-- > multimastered 2 (1/100) (1/2) $ Grid
|
|
--
|
|
-- This will use the left half of your screen for a master window and let
|
|
-- Grid manage the right half.
|
|
--
|
|
-- For more detailed instructions on editing the layoutHook see
|
|
-- <https://xmonad.org/TUTORIAL.html#customizing-xmonad the tutorial> and
|
|
-- "XMonad.Doc.Extending#Editing_the_layout_hook".
|
|
--
|
|
-- Like 'XMonad.Layout.Tall', 'withMaster' supports the
|
|
-- 'XMonad.Layout.Shrink' and XMonad.Layout.Expand' messages.
|
|
|
|
-- | Data type for LayoutModifier which converts given layout to a mastered
|
|
-- layout
|
|
data AddMaster a = AddMaster Int Rational Rational deriving (Show, Read)
|
|
|
|
multimastered :: (LayoutClass l a) =>
|
|
Int -- ^ @k@, number of master windows
|
|
-> Rational -- ^ @delta@, the ratio of the screen to resize by
|
|
-> Rational -- ^ @frac@, what portion of the screen to use for the master window
|
|
-> l a -- ^ the layout to be modified
|
|
-> ModifiedLayout AddMaster l a
|
|
multimastered k delta frac = ModifiedLayout $ AddMaster k delta frac
|
|
|
|
mastered :: (LayoutClass l a) =>
|
|
Rational -- ^ @delta@, the ratio of the screen to resize by
|
|
-> Rational -- ^ @frac@, what portion of the screen to use for the master window
|
|
-> l a -- ^ the layout to be modified
|
|
-> ModifiedLayout AddMaster l a
|
|
mastered = multimastered 1
|
|
|
|
instance LayoutModifier AddMaster Window where
|
|
modifyLayout (AddMaster k delta frac) = applyMaster False k delta frac
|
|
modifierDescription _ = "Mastered"
|
|
|
|
pureMess (AddMaster k delta frac) m
|
|
| Just Shrink <- fromMessage m = Just $ AddMaster k delta (frac-delta)
|
|
| Just Expand <- fromMessage m = Just $ AddMaster k delta (frac+delta)
|
|
| Just (IncMasterN d) <- fromMessage m = Just $ AddMaster (max 1 (k+d)) delta frac
|
|
|
|
pureMess _ _ = Nothing
|
|
|
|
newtype FixMaster a = FixMaster (AddMaster a) deriving (Show, Read)
|
|
|
|
instance LayoutModifier FixMaster Window where
|
|
modifyLayout (FixMaster (AddMaster k d f)) = applyMaster True k d f
|
|
modifierDescription (FixMaster a) = "Fix" ++ modifierDescription a
|
|
pureMess (FixMaster a) m = fmap FixMaster (pureMess a m)
|
|
|
|
fixMastered :: (LayoutClass l a) =>
|
|
Rational -- ^ @delta@, the ratio of the screen to resize by
|
|
-> Rational -- ^ @frac@, what portion of the screen to use for the master window
|
|
-> l a -- ^ the layout to be modified
|
|
-> ModifiedLayout FixMaster l a
|
|
fixMastered delta frac = ModifiedLayout . FixMaster $ AddMaster 1 delta frac
|
|
|
|
-- | Internal function for adding a master window and let the modified
|
|
-- layout handle the rest of the windows
|
|
applyMaster :: (LayoutClass l Window) =>
|
|
Bool
|
|
-> Int
|
|
-> Rational
|
|
-> Rational
|
|
-> S.Workspace WorkspaceId (l Window) Window
|
|
-> Rectangle
|
|
-> X ([(Window, Rectangle)], Maybe (l Window))
|
|
applyMaster f k _ frac wksp rect = do
|
|
let st= S.stack wksp
|
|
let ws = S.integrate' st
|
|
let n = length ws + fromEnum f
|
|
if n > 1 then
|
|
if n<=k then
|
|
return (divideCol rect ws, Nothing)
|
|
else do
|
|
let m = take k ws
|
|
let (mr, sr) = splitHorizontallyBy frac rect
|
|
let nst = st>>= S.filter (`notElem` m)
|
|
wrs <- runLayout (wksp {S.stack = nst}) sr
|
|
return (first (divideCol mr m ++) wrs)
|
|
else runLayout wksp rect
|
|
|
|
-- | Shift rectangle down
|
|
shiftD :: Position -> Rectangle -> Rectangle
|
|
shiftD s (Rectangle x y w h) = Rectangle x (y+s) w h
|
|
|
|
-- | Divide rectangle between windows
|
|
divideCol :: Rectangle -> [a] -> [(a, Rectangle)]
|
|
divideCol (Rectangle x y w h) ws = zip ws rects
|
|
where n = length ws
|
|
oneH = fromIntegral h `div` n
|
|
oneRect = Rectangle x y w (fromIntegral oneH)
|
|
rects = take n $ iterate (shiftD (fromIntegral oneH)) oneRect
|