[xmonad] XMonad.Actions.CycleRecentWS rewrite (new modules inside)

Jochen Keil jochen.keil at gmail.com
Mon Jan 9 11:43:19 CET 2012

Hash: SHA1

Hello Nathaniel,

On 09.01.2012 02:15, Nathaniel Filardo wrote:
> Would it be possible to rework this to avoid looping around the X 
> event stream?
Not with this form of generalization.

> IMHO it would be nicer if it updated its internal state and then
> let the main event loop dispatch events its way.
If you do it that way, you cannot cycle over your workspaces. It would
be effectively a key for toggling your last viewed workspace, due to the
way XMonad updates its internal Workspace list.
E.g. workspaces: current: 0, others: [1,2,3,4]
view $ head others: current 1, others: [0,2,3,4]
view $ head others: current 0, others: [1,2,3,4], etc.
If you want to cycle you have to preserve the state of the initial list.

> Modules creating their own event loops just doesn't seem right (and
>  in the case of XMonad.Prompt causes usability problems for me
> where I will start filling out a prompt and then want to change
> focus before finishing).
First of, XMonad takes Events from the X event queue in a single
threaded event based loop. Reading from the event queue and processing
the events our specific function is interested in should normally cause
no harm since we are still within the X state monad without concurrency.

Furthermore, events we are not interested in lead to an immediate break
of the function and are put back into the event queue (putBackEvent) so
nothing is lost.

In general, there are currently two ways I see how to accomplish this
recent workspace cycling problem. I've tried them both and opted for
this method, I'll give you the reasons later.

The first method would be to use Extensible State. This allows to store
a Show- and Tybeable -able Type in the X Monad, which means that
anything that contains layouts (LayoutClass), like Screens, Workspaces
or WindowSets is out.
You can do this by saving a list of tags (Strings) and use this list for
* no need to read events from x event queue
* limited to types which are (at least) Show and Typeable, Read would be
* without Read there is no PersistentState, so your Workspace cycling
order is lost on restarts
* not a general solution, rather a very specific one

The other solution is what I did. Keeping a state myself in the function
loop, thus unlimited on the type.
The state is retrieved from the X state monad *once* and then passed
through. So every time we apply a function for altering the state it
is done with the initial state.
Since this is a functional programming language there is no such thing
as a global state, only what you pass either from one function to the
other or in the case of XMonad in the outer event loop (which is just
function itself. But you cannot declare your own state in a module and
have it globally available.
* general solution, unlimited on types, does no harm to the x event
loop (afais)
cons: own event processing

Now this is a rather long read and I apologize for that. However, I
hope that I clearly pointed out, that there are only two possibilities
to implement this and why I've chosen the current implementation.

Best Wishes,


> Thanks. --nwf;
> On Sun, Jan 8, 2012 at 6:07 AM, Jochen Keil <jochen.keil at gmail.com>
>  wrote: Hi,
> my last version of CycleRecentWS.hs had a small logical bug. I
> added the current ws to the end of the list but it should go to the
> head. This makes also the somewhat strange +/-2 on secondary
> modifier keypress superfluous. I also thought about getting rid of
> passive grab but the problem is that we stay in the recursive loop
> if we don't exit on the keyrelease event by the grabbed modifier.
> This shouldn't be a problem normally, because when you press
> another modifier + key combination we'll terminate the loop. It can
> however lead to unexpected behavior when releasing the modifier and
> then pressing it again so that the loop stays active thus cycling
> over the (old and possibly not desired) state again.
> Best Regards,
> Jochen
> On 07.01.2012 23:32, Jochen Keil wrote:
>>>> Dear list,
>>>> after struggling for a while the XMonad.Actions.CycleRecentWS
>>>>  contrib module, mainly because it actively grabs the whole 
>>>> keyboard (and thus breaks various functionality, e.g. 
>>>> switching the layout on the fly), I took the time to rewrite 
>>>> this module. It now does not actively grab the whole
>>>> keyboard anymore but relies only on one passive grab. I
>>>> imagine this could be done even more generally, but I am
>>>> pretty satisfied with how it works now. However, since theres
>>>> always room for improvement new ideas are always welcome. :)
>>>> I've included another module which helps to setup up a
>>>> passive grab on a certain key. Configuration is a bit
>>>> (tr)icky, but I hope not too troublesome.
>>>> Best regards,
>>>> Jochen
>>>> _______________________________________________ xmonad
>>>> mailing list xmonad at haskell.org 
>>>> http://www.haskell.org/mailman/listinfo/xmonad
>> _______________________________________________ xmonad mailing
>> list xmonad at haskell.org
>> http://www.haskell.org/mailman/listinfo/xmonad
Version: GnuPG v1.4.11 (GNU/Linux)


More information about the xmonad mailing list