mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-18 19:10:21 -07:00
All hints are applied in one single commit, as a commit per hint would result in 80+ separate commits—tihs is really just too much noise. Related: https://github.com/xmonad/xmonad-contrib/issues/537
111 lines
4.3 KiB
Haskell
111 lines
4.3 KiB
Haskell
-----------------------------------------------------------------------------
|
|
-- |
|
|
-- 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
|
|
,WorkscreenId
|
|
) 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 = concatMap expandId
|
|
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 = zipWith Workscreen [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
|