aboutsummaryrefslogtreecommitdiffstats
path: root/XMonad/Actions/PhysicalScreens.hs
diff options
context:
space:
mode:
Diffstat (limited to 'XMonad/Actions/PhysicalScreens.hs')
-rw-r--r--XMonad/Actions/PhysicalScreens.hs48
1 files changed, 38 insertions, 10 deletions
diff --git a/XMonad/Actions/PhysicalScreens.hs b/XMonad/Actions/PhysicalScreens.hs
index 84b4e32..7ba3ce5 100644
--- a/XMonad/Actions/PhysicalScreens.hs
+++ b/XMonad/Actions/PhysicalScreens.hs
@@ -19,14 +19,14 @@ module XMonad.Actions.PhysicalScreens (
, getScreen
, viewScreen
, sendToScreen
+ , onNextNeighbour
+ , onPrevNeighbour
) where
import XMonad
import qualified XMonad.StackSet as W
-import Graphics.X11.Xinerama
-
-import Data.List (sortBy)
+import Data.List (sortBy,findIndex)
import Data.Function (on)
{- $usage
@@ -43,6 +43,11 @@ Example usage in your @~\/.xmonad\/xmonad.hs@ file:
> import XMonad.Actions.PhysicalSCreens
+> , ((modMask, xK_a), onPrevNeighbour W.view)
+> , ((modMask, xK_o), onNextNeighbour W.view)
+> , ((modMask .|. shiftMask, xK_a), onPrevNeighbour W.shift)
+> , ((modMask .|. shiftMask, xK_o), onNextNeighbour W.shift)
+
> --
> -- mod-{w,e,r}, Switch to physical/Xinerama screens 1, 2, or 3
> -- mod-shift-{w,e,r}, Move client to screen 1, 2, or 3
@@ -60,12 +65,12 @@ newtype PhysicalScreen = P Int deriving (Eq,Ord,Show,Read,Enum,Num,Integral,Real
-- | Translate a physical screen index to a "ScreenId"
getScreen :: PhysicalScreen -> X (Maybe ScreenId)
-getScreen (P i) = withDisplay $ \dpy -> do
- screens <- io $ getScreenInfo dpy
- if i >= length screens
- then return Nothing
- else let ss = sortBy (cmpScreen `on` fst) $ zip screens [0..]
- in return $ Just $ snd $ ss !! i
+getScreen (P i) = do w <- gets windowset
+ let screens = W.current w : W.visible w
+ if i<0 || i >= length screens
+ then return Nothing
+ else let ss = sortBy (cmpScreen `on` (screenRect . W.screenDetail)) screens
+ in return $ Just $ W.screen $ ss !! i
-- | Switch to a given physical screen
viewScreen :: PhysicalScreen -> X ()
@@ -84,4 +89,27 @@ sendToScreen p = do i <- getScreen p
-- | Compare two screens by their top-left corners, ordering
-- | top-to-bottom and then left-to-right.
cmpScreen :: Rectangle -> Rectangle -> Ordering
-cmpScreen (Rectangle x1 y1 _ _) (Rectangle x2 y2 _ _) = compare (y1,x1) (y2,x2)
+cmpScreen (Rectangle x1 y1 _ _) (Rectangle x2 y2 _ _) = compare (y1,x1) (y2,x2)
+
+
+-- | Get ScreenId for neighbours of the current screen based on position offset.
+getNeighbour :: Int -> X ScreenId
+getNeighbour d = do w <- gets windowset
+ let ss = map W.screen $ sortBy (cmpScreen `on` (screenRect . W.screenDetail)) $ W.current w : W.visible w
+ curPos = maybe 0 id $ findIndex (== W.screen (W.current w)) ss
+ pos = (curPos + d) `mod` length ss
+ return $ ss !! pos
+
+neighbourWindows :: Int -> (WorkspaceId -> WindowSet -> WindowSet) -> X ()
+neighbourWindows d f = do s <- getNeighbour d
+ w <- screenWorkspace s
+ whenJust w $ windows . f
+
+-- | Apply operation on a WindowSet with the WorkspaceId of the next screen in the physical order as parameter.
+onNextNeighbour :: (WorkspaceId -> WindowSet -> WindowSet) -> X ()
+onNextNeighbour = neighbourWindows 1
+
+-- | Apply operation on a WindowSet with the WorkspaceId of the previous screen in the physical order as parameter.
+onPrevNeighbour :: (WorkspaceId -> WindowSet -> WindowSet) -> X ()
+onPrevNeighbour = neighbourWindows (-1)
+