aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--XMonad/Actions/Workscreen.hs109
-rw-r--r--xmonad-contrib.cabal1
2 files changed, 110 insertions, 0 deletions
diff --git a/XMonad/Actions/Workscreen.hs b/XMonad/Actions/Workscreen.hs
new file mode 100644
index 0000000..80f1b37
--- /dev/null
+++ b/XMonad/Actions/Workscreen.hs
@@ -0,0 +1,109 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module : XMonad.Actions.Workscreen
+-- Copyright : (c) 2012 kedals0
+-- License : BSD3-style (see LICENSE)
+--
+-- Maintainer : Dal <kedasl0@gmail.com>
+-- Stability : unstable
+-- Portability: unportable
+--
+-- A workscreen permits to display a set of workspaces on several
+-- screens. In xinerama mode, when a workscreen is viewed, workspaces
+-- associated to all screens are visible.
+
+-- The first workspace of a workscreen is displayed on first screen,
+-- second on second screen, etc. Workspace position can be easily
+-- changed. If the current workscreen is called again, workspaces are
+-- shifted.
+--
+-- This also permits to see all workspaces of a workscreen even if just
+-- one screen is present, and to move windows from workspace to workscreen.
+-----------------------------------------------------------------------------
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module XMonad.Actions.Workscreen (
+ -- * Usage
+ -- $usage
+ configWorkscreen
+ ,viewWorkscreen
+ ,Workscreen(..)
+ ,shiftToWorkscreen
+ ,fromWorkspace
+ ,expandWorkspace
+ ) where
+
+import XMonad hiding (workspaces)
+import qualified XMonad.StackSet as W
+import qualified XMonad.Util.ExtensibleState as XS
+import XMonad.Actions.OnScreen
+
+-- $usage
+-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
+--
+-- > import XMonad.Actions.Workscreen
+-- > myWorkspaces = let myOldWorkspaces = ["adm","work","mail"]
+-- > in Workscreen.expandWorkspace 2 myOldWorkspaces
+-- > myStartupHook = do Workscreen.configWorkscreen (Workscreen.fromWorkspace 2 myWorkspaces)
+-- > return ()
+--
+-- Then, replace normal workspace view and shift keybinding:
+--
+-- > [((m .|. modm, k), f i)
+-- > | (i, k) <- zip [0..] [1..12]
+-- > , (f, m) <- [(Workscreen.viewWorkscreen, 0), (Workscreen.shiftToWorkscreen, shiftMask)]]
+--
+-- For detailed instructions on editing your key bindings, see
+-- "XMonad.Doc.Extending#Editing_key_bindings".
+
+
+data Workscreen = Workscreen{workscreenId::Int,workspaces::[WorkspaceId]} deriving (Show,Typeable)
+type WorkscreenId=Int
+
+data WorkscreenStorage = WorkscreenStorage WorkscreenId [Workscreen] deriving (Show,Typeable)
+instance ExtensionClass WorkscreenStorage where
+ initialValue = WorkscreenStorage 0 []
+
+-- | Helper to group workspaces. Multiply workspace by screens number.
+expandWorkspace :: Int -> [WorkspaceId] -> [WorkspaceId]
+expandWorkspace nscr ws = concat $ map expandId ws
+ where expandId wsId = let t = wsId ++ "_"
+ in map ((++) t . show ) [1..nscr]
+
+-- | Create workscreen list from workspace list. Group workspaces to
+-- packets of screens number size.
+fromWorkspace :: Int -> [WorkspaceId] -> [Workscreen]
+fromWorkspace n ws = map (\(a,b) -> Workscreen a b) $ zip [0..] (fromWorkspace' n ws)
+fromWorkspace' :: Int -> [WorkspaceId] -> [[WorkspaceId]]
+fromWorkspace' _ [] = []
+fromWorkspace' n ws = take n ws : fromWorkspace' n (drop n ws)
+
+-- | Initial configuration of workscreens
+configWorkscreen :: [Workscreen] -> X ()
+configWorkscreen wscrn = XS.put (WorkscreenStorage 0 wscrn)
+
+-- | View workscreen of index @WorkscreenId@. If current workscreen is asked
+-- workscreen, workscreen's workspaces are shifted.
+viewWorkscreen :: WorkscreenId -> X ()
+viewWorkscreen wscrId = do (WorkscreenStorage c a) <- XS.get
+ let wscr = if wscrId == c
+ then Workscreen wscrId $ shiftWs (workspaces $ a !! wscrId)
+ else a !! wscrId
+ (x,_:ys) = splitAt wscrId a
+ newWorkscreenStorage = WorkscreenStorage wscrId (x ++ [wscr] ++ ys)
+ windows (viewWorkscreen' wscr)
+ XS.put newWorkscreenStorage
+
+viewWorkscreen' :: Workscreen -> WindowSet -> WindowSet
+viewWorkscreen' (Workscreen _ ws) = \s -> foldl wsToSc' s (zip [0..] ws)
+ where wsToSc' s (scr,wsId) = greedyViewOnScreen scr wsId s
+
+shiftWs :: [WorkspaceId] -> [WorkspaceId]
+shiftWs a = drop 1 a ++ take 1 a
+
+-- | Shift a window on the first workspace of workscreen
+-- @WorkscreenId@.
+shiftToWorkscreen :: WorkscreenId -> X ()
+shiftToWorkscreen wscrId = do (WorkscreenStorage _ a) <- XS.get
+ let ws = head . workspaces $ a !! wscrId
+ windows $ W.shift ws
diff --git a/xmonad-contrib.cabal b/xmonad-contrib.cabal
index d481139..76b5e1d 100644
--- a/xmonad-contrib.cabal
+++ b/xmonad-contrib.cabal
@@ -133,6 +133,7 @@ library
XMonad.Actions.WithAll
XMonad.Actions.WorkspaceCursors
XMonad.Actions.WorkspaceNames
+ XMonad.Actions.Workscreen
XMonad.Config.Arossato
XMonad.Config.Azerty
XMonad.Config.Bluetile