Technically, contrib still does not build with stack, as it forces
xmonad-0.17.0, while only HEAD builds with newer mtl versions. However,
until our dependencies are at least revbumped, this may be the best we
can do.
Related: https://github.com/xmonad/xmonad-contrib/issues/805
These modules were duplicating a substantial amount of low-level code.
`X.A.CycleWorkspaceByScreen` had already separated most of the
implementation details from the logic with `repeatableAction`; all that
was left was to generalise it a little further, put it in a suitable
place and express the other modules through it.
Essentially, whenever the tutorial actually has decent material on the
subject matter. The replacement is roughly done as follows:
- logHook → tutorial
- keybindings → tutorial, as this is thoroughly covered
- manageHook → tutorial + X.D.Extending, as the manageHook stuff the
tutorial talks about is a little bit of an afterthought.
- X.D.Extending (on its own) → tutorial + X.D.Extending
- layoutHook → tutorial + X.D.Extending, as the tutorial, while
talking about layouts, doesn't necessarily have a huge focus there.
- mouse bindings → leave this alone, as the tutorial does not at all
talk about them.
Entirely unnecessary for the current version of `cycleWindowSets`, but
if anyone ever wants to use `greedyView`, this shows that it's not at
all complicated to adapt `unView` to that.
To make this more "obviously correct", make it resemble the `view`
implementation, just do the exact reverse. Now the only complex bit is
the "undelete" operation.
This also fixes another issue: state was only preserved in the focused
workspace, but it may have changed in another visible workspace as well.
The property test is updated to test this.
The way that workspace cycling is implemented right now—by generating
new windowsets where the things we want happen to be true and then
replacing the old windowsets—is not safe, as workspaces and layouts may
carry state with them. That state will get lost in translation when
windowsets are simply replaced.
As an example, a conflict occurs when using `X.L.ShowWName.showWName` in
one's layoutHook. When cycling through workspaces via, e.g.,
`cycleRecentWS` the flashed workspace tag will not disappear, as the
necessary state to control this isn't present in the new windowset.
Instead, what we want to do is to keep the "current" windowset alive and
actually switch to the requested workspaces. This mostly works without
much trouble, the only hard part is maintaining the invariant that
previewed workspaces don't count towards the history of recently-viewed
workspaces. This is done by remembering the tag-order of the original
windowset and then restoring that at the end.
This is a breaking change, insofar as it changes the type signatures of
the exported functions `recentWS`, `cycleWindowSets`, and
`toggleWindowSets` to return a list of `WorkspaceId`s instead of a list
of `WindowSet`s.
Fixes: https://github.com/xmonad/xmonad-contrib/issues/504