Saturday, March 30, 2019

skipping over already-visible workspaces in xmonad

I recently went back to a two-monitor setup on my work system (an Intel NUC I bought back in November). For the most part this has been a big improvement, and xmonad handles multi-screen layouts just as well as I remembered. Each screen displays a workspace, and they can be switched independently.

I have had one nagging complaint: I have a bunch of pre-configured workspaces and tend to cycle through with them with the arrow keys. When I switched to a workspace that was already displayed on the other screen, it’d swap onto the current screen. This seems like a pretty minor thing, but in practice it tends to add confusion - I might, for example, have a page of notes up on one display and be trying to quickly navigate on the other display for items from mail, code, IRC, etc., to summarize in the notes. If that workspace jumps around, it’s easier to lose track of what I’m doing.

I wondered if it was possible to “lock” a workspace to a specific display. I still don’t know the answer to that question, but skimming the docs for XMonad.Actions.CycleWS I found an alternative that mostly solves my problem.

Originally I had the following keybindings in my xmonad.hs:

  ("M-<Right>", nextWS)
, ("M-<Left>", prevWS)

These have been replaced with:

  ("M-<Left>", moveTo Prev HiddenWS)
, ("M-<Right>", moveTo Next HiddenWS)

In practice this means that the workspace cycling for mod-Left and mod-Right will skip over any already-visible workspaces, leaving them in place on the other display. There are other possibilities, including the next/previous empty workspace, but this is pretty close to what I was looking for.