[xmonad] The future of PerWorkspace

Brent Yorgey byorgey at gmail.com
Wed Jan 30 19:29:58 EST 2008

Hi all!

This may end up being a long e-mail.  Executive summary:

  1. PerWorkspace is an inelegant hack with several icky problems:
     - 'description' is not in the X monad so can't figure out the
       current workspace
     - the currently focused workspace might not even be the correct
       one anyway, in the case of xinerama or message handling.

  2. Andrea's LayoutCombinator class and core patch to move the result
     of the description function into the X monad will help with some
     but not all of the problems.  In particular it still won't work
     with xinerama.

  3. It would be nice to have the PerWorkspace functionality supported
     in the core, and I have a nice, elegant way to do it.  This would
     fix all the problems.  ...The only catch is that it would also
     require going back to requiring existential Layout wrappers
     everywhere. =(

  4. Well, crap.

I had recently been thinking about PerWorkspace and ways to improve
it, but hadn't yet gotten around to really doing anything about it.
Andrea's new emptyLayout function, and then in particular his
reimplementation of PerWorkspace using the new LayoutCombinator
framework obviously motivated me to get around to it!  So I'd like to
explain some of the problems with PerWorkspace and possible future

First, the basics: although the xmonad core tracks layouts separately
for each workspace, it is not possible to *specify* a different
starting layout on a per-workspace basis.  Only a single layout may be
specified in the XConfig record, and this layout is duplicated across
all workspaces on xmonad startup.  PerWorkspace attempts to get around this
limitation by providing a layout which dynamically decides on which of two
to use, based on the current workspace tag.  All workspaces still have the
same layout, but that one layout acts differently depending on the current
You can see from the beginning that this is something of a hack.

This approach has two major limitations, each of which leads to one or
more problems.

  * To find out the current workspace obviously requires access to the
    X monad.  For doLayout and handleMessage this is obviously not a
    problem.  The description method, however, is a pure function.  I
    solved this in a very hackish way before by having a call to
    doLayout return a modified PerWorkspace layout structure with a
    cached value remembering which of the two layouts should be used.
    description could then use this cached value to decide on the
    description to return.  Andrea's current reimplementation of
    PerWorkspace does not do this caching, which is why the
    description method is currently broken.  I can reimplement this,
    and the new emptyLayout method will help, but it still feels very

  * A more insidious problem is that it is not possible, in general,
    for doLayout or doMessage to figure out which workspace they
    belong to, and hence which layout to use.  PerWorkspace currently
    works by retrieving the tag of the currently focused workspace
    from the xmonad state, but there are several situations in which
    doLayout or handleMessage are called on a workspace which is
    not the currently focused workspace:

    - If xinerama is in use, doLayout will be called for all the
      visible workspaces as well as the focused workspace.
    - Messages can be broadcast to all workspaces, in which case
      handleMessage will be called for all workspaces, including
      non-focused or even hidden workspaces.

    In either of these situations, PerWorkspace may choose the wrong
    layout.  The message problem can be solved by simply passing along
    any messages to all layouts, without trying to decide on the
    correct one: it cannot hurt to pass messages to unintended
    recipients, especially if the unintended recipient layouts will
    never be used anyway!  The xinerama problem seems insoluble,
    however.  PerWorkspace simply cannot work on xinerama because it
    cannot get the information it needs to decide which layout to

So, what is the way forward?  It looks like I can get PerWorkspace
back to its original level of workingness --- thanks to the
LayoutCombinator class it will be a lot shorter, but it still won't
work with xinerama, and it will still be an ugly, fragile hack.

I had been intending to suggest adding support for per-workspace
layouts to the xmonad core.  After all, xmonad does track and
save/restore layouts on a per-workspace basis, so why shouldn't it
allow configuring them on a per-workspace basis too?  I intended to keep
the current layoutHook (specifying the default layout to be used on
all workspaces not otherwise specified) as well as adding a new field
to the config which would store a list of (workspace tag, layout)
pairs.  The core modifications necessary to support this are not too
hard and end up being fairly elegant -- in fact, I have made these
modifications in a local branch.

The catch? Having a bunch of layouts in a list like this requires
going back to wrapping everything with Layout existentials in user
configs! =( This doesn't sound like much fun either.

So, I am at something of a loss.  Any thoughts or suggestions for moving
are appreciated!

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/xmonad/attachments/20080130/26613d3a/attachment-0001.htm

More information about the xmonad mailing list