mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 03:20:21 -07:00
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:
parent
ea10cbbbd8
commit
021245b5fa
@ -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.
|
||||||
|
@ -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
|
|
||||||
|
232
XMonad/Layout/Groups/Helpers.hs
Normal file
232
XMonad/Layout/Groups/Helpers.hs
Normal 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
|
133
XMonad/Layout/Groups/Wmii.hs
Normal file
133
XMonad/Layout/Groups/Wmii.hs
Normal 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"
|
||||||
|
|
@ -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
|
||||||
--
|
--
|
||||||
|
Loading…
x
Reference in New Issue
Block a user