From 62228e398ad148db461eea8aa67fb84e573bb117 Mon Sep 17 00:00:00 2001 From: Malebria Date: Fri, 23 May 2008 02:43:57 +0200 Subject: Add XMonad.Actions.Plane darcs-hash:20080523004357-1ef02-864e1b010b5eeb5e520959168ce7a8e441434be0.gz --- XMonad/Actions/Plane.hs | 134 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 XMonad/Actions/Plane.hs (limited to 'XMonad/Actions/Plane.hs') 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 , +-- License : BSD3-style (see LICENSE) +-- +-- Maintainer : Malebria +-- 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 -- cgit v1.2.3