Search code examples
haskellxmonadmultiple-monitors

Xmonad: Combine dwm-style workspaces per physical screen with cycling function


my question should be a piece of cake for anyone a bit learned in Haskell:

I would like to use the dwm-like multihead-setup: each physical screen gets it's own set of workspaces. No automatic swapping of windows or focus or whatsoever. This is provided by the extension XMonad.Layout.IndependentScreens (http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-IndependentScreens.html) which works fine.

But I would equally like to use the cycling function provided by XMonad.Actions.CycleWS (http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-CycleWS.html) which works equally fine (by itself).

As it is, when I cycle through the workspaces, it goes: Screen1 WS1 <--> Screen2 WS1 <--> Screen1 WS2 <--> Screen2 WS2 etc.

The cycling function would have to be wrapped in a independent-layout-function i guess. As I said, this is probably extremely simple, but I know little of Haskell and couldn't figure it out.

Both of the extensions are well documented, so this should be a simple one for some of you guys.

Thanks for helping!


Solution

  • I guess the main trick is to build a WSType which informs CycleWS that you're only interested in physical workspaces that appear on the same screen as the current physical workspace. Here's how you would do that.

    isOnScreen :: ScreenId -> WindowSpace -> Bool
    isOnScreen s ws = s == unmarshallS (tag ws)
    
    currentScreen :: X ScreenId
    currentScreen = gets (screen . current . windowset)
    
    spacesOnCurrentScreen :: WSType
    spacesOnCurrentScreen = WSIs (isOnScreen <$> currentScreen)
    

    Then you can use spacesOnCurrentScreen in keybindings something like this:

    , ((modM, xK_whatever ), moveTo  Next spacesOnCurrentScreen)
    , ((modM, xK_whatever2), shiftTo Next spacesOnCurrentScreen)
    

    I haven't tested it, but it typechecks at least. ;-)