[Xmonad] Add FloatLayout, a Layout Transformer adding a floating layer

David Roundy droundy at darcs.net
Thu Oct 11 10:55:43 EDT 2007

On Thu, Oct 11, 2007 at 01:27:49AM +0200, Karsten Schoelzel wrote:
> Hi,
> this is to try out moving the floating to the level of layouts.
> This would make it possible to have different layout algorithms for the
> floating layer, including different decorations for windows there.


> At the moment it's possible to move windows with the mouse and keys.
> Additionally there is a hidden layer so windows can be hidden
> temporarily (this being the initial reason to investigate it: hide all
> floating windows for a moment)
> TODO: - it's difficult to automagically move a window to the floating
>         layer with a manageHook 

Couldn't this be done with a simple sendMessage?

>       - moving windows between workspaces will *not* preserve the
>         floating status

This issue shouldn't be too much of a problem, in my opinion.  It'll be
solved when floating is handled properly in the core.  It could also be
hacked by broadcasting the change to float status, but at the cost of
having duplicate information about floating windows.

> What do you think?

This is something I've wished I had time to do, and I'm glad you've gotten
around to it!  :)

> +type FloatInfo a = M.Map FloatState [(a, Rectangle)]

I think this would be much clearer and more bug-proof if you used

data FloatInfo a = FloatInfo { hiddenWindows :: [(a, Rectangle)]
                             , floatingWindows :: [(a, Rectangle)]
                             , otherWindows :: [(a, Rectangle)] }

This way you'll be using inherently total functions, and it should be
faster code than a Data.Map, also.

> +data RatRect = RatRect { rx :: Rational, ry :: Rational, rw :: Rational, rh :: Rational }

There's already a RationalRect defined elsewhere (but maybe with a
different name), which I'd reuse, if you feel a need for such a beast.

> +data FloatLayout l a = FloatLayout (FloatInfo a) (Layout a)
> +                             deriving ( Show, Read )

This would be better as

data FloatLayout l a = FloatLayout (FloatInfo a) (l a)
                                deriving ( Show, Read )

in the sense that it'd be easier to read and show.  We should only use the
Layout type when there's absolutely no way around it, which basically means
when we've got to store a list of layouts.

> +instance LayoutClass (FloatLayout (FloatInfo Window)) Window where

The instance constraint would then be:

instance LayoutClass l Window => LayoutClass (FloatLayout l) Window where

and the rest of your code should be unmodified by the elimination of the
Layout data type (it'll of course be modified if you take my FloatInfo
advice above).

At another level, I think that this layout would benefit by being broken
into three layouts: one layout to divide a window between two layouts, a
second layout to implement a float-only layout, and finally, a "hidden"
layout.  This would give precisely the same functionality you've
implemented, but would involve three much smaller layouts.  Probably you'd
want the float layout to include a simple function that behaves exactly as
the one you defined (floatLayout), but by creating these three layouts
you'd make it easy to reuse most of your code for other purposes (such as a
decorated float layout, or one that preserves the size of float
windows--here I'm assuming you've simply duplicated the behavior of the
existing float layer).

Just to be slightly more clear, I'm imagining the stacking layout as
something like:

data ChangeWindowLayer a = MoveToLayer String a
                           deriving ( Show, Eq, Typeable )

data StackTwoLayouts ltop lbot a = StackTwoLayouts { windowsOnTop :: [a]
                                                   , windowsOnBot :: [a]
                                                   , layoutTop :: ltop a
                                                   , layoutBot :: lbot a
                                                   , topName :: String }
                                   deriving ( Show, Read )

So that this layout would have the reponsibility of dividing windows
between the two layouts.  The top one could be float while the bottom is
tiled, or one of them could be hidden.

Note also, that your monolithic approach isn't a bad idea, as in many ways
any of these approaches are going to be prototypes.  But the more modular
approach I would guess would more easily morph into what we see replacing
the current float layer.  Eventually we'll want to have separate Stacks for
the float and tiled layers, which ought to be done in the core, not in a
David Roundy
Department of Physics
Oregon State University

More information about the Xmonad mailing list