aboutsummaryrefslogtreecommitdiffstats
path: root/XMonad/Actions/Plane.hs
diff options
context:
space:
mode:
authorMalebria <malebria@riseup.net>2008-05-23 02:43:57 +0200
committerMalebria <malebria@riseup.net>2008-05-23 02:43:57 +0200
commit62228e398ad148db461eea8aa67fb84e573bb117 (patch)
tree68270135ad6ae10a38aaea5d27881767365a7ebf /XMonad/Actions/Plane.hs
parent7e1fd1be4277b90595df3ded8d80253ecd6171ec (diff)
downloadXMonadContrib-62228e398ad148db461eea8aa67fb84e573bb117.tar.gz
XMonadContrib-62228e398ad148db461eea8aa67fb84e573bb117.tar.xz
XMonadContrib-62228e398ad148db461eea8aa67fb84e573bb117.zip
Add XMonad.Actions.Plane
darcs-hash:20080523004357-1ef02-864e1b010b5eeb5e520959168ce7a8e441434be0.gz
Diffstat (limited to 'XMonad/Actions/Plane.hs')
-rw-r--r--XMonad/Actions/Plane.hs134
1 files changed, 134 insertions, 0 deletions
diff --git a/XMonad/Actions/Plane.hs b/XMonad/Actions/Plane.hs
new file mode 100644
index 0000000..92593c5
--- /dev/null
+++ b/XMonad/Actions/Plane.hs
@@ -0,0 +1,134 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : XMonad.Actions.Plane
+-- Copyright : (c) Malebria <malebria@riseup.net>,
+-- License : BSD3-style (see LICENSE)
+--
+-- Maintainer : Malebria <malebria@riseup.net>
+-- Stability : unstable
+-- Portability : unportable
+--
+-- This module has functions to navigate through workspaces in a bidimensional
+-- manner. It allows the organization of workspaces in columns, and provides
+-- functions to move and shift windows in all four directions (left, up, right
+-- and down) possible in a surface.
+--
+-- This functionality was inspired by GNOME (finite) and KDE (infinite)
+-- keybindings for workspace navigation, and by "XMonad.Actions.CycleWS" for
+-- the idea of applying this approach to XMonad.
+-----------------------------------------------------------------------------
+
+module XMonad.Actions.Plane
+ (
+ -- * Usage
+ -- $usage
+
+ -- * Data types
+ Direction (..)
+ , Limits (..)
+
+ -- * Navigating through workspaces
+ -- $navigating
+ , planeShift
+ , planeMove
+ )
+ where
+
+import Control.Monad
+import Data.List hiding (union)
+import Data.Maybe
+
+import XMonad
+import XMonad.StackSet hiding (workspaces)
+
+-- $usage
+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@ file:
+--
+-- > import XMonad.Actions.Plane
+-- >
+-- > main = xmonad defaultConfig {keys = myKeys}
+-- >
+-- > myKeys conf = union (keys defaultConfig conf) $ myNewKeys conf
+-- >
+-- > myNewkeys (XConfig {modMask = m}) =
+-- > fromList
+-- > [ ((keyMask .|. m, keySym), function 3 Finite direction)
+-- > | (keySym, direction) <- zip [xK_Left .. xK_Down] $ enumFrom ToLeft
+-- > , (keyMask, function) <- [(0, planeMove), (shiftMask, planeShift)]
+-- > ]
+--
+-- For detailed instructions on editing your key bindings, see
+-- "XMonad.Doc.Extending#Editing_key_bindings".
+
+-- | Direction to go in the plane.
+data Direction = ToLeft | ToUp | ToRight | ToDown deriving Enum
+
+-- | Defines whether it's a finite or a circular organization of workspaces.
+data Limits
+ = Finite -- ^ When you're at a edge of the plane, there's no way to move
+ -- to the next region.
+ | Circular -- ^ If you try to move, you'll get to the other edge, on the
+ -- other side.
+ deriving Eq
+
+-- $navigating
+--
+-- There're two parameters that must be provided to navigate, and it's a good
+-- idea to use them with the same values in each keybinding.
+--
+-- The first is the number of columns in which the workspaces are going to be
+-- organized. It's possible to use a number of columns that is not a divisor
+-- of the number of workspaces, but the results are better when using a
+-- divisor. If it's not a divisor, the last line will have the remaining
+-- workspaces.
+--
+-- The other one is 'Limits'.
+
+-- | Shift a window to the next workspace in 'Direction'. Note that this will
+-- also move to the next workspace.
+planeShift
+ :: Int -- ^ Number of columns.
+ -> Limits
+ -> Direction
+ -> X ()
+planeShift = plane shift'
+
+shift' ::
+ (Eq s, Eq i, Ord a) => i -> StackSet i l a s sd -> StackSet i l a s sd
+shift' area = greedyView area . shift area
+
+-- | Move to the next workspace in 'Direction'.
+planeMove
+ :: Int -- ^ Number of columns.
+ -> Limits
+ -> Direction
+ -> X ()
+planeMove = plane greedyView
+
+plane ::
+ (WorkspaceId -> WindowSet -> WindowSet) -> Int -> Limits -> Direction ->
+ X ()
+plane function columns limits direction = do
+ state <- get
+ xconf <- ask
+ let vertical f =
+ if mod currentWS columns >= mod areas columns
+ then mod (f currentWS columns) $ div areas columns * columns
+ else mod (f currentWS columns) $ ((div areas columns + 1) * columns)
+ horizontal f = mod (f currentWS) columns + line * columns
+ line = div currentWS columns
+ column = mod currentWS columns
+ currentWS = fromJust mCurrentWS
+ mCurrentWS = elemIndex (currentTag $ windowset state) areaNames
+ run condition position =
+ when (limits == Circular || condition) $
+ windows $ function $ areaNames !! position
+ areas = length areaNames
+ areaNames = workspaces $ config $ xconf
+
+ when (isJust mCurrentWS) $
+ case direction of
+ ToUp -> run (line /= 0 ) $ vertical (-)
+ ToDown -> run (currentWS + columns < areas) $ vertical (+)
+ ToLeft -> run (column /= 0 ) $ horizontal pred
+ ToRight -> run (column /= columns - 1 ) $ horizontal succ