Split X.L.Groups.Examples

X.L.G.Examples : rowOfColumns and tiled tabs layouts
X.L.G.Helpers : helper actions
X.L.G.Wmii : wmii layout
This commit is contained in:
moserq 2010-10-01 10:41:42 +00:00
parent ea10cbbbd8
commit 021245b5fa
5 changed files with 395 additions and 313 deletions

View File

@ -73,9 +73,9 @@ import Control.Monad (forM)
-- group, and the layout with which the groups themselves will -- group, and the layout with which the groups themselves will
-- be arranged on the screen. -- be arranged on the screen.
-- --
-- The "XMonad.Layout.Groups.Examples" module contains examples of -- The "XMonad.Layout.Groups.Examples" and "XMonad.Layout.Groups.Wmii"
-- layouts that can be defined with this combinator, and useful -- modules contain examples of layouts that can be defined with this
-- operations on them. It is also the recommended starting point -- combinator. They're also the recommended starting point
-- if you are a beginner and looking for something you can use easily. -- if you are a beginner and looking for something you can use easily.
-- --
-- One thing to note is that 'Groups'-based layout have their own -- One thing to note is that 'Groups'-based layout have their own
@ -87,7 +87,7 @@ import Control.Monad (forM)
-- example 'ModifySpec's (to be passed to the 'Modify' message) provided -- example 'ModifySpec's (to be passed to the 'Modify' message) provided
-- by this module. -- by this module.
-- --
-- If you use both 'Groups'-based and other layouts, The "XMonad.Layout.Groups.Examples" -- If you use both 'Groups'-based and other layouts, The "XMonad.Layout.Groups.Helpers"
-- module provides actions that can work correctly with both, defined using -- module provides actions that can work correctly with both, defined using
-- functions from "XMonad.Actions.MessageFeedback". -- functions from "XMonad.Actions.MessageFeedback".
@ -117,10 +117,10 @@ gen (U i1 i2) = (U (i1+1) i2, zipWith U (repeat i1) [i2..])
-- | Split an infinite list into two. I ended up not -- | Split an infinite list into two. I ended up not
-- needing this, but let's keep it just in case. -- needing this, but let's keep it just in case.
split :: [a] -> ([a], [a]) -- split :: [a] -> ([a], [a])
split as = snd $ foldr step (True, ([], [])) as -- split as = snd $ foldr step (True, ([], [])) as
where step a (True, (as1, as2)) = (False, (a:as1, as2)) -- where step a (True, (as1, as2)) = (False, (a:as1, as2))
step a (False, (as1, as2)) = (True, (as1, a:as2)) -- step a (False, (as1, as2)) = (True, (as1, a:as2))
-- | Add a unique identity to a layout so we can -- | Add a unique identity to a layout so we can
-- follow it around. -- follow it around.

View File

@ -11,28 +11,16 @@
-- Stability : unstable -- Stability : unstable
-- Portability : unportable -- Portability : unportable
-- --
-- Utility functions and example layouts for "XMonad.Layout.Groups". -- Example layouts for "XMonad.Layout.Groups".
-- --
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
module XMonad.Layout.Groups.Examples ( -- * Usage module XMonad.Layout.Groups.Examples ( -- * Usage
-- $usage -- $usage
-- * Example: Wmii-like layout
-- $example1
wmiiLike
, zoomGroupIn
, zoomGroupOut
, zoomGroupReset
, toggleGroupFull
, groupToNextLayout
, groupToFullLayout
, groupToTabbedLayout
, groupToVerticalLayout
-- * Example: Row of columns -- * Example: Row of columns
-- $example2 -- $example1
, rowOfColumns rowOfColumns
, zoomColumnIn , zoomColumnIn
, zoomColumnOut , zoomColumnOut
, zoomColumnReset , zoomColumnReset
@ -43,7 +31,7 @@ module XMonad.Layout.Groups.Examples ( -- * Usage
, toggleWindowFull , toggleWindowFull
-- * Example: Tiled tab groups -- * Example: Tiled tab groups
-- $example3 -- $example2
, tallTabs , tallTabs
, mirrorTallTabs , mirrorTallTabs
, fullTabs , fullTabs
@ -55,60 +43,32 @@ module XMonad.Layout.Groups.Examples ( -- * Usage
, expandMasterGroups , expandMasterGroups
, nextOuterLayout , nextOuterLayout
-- * Useful actions
-- $actions
-- ** Layout-generic actions -- * Useful re-exports and utils
, swapUp , module XMonad.Layout.Groups.Helpers
, swapDown
, swapMaster
, focusUp
, focusDown
, focusMaster
, toggleFocusFloat
-- ** 'G.Groups'-secific actions
, swapGroupUp
, swapGroupDown
, swapGroupMaster
, focusGroupUp
, focusGroupDown
, focusGroupMaster
, moveToGroupUp
, moveToGroupDown
, moveToNewGroupUp
, moveToNewGroupDown
, splitGroup
-- * Other useful stuff, re-exports
, GroupEQ
, shrinkText , shrinkText
, defaultTheme , defaultTheme
, GroupEQ(..)
, zoomRowG
) where ) where
import XMonad hiding ((|||)) import XMonad hiding ((|||))
import qualified XMonad.StackSet as W
import qualified XMonad.Layout.Groups as G import qualified XMonad.Layout.Groups as G
import XMonad.Layout.Groups.Helpers
import XMonad.Layout.ZoomRow import XMonad.Layout.ZoomRow
import XMonad.Layout.Tabbed import XMonad.Layout.Tabbed
import XMonad.Layout.Named import XMonad.Layout.Named
import XMonad.Layout.Renamed import XMonad.Layout.Renamed
import XMonad.Layout.LayoutCombinators import XMonad.Layout.LayoutCombinators
import XMonad.Layout.MessageControl
import XMonad.Layout.Decoration import XMonad.Layout.Decoration
import XMonad.Layout.Simplest import XMonad.Layout.Simplest
import XMonad.Actions.MessageFeedback
import Control.Monad (unless)
import qualified Data.Map as M
-- $usage -- $usage
-- This module contains example 'G.Groups'-based layouts, and -- This module contains example 'G.Groups'-based layouts.
-- 'X' actions that are useful when using them. You can either -- You can either import this module directly, or look at its source
-- import this module directly, or look at its source
-- for ideas of how "XMonad.Layout.Groups" may be used. -- for ideas of how "XMonad.Layout.Groups" may be used.
-- --
-- You can use the contents of this module by adding -- You can use the contents of this module by adding
@ -122,15 +82,9 @@ import qualified Data.Map as M
-- --
-- Whichever layout you choose to use, you will probably want to be -- Whichever layout you choose to use, you will probably want to be
-- able to move focus and windows between groups in a consistent -- able to move focus and windows between groups in a consistent
-- manner. For this, you should take a look at the \"Useful Actions\" -- manner. For this, you should take a look at the functions from
-- section. -- the "XMonad.Layout.Groups.Helpers" module, which are all
-- -- re-exported by this module.
-- This module exports many operations with the same names as
-- 'G.ModifySpec's from "XMonad.Layout.Groups", so if you want
-- to import both, we suggest to import "XMonad.Layout.Groups"
-- qualified:
--
-- > import qualified XMonad.Layout.Groups as G
-- --
-- For more information on how to extend your layour hook and key bindings, see -- For more information on how to extend your layour hook and key bindings, see
-- "XMonad.Doc.Extending". -- "XMonad.Doc.Extending".
@ -150,81 +104,9 @@ zoomRowG :: (Eq a, Show a, Read a, Show (l a), Read (l a))
zoomRowG = zoomRowWith GroupEQ zoomRowG = zoomRowWith GroupEQ
-- * Example 1: Wmii-like layout -- * Example 1: Row of columns
-- $example1 -- $example1
-- A layout inspired by the one used by the wmii (<http://wmii.suckless.org>).
-- Windows groups are arranged in a horizontal row, and each group can lay out
-- its windows
--
-- * by maximizing the focused one
--
-- * by tabbing them (wmii uses a stacked layout, but I'm too lazy to write it)
--
-- * by arranging them in a column.
--
-- As the groups are arranged in a 'ZoomRow', the width of each group can be increased
-- or decreased at will. Groups can also be set to use the whole screen whenever they
-- have focus.
--
-- To use this layout, add 'wmiiLike' (with a 'Shrinker' and decoration 'Theme' as
-- parameters) to your layout hook, for example:
--
-- > myLayout = wmiiLike shrinkText defaultTheme
--
-- To be able to zoom in and out of groups, change their inner layout, etc.,
-- create key bindings for the relevant actions:
--
-- > ((modMask, xK_f), toggleGroupFull)
--
-- and so on.
wmiiLike s t = G.group innerLayout zoomRowG
where column = named "Column" $ Tall 0 (3/100) (1/2)
tabs = named "Tabs" $ Simplest
innerLayout = renamed [CutWordsLeft 3]
$ addTabs s t
$ ignore NextLayout
$ ignore (JumpToLayout "") $ unEscape
$ column ||| tabs ||| Full
-- | Increase the width of the focused group
zoomGroupIn :: X ()
zoomGroupIn = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomIn
-- | Decrease the size of the focused group
zoomGroupOut :: X ()
zoomGroupOut = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomOut
-- | Reset the size of the focused group to the default
zoomGroupReset :: X ()
zoomGroupReset = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomReset
-- | Toggle whether the currently focused group should be maximized
-- whenever it has focus.
toggleGroupFull :: X ()
toggleGroupFull = sendMessage $ G.ToEnclosing $ SomeMessage $ ZoomFullToggle
-- | Rotate the layouts in the focused group.
groupToNextLayout :: X ()
groupToNextLayout = sendMessage $ escape NextLayout
-- | Switch the focused group to the \"maximized\" layout.
groupToFullLayout :: X ()
groupToFullLayout = sendMessage $ escape $ JumpToLayout "Full"
-- | Switch the focused group to the \"tabbed\" layout.
groupToTabbedLayout :: X ()
groupToTabbedLayout = sendMessage $ escape $ JumpToLayout "Tabs"
-- | Switch the focused group to the \"column\" layout.
groupToVerticalLayout :: X ()
groupToVerticalLayout = sendMessage $ escape $ JumpToLayout "Column"
-- * Example 2: Row of columns
-- $example2
-- A layout that arranges windows in a row of columns. It uses 'ZoomRow's for -- A layout that arranges windows in a row of columns. It uses 'ZoomRow's for
-- both, allowing you to: -- both, allowing you to:
-- --
@ -252,20 +134,20 @@ rowOfColumns = G.group column zoomRowG
-- | Increase the width of the focused column -- | Increase the width of the focused column
zoomColumnIn :: X () zoomColumnIn :: X ()
zoomColumnIn = zoomGroupIn zoomColumnIn = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomIn
-- | Decrease the width of the focused column -- | Decrease the width of the focused column
zoomColumnOut :: X () zoomColumnOut :: X ()
zoomColumnOut = zoomGroupOut zoomColumnOut = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomOut
-- | Reset the width of the focused column -- | Reset the width of the focused column
zoomColumnReset :: X () zoomColumnReset :: X ()
zoomColumnReset = zoomGroupReset zoomColumnReset = sendMessage $ G.ToEnclosing $ SomeMessage $ zoomReset
-- | Toggle whether the currently focused column should -- | Toggle whether the currently focused column should
-- take up all available space whenever it has focus -- take up all available space whenever it has focus
toggleColumnFull :: X () toggleColumnFull :: X ()
toggleColumnFull = toggleGroupFull toggleColumnFull = sendMessage $ G.ToEnclosing $ SomeMessage $ ZoomFullToggle
-- | Increase the heigth of the focused window -- | Increase the heigth of the focused window
zoomWindowIn :: X () zoomWindowIn :: X ()
@ -285,9 +167,9 @@ toggleWindowFull :: X ()
toggleWindowFull = sendMessage ZoomFullToggle toggleWindowFull = sendMessage ZoomFullToggle
-- * Example 3: Tabbed groups in a Tall/Full layout. -- * Example 2: Tabbed groups in a Tall/Full layout.
-- $example3 -- $example2
-- A layout which arranges windows into tabbed groups, and the groups -- A layout which arranges windows into tabbed groups, and the groups
-- themselves according to XMonad's default algorithm -- themselves according to XMonad's default algorithm
-- (@'Tall' ||| 'Mirror' 'Tall' ||| 'Full'@). As their names -- (@'Tall' ||| 'Mirror' 'Tall' ||| 'Full'@). As their names
@ -356,168 +238,3 @@ expandMasterGroups = sendMessage $ G.ToEnclosing $ SomeMessage $ Expand
nextOuterLayout :: X () nextOuterLayout :: X ()
nextOuterLayout = sendMessage $ G.ToEnclosing $ SomeMessage $ NextLayout nextOuterLayout = sendMessage $ G.ToEnclosing $ SomeMessage $ NextLayout
-- * Useful actions
-- $actions
-- "XMonad.Layout.Groups"-based layouts do not have the same notion
-- of window ordering as the rest of XMonad. For this reason, the usual
-- ways of reordering windows and moving focus do not work with them.
-- "XMonad.Layout.Groups" provides 'Message's that can be used to obtain
-- the right effect.
--
-- But what if you want to use both 'G.Groups' and other layouts?
-- This module provides actions that try to send 'G.GroupsMessage's, and
-- fall back to the classic way if the current layout doesn't hande them.
-- They are in the section called \"Layout-generic actions\".
--
-- The sections \"Groups-specific actions\" contains actions that don't make
-- sense for non-'G.Groups'-based layouts. These are simply wrappers around
-- the equivalent 'G.GroupsMessage's, but are included so you don't have to
-- write @sendMessage $ Modify $ ...@ everytime.
-- ** Layout-generic actions
-- #Layout-generic actions#
alt :: G.ModifySpec -> (WindowSet -> WindowSet) -> X ()
alt f g = alt2 (G.Modify f) $ windows g
alt2 :: G.GroupsMessage -> X () -> X ()
alt2 m x = do b <- send m
unless b x
-- | Swap the focused window with the previous one
swapUp :: X ()
swapUp = alt G.swapUp W.swapUp
-- | Swap the focused window with the next one
swapDown :: X ()
swapDown = alt G.swapDown W.swapDown
-- | Swap the focused window with the master window
swapMaster :: X ()
swapMaster = alt G.swapMaster W.swapMaster
-- | If the focused window is floating, focus the next floating
-- window. otherwise, focus the next non-floating one.
focusUp :: X ()
focusUp = ifFloat focusFloatUp focusNonFloatUp
-- | If the focused window is floating, focus the next floating
-- window. otherwise, focus the next non-floating one.
focusDown :: X ()
focusDown = ifFloat focusFloatDown focusNonFloatDown
-- | Move focus to the master window
focusMaster :: X ()
focusMaster = alt G.focusMaster W.shiftMaster
-- | Move focus between the floating and non-floating layers
toggleFocusFloat :: X ()
toggleFocusFloat = ifFloat focusNonFloat focusFloatUp
-- *** Floating layer helpers
getFloats :: X [Window]
getFloats = gets $ M.keys . W.floating . windowset
getWindows :: X [Window]
getWindows = gets $ W.integrate' . W.stack . W.workspace . W.current . windowset
ifFloat :: X () -> X () -> X ()
ifFloat x1 x2 = withFocused $ \w -> do floats <- getFloats
if elem w floats then x1 else x2
focusNonFloat :: X ()
focusNonFloat = alt2 G.Refocus helper
where helper = withFocused $ \w -> do
ws <- getWindows
floats <- getFloats
let (before, after) = span (/=w) ws
case filter (flip notElem floats) $ after ++ before of
[] -> return ()
w':_ -> focus w'
focusHelper :: (Bool -> Bool) -- ^ if you want to focus a floating window, 'id'.
-- if you want a non-floating one, 'not'.
-> ([Window] -> [Window]) -- ^ if you want the next window, 'id'.
-- if you want the previous one, 'reverse'.
-> X ()
focusHelper f g = withFocused $ \w -> do
ws <- getWindows
let (before, _:after) = span (/=w) ws
let toFocus = g $ after ++ before
floats <- getFloats
case filter (f . flip elem floats) toFocus of
[] -> return ()
w':_ -> focus w'
focusNonFloatUp :: X ()
focusNonFloatUp = alt2 (G.Modify G.focusUp) $ focusHelper not reverse
focusNonFloatDown :: X ()
focusNonFloatDown = alt2 (G.Modify G.focusDown) $ focusHelper not id
focusFloatUp :: X ()
focusFloatUp = focusHelper id reverse
focusFloatDown :: X ()
focusFloatDown = focusHelper id id
-- ** Groups-specific actions
wrap :: G.ModifySpec -> X ()
wrap = sendMessage . G.Modify
-- | Swap the focused group with the previous one
swapGroupUp :: X ()
swapGroupUp = wrap G.swapGroupUp
-- | Swap the focused group with the next one
swapGroupDown :: X ()
swapGroupDown = wrap G.swapGroupDown
-- | Swap the focused group with the master group
swapGroupMaster :: X ()
swapGroupMaster = wrap G.swapGroupMaster
-- | Move the focus to the previous group
focusGroupUp :: X ()
focusGroupUp = wrap G.focusGroupUp
-- | Move the focus to the next group
focusGroupDown :: X ()
focusGroupDown = wrap G.focusGroupDown
-- | Move the focus to the master group
focusGroupMaster :: X ()
focusGroupMaster = wrap G.focusGroupMaster
-- | Move the focused window to the previous group. The 'Bool' argument
-- determines what will be done if the focused window is in the very first
-- group: Wrap back to the end ('True'), or create a new group before
-- it ('False').
moveToGroupUp :: Bool -> X ()
moveToGroupUp = wrap . G.moveToGroupUp
-- | Move the focused window to the next group. The 'Bool' argument
-- determines what will be done if the focused window is in the very last
-- group: Wrap back to the beginning ('True'), or create a new group after
-- it ('False').
moveToGroupDown :: Bool -> X ()
moveToGroupDown = wrap . G.moveToGroupDown
-- | Move the focused window to a new group before the current one
moveToNewGroupUp :: X ()
moveToNewGroupUp = wrap G.moveToNewGroupUp
-- | Move the focused window to a new group after the current one
moveToNewGroupDown :: X ()
moveToNewGroupDown = wrap G.moveToNewGroupDown
-- | Split the focused group in two at the position of the focused
-- window.
splitGroup :: X ()
splitGroup = wrap G.splitGroup

View File

@ -0,0 +1,232 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
{-# LANGUAGE MultiParamTypeClasses, Rank2Types #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.Groups.Helpers
-- Copyright : Quentin Moser <moserq@gmail.com>
-- License : BSD-style (see LICENSE)
--
-- Maintainer : orphaned
-- Stability : stable
-- Portability : unportable
--
-- Utility functions for "XMonad.Layout.Groups".
--
-----------------------------------------------------------------------------
module XMonad.Layout.Groups.Helpers ( -- * Usage
-- $usage
-- ** Layout-generic actions
swapUp
, swapDown
, swapMaster
, focusUp
, focusDown
, focusMaster
, toggleFocusFloat
-- ** 'G.Groups'-secific actions
, swapGroupUp
, swapGroupDown
, swapGroupMaster
, focusGroupUp
, focusGroupDown
, focusGroupMaster
, moveToGroupUp
, moveToGroupDown
, moveToNewGroupUp
, moveToNewGroupDown
, splitGroup ) where
import XMonad hiding ((|||))
import qualified XMonad.StackSet as W
import qualified XMonad.Layout.Groups as G
import XMonad.Actions.MessageFeedback
import Control.Monad (unless)
import qualified Data.Map as M
-- $usage
--
-- This module provides helpers functions for use with "XMonad.Layout.Groups"-based
-- layouts. You can use its contents by adding
--
-- > import XMonad.Layout.Groups.Helpers
--
-- to the top of your @.\/.xmonad\/xmonad.hs@.
--
-- "XMonad.Layout.Groups"-based layouts do not have the same notion
-- of window ordering as the rest of XMonad. For this reason, the usual
-- ways of reordering windows and moving focus do not work with them.
-- "XMonad.Layout.Groups" provides 'Message's that can be used to obtain
-- the right effect.
--
-- But what if you want to use both 'G.Groups' and other layouts?
-- This module provides actions that try to send 'G.GroupsMessage's, and
-- fall back to the classic way if the current layout doesn't hande them.
-- They are in the section called \"Layout-generic actions\".
--
-- The sections \"Groups-specific actions\" contains actions that don't make
-- sense for non-'G.Groups'-based layouts. These are simply wrappers around
-- the equivalent 'G.GroupsMessage's, but are included so you don't have to
-- write @sendMessage $ Modify $ ...@ everytime.
--
-- This module exports many operations with the same names as
-- 'G.ModifySpec's from "XMonad.Layout.Groups", so if you want
-- to import both, we suggest to import "XMonad.Layout.Groups"
-- qualified:
--
-- > import qualified XMonad.Layout.Groups as G
--
-- For more information on how to extend your layour hook and key bindings, see
-- "XMonad.Doc.Extending".
-- ** Layout-generic actions
-- #Layout-generic actions#
alt :: G.ModifySpec -> (WindowSet -> WindowSet) -> X ()
alt f g = alt2 (G.Modify f) $ windows g
alt2 :: G.GroupsMessage -> X () -> X ()
alt2 m x = do b <- send m
unless b x
-- | Swap the focused window with the previous one
swapUp :: X ()
swapUp = alt G.swapUp W.swapUp
-- | Swap the focused window with the next one
swapDown :: X ()
swapDown = alt G.swapDown W.swapDown
-- | Swap the focused window with the master window
swapMaster :: X ()
swapMaster = alt G.swapMaster W.swapMaster
-- | If the focused window is floating, focus the next floating
-- window. otherwise, focus the next non-floating one.
focusUp :: X ()
focusUp = ifFloat focusFloatUp focusNonFloatUp
-- | If the focused window is floating, focus the next floating
-- window. otherwise, focus the next non-floating one.
focusDown :: X ()
focusDown = ifFloat focusFloatDown focusNonFloatDown
-- | Move focus to the master window
focusMaster :: X ()
focusMaster = alt G.focusMaster W.shiftMaster
-- | Move focus between the floating and non-floating layers
toggleFocusFloat :: X ()
toggleFocusFloat = ifFloat focusNonFloat focusFloatUp
-- *** Floating layer helpers
getFloats :: X [Window]
getFloats = gets $ M.keys . W.floating . windowset
getWindows :: X [Window]
getWindows = gets $ W.integrate' . W.stack . W.workspace . W.current . windowset
ifFloat :: X () -> X () -> X ()
ifFloat x1 x2 = withFocused $ \w -> do floats <- getFloats
if elem w floats then x1 else x2
focusNonFloat :: X ()
focusNonFloat = alt2 G.Refocus helper
where helper = withFocused $ \w -> do
ws <- getWindows
floats <- getFloats
let (before, after) = span (/=w) ws
case filter (flip notElem floats) $ after ++ before of
[] -> return ()
w':_ -> focus w'
focusHelper :: (Bool -> Bool) -- ^ if you want to focus a floating window, 'id'.
-- if you want a non-floating one, 'not'.
-> ([Window] -> [Window]) -- ^ if you want the next window, 'id'.
-- if you want the previous one, 'reverse'.
-> X ()
focusHelper f g = withFocused $ \w -> do
ws <- getWindows
let (before, _:after) = span (/=w) ws
let toFocus = g $ after ++ before
floats <- getFloats
case filter (f . flip elem floats) toFocus of
[] -> return ()
w':_ -> focus w'
focusNonFloatUp :: X ()
focusNonFloatUp = alt2 (G.Modify G.focusUp) $ focusHelper not reverse
focusNonFloatDown :: X ()
focusNonFloatDown = alt2 (G.Modify G.focusDown) $ focusHelper not id
focusFloatUp :: X ()
focusFloatUp = focusHelper id reverse
focusFloatDown :: X ()
focusFloatDown = focusHelper id id
-- ** Groups-specific actions
wrap :: G.ModifySpec -> X ()
wrap = sendMessage . G.Modify
-- | Swap the focused group with the previous one
swapGroupUp :: X ()
swapGroupUp = wrap G.swapGroupUp
-- | Swap the focused group with the next one
swapGroupDown :: X ()
swapGroupDown = wrap G.swapGroupDown
-- | Swap the focused group with the master group
swapGroupMaster :: X ()
swapGroupMaster = wrap G.swapGroupMaster
-- | Move the focus to the previous group
focusGroupUp :: X ()
focusGroupUp = wrap G.focusGroupUp
-- | Move the focus to the next group
focusGroupDown :: X ()
focusGroupDown = wrap G.focusGroupDown
-- | Move the focus to the master group
focusGroupMaster :: X ()
focusGroupMaster = wrap G.focusGroupMaster
-- | Move the focused window to the previous group. The 'Bool' argument
-- determines what will be done if the focused window is in the very first
-- group: Wrap back to the end ('True'), or create a new group before
-- it ('False').
moveToGroupUp :: Bool -> X ()
moveToGroupUp = wrap . G.moveToGroupUp
-- | Move the focused window to the next group. The 'Bool' argument
-- determines what will be done if the focused window is in the very last
-- group: Wrap back to the beginning ('True'), or create a new group after
-- it ('False').
moveToGroupDown :: Bool -> X ()
moveToGroupDown = wrap . G.moveToGroupDown
-- | Move the focused window to a new group before the current one
moveToNewGroupUp :: X ()
moveToNewGroupUp = wrap G.moveToNewGroupUp
-- | Move the focused window to a new group after the current one
moveToNewGroupDown :: X ()
moveToNewGroupDown = wrap G.moveToNewGroupDown
-- | Split the focused group in two at the position of the focused
-- window.
splitGroup :: X ()
splitGroup = wrap G.splitGroup

View File

@ -0,0 +1,133 @@
{-# OPTIONS_GHC -fno-warn-missing-signatures #-}
{-# LANGUAGE MultiParamTypeClasses, Rank2Types #-}
-----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.Groups.Wmii
-- Copyright : Quentin Moser <moserq@gmail.com>
-- License : BSD-style (see LICENSE)
--
-- Maintainer : orphaned
-- Stability : stable
-- Portability : unportable
--
-- A wmii-like layout algorithm.
--
-----------------------------------------------------------------------------
module XMonad.Layout.Groups.Wmii ( -- * Usage
-- $usage
wmii
, zoomGroupIn
, zoomGroupOut
, zoomGroupReset
, toggleGroupFull
, groupToNextLayout
, groupToFullLayout
, groupToTabbedLayout
, groupToVerticalLayout
-- * Useful re-exports
, shrinkText
, defaultTheme
, module XMonad.Layout.Groups.Helpers ) where
import XMonad hiding ((|||))
import qualified XMonad.Layout.Groups as G
import XMonad.Layout.Groups.Examples
import XMonad.Layout.Groups.Helpers
import XMonad.Layout.Tabbed
import XMonad.Layout.Named
import XMonad.Layout.Renamed
import XMonad.Layout.LayoutCombinators
import XMonad.Layout.MessageControl
import XMonad.Layout.Simplest
-- $usage
-- This module provides a layout inspired by the one used by the wmii
-- (<http://wmii.suckless.org>) window manager.
-- Windows are arranged into groups in a horizontal row, and each group can lay out
-- its windows
--
-- * by maximizing the focused one
--
-- * by tabbing them (wmii uses a stacked layout, but I'm too lazy to write it)
--
-- * by arranging them in a column.
--
-- As the groups are arranged in a 'ZoomRow', the relative width of each group can be
-- increased or decreased at will. Groups can also be set to use the whole screen
-- whenever they have focus.
--
-- You can use the contents of this module by adding
--
-- > import XMonad.Layout.Groups.Wmii
--
-- to the top of your @.\/.xmonad\/xmonad.hs@, and adding 'wmii'
-- (with a 'Shrinker' and decoration 'Theme' as
-- parameters) to your layout hook, for example:
--
-- > myLayout = wmii shrinkText defaultTheme
--
-- To be able to zoom in and out of groups, change their inner layout, etc.,
-- create key bindings for the relevant actions:
--
-- > ((modMask, xK_f), toggleGroupFull)
--
-- and so on.
--
-- For more information on how to extend your layout hook and key bindings, see
-- "XMonad.Doc.Extending".
--
-- Finally, you will probably want to be able to move focus and windows
-- between groups in a consistent fashion. For this, you should take a look
-- at the "XMonad.Layout.Groups.Helpers" module, whose contents are re-exported
-- by this module.
-- | A layout inspired by wmii
wmii s t = G.group innerLayout zoomRowG
where column = named "Column" $ Tall 0 (3/100) (1/2)
tabs = named "Tabs" $ Simplest
innerLayout = renamed [CutWordsLeft 3]
$ addTabs s t
$ ignore NextLayout
$ ignore (JumpToLayout "") $ unEscape
$ column ||| tabs ||| Full
-- | Increase the width of the focused group
zoomGroupIn :: X ()
zoomGroupIn = zoomColumnIn
-- | Decrease the size of the focused group
zoomGroupOut :: X ()
zoomGroupOut = zoomColumnOut
-- | Reset the size of the focused group to the default
zoomGroupReset :: X ()
zoomGroupReset = zoomColumnReset
-- | Toggle whether the currently focused group should be maximized
-- whenever it has focus.
toggleGroupFull :: X ()
toggleGroupFull = toggleGroupFull
-- | Rotate the layouts in the focused group.
groupToNextLayout :: X ()
groupToNextLayout = sendMessage $ escape NextLayout
-- | Switch the focused group to the \"maximized\" layout.
groupToFullLayout :: X ()
groupToFullLayout = sendMessage $ escape $ JumpToLayout "Full"
-- | Switch the focused group to the \"tabbed\" layout.
groupToTabbedLayout :: X ()
groupToTabbedLayout = sendMessage $ escape $ JumpToLayout "Tabs"
-- | Switch the focused group to the \"column\" layout.
groupToVerticalLayout :: X ()
groupToVerticalLayout = sendMessage $ escape $ JumpToLayout "Column"

View File

@ -6,7 +6,7 @@
-- Copyright : (c) 2008 Quentin Moser -- Copyright : (c) 2008 Quentin Moser
-- License : BSD3 -- License : BSD3
-- --
-- Maintainer : <moserq@gmail.com> -- Maintainer : orphaned
-- Stability : unstable -- Stability : unstable
-- Portability : unportable -- Portability : unportable
-- --