Visual xmonad Layouts Guide

Seven basic layouts in xmonad and how to use them

Posted by Brandon Wong on 3rd Aug 2019

Are you getting into xmonad? Here are seven basic layouts that are easy to configure, and might be just what you need for your work setup!

1. Tall

xmonad tall layout

The Tall layout has the master pane on the left, taking half of the screen. All other windows share the right half of the screen, and are stacked vertically, top to bottom.

Configuration

The Tall layout has three optional parameters. The first defines the initial number of windows in the master pane (which by default is 1); this can be modified while in use via the mod-,/. keys. Because Tall is one of the built-in layouts, you don't need to import anything extra in your xmonad.hs configuration file.

myLayout = Tall 1 (3/100) (1/2)

Uses

This is the go-to layout, and it's the first one that you get when you run xmonad out of the box. It's common to have one window in focus while a couple secondary windows are in view, so the Tall layout works great. It's very useful in many situations, but the windows on the right start to feel a little crowded beyond five windows.

2. Spiral

xmonad spiral layout

The Spiral layout starts with a window taking a majority of the screen on the left, then another window taking occupying the top of the remainder, then another on the right of the remainder, then the bottom of the remainder, then the left of the remainder, and so on.

Configuration

A popular proportion for the amount of space a window takes vs. its remainder is the Golden Ratio (approximately 0.856), which would make the windows simulate a Fibonacci spiral. This is not necessary, however, and you can put any fraction.

import XMonad.Layout.Spiral

myLayout = spiral (6/7)

Uses

Honestly, I think the uses for this layout are narrow. There have been times when it was useful to have a layout in which each window was successively smaller and placed in a spiral pattern, but the most common use for me was to show off to my friends what xmonad was capable of doing.

3. Three Columns

xmonad three-column layout

As the name suggests, the ThreeCol layout splits the screen into three columns: one primary, and two secondary. In the original form, the primary column is on the left, and takes half of the screen. Then the next two windows horizontally share the other half of the screen. If there is a fourth window, then the third window is pushed into the middle, and the middle column vertically shares two windows. A fifth window will share the right column with the fourth window. All subsequent windows will be placed into the two right columns in the same manner.

Configuration

The configuration for ThreeCol is the same as for Tall, with the first parameter being the starting number of windows in the primary pane, the second parameter being the amount of resize, and the third being the initial proportion of the main column.

import XMonad.Layout.ThreeColumns

myLayout = ThreeCol 1 (3/100) (1/2)

Uses

This layout is particularly useful when programming, especially if you only have one screen. The primary pane contains the code. The other two contain a browser with documentation (or google searches and Stack Overflow!), and a window with compilation and test suite output - both of which are usually better when laid out vertically.

There is also a variant (many layouts have variants that offer a twist on the original) called ThreeColMid, which is configured in the same way as ThreeCol, but places the primary pane in the center, with the other two columns on either side. This is especially great for wide screens, since it places the important things directly in your line of sight, and the secondary things in the periphery.

4. Grid

xmonad grid layout

The Grid layout arranges windows evenly horizontally and vertically, as much as possible. If there are four windows, they are arranged like a cartesian graph. If there are nine windows, they are arranged like a tic-tac-toe board.

Configuration

There are no parameters for this layout, although it does have a variant which allows you to adjust the ratio of columns to rows.

import XMonad.Layout.Grid

myLayout = Grid

Uses

This is the best layout for displaying a large number of windows simultaneously, since each window is about the same size as each other.

5. Multi-Cols

xmonad multiple columns layout

The MultiColumns layout arranges windows side-by-side, each filling the entire vertical space and sharing the horizontal space.

Configuration

Using the mod-,/. keys, multiple windows can be combined into individual columns, sharing vertical space. The first and second parameters of multiCol defines the maximum number of windows that can share a column, in each column. The other two parameters describe the relative widths of each column, the default being equally-sized columns.

import XMonad.Layout.MultiColumns

myLayout = multiCol [1] 1 0.01 (-0.5)

Uses

This layout is optimal for displaying multiple terminals with streaming output. When used in this way, it also looks very geeky and cool.

6. Full

xmonad full layout

This layout is the simplest - it fills the entire screen with one window. All other windows are hiding behind it, and are brought to the front by cycling through them as usual (with alt-tab, or mod-j/k).

Configuration

There are no parameters for this layout.

myLayout = Full

Uses

The full layout is ideal for watching videos, or if you want to focus exclusively on one thing at a time. It's also good for when you are using an app or program that already subdivides the screen, and you don't want to mess up its internal layout - such as a split-screen session of vim, or tmux.

Modifiers

xmonad also offers a few modifiers, which are functions that accept a layout, and adjust them in some way. The two that I'll mention here are Mirror and spacing.

Mirror

The Mirror modifier takes a layout and rotates it by 90 degrees. The best example of this is the final layout for this guide, Mirror Tall.

7. Mirror Tall

xmonad mirrored tall layout

The Mirror Tall layout is the Tall layout, but rotated on its side. The master pane on top, occupying the entire upper half of the screen. All the other windows share the bottom half, left to right.

myLayout = Mirror (Tall 1 (3/100) (3/5))

Spacing

The other modifier that's often used is spacing. Depending on the parameter you put, this adds a gap of a certain width between each of your windows (and the edge of the screen), revealing the background behind the windows. If you have the screen real estate to spare, it visually gives your windows room to breathe, and can help distinguish similarly-looking windows. Also, it looks really really cool.

Putting Them to Use

The easiest way to use different layouts in xmonad is to select a list of your favourite ones, and write it into your xmonad.hs config file. Then while using it, hit mod-space to cycle through the list (and mod-shift-space to reset to the first layout).

For clarity, I recommend defining all your layouts in a variable outside the main function, then referencing it inside your call to xmonad. Use the triple-pipe operator, |||, to list your desired layouts. Use haskell's function application operator, the dollar sign $, to apply a modifier to the whole list.

Here's an example:

-- xmonad.hs

import XMonad.Layout.Spiral
import Data.Ratio -- this makes the '%' operator available (optional)
import XMonad.Layout.Spiral
import XMonad.Layout.Grid

myLayouts = spacing 10 $ Tall 1 (3/100) (1/2) ||| spiral (125 % 146) ||| Grid ||| Mirror (Tall 1 (3/100) (3/5)) ||| Full

main =
    xmonad {

           ... -- more config goes here

           , layoutHook = myLayouts

           ... -- more config goes here

    }

Here's the same example with some nicer formatting, using Haskell's "where" binding:

...

myLayouts = spacing 10 $
            layoutTall ||| layoutSpiral ||| layoutGrid ||| layoutMirror ||| layoutFull
    where
      layoutTall = Tall 1 (3/100) (1/2)
      layoutSpiral = spiral (125 % 146)
      layoutGrid = Grid
      layoutMirror = Mirror (Tall 1 (3/100) (3/5))
      layoutFull = Full

main =
    xmonad {
           ...
           , layoutHook = myLayouts
           ...
    }

Run xmonad --replace to restart xmonad with the new configuration, and give it a try!

Resources