Layout - bakkeby/dusk GitHub Wiki
A layout controls how clients are arranged (tiled) respective to other clients on the same workspace.
Most layouts have a larger "master" area where the main window(s) of interest reside and one or more "stack" areas where the remaining windows are placed.
The underlying mechanism that handles the arrangement of client windows is called flextile-deluxe and it works by splitting the workspace into separate areas (i.e. master, primary stack, secondary stack) where each area is arranged independently.
This is in contrast to the dynamic window manager (dwm) where most layouts are handled by a single function that has a fixed split and arrangement.
A split in the context of the layout means how the workspace area is divided into a master and stack area as an example. In the case of a centered master layout there would be a secondary stack area as well.
The possible splits are:
Split | Description |
---|---|
NO_SPLIT | A no master and stack layout |
SPLIT_VERTICAL | Master stack vertical split |
SPLIT_HORIZONTAL | Master stack horizontal split |
SPLIT_CENTERED_VERTICAL | Centered master vertical split |
SPLIT_CENTERED_HORIZONTAL | Centered master horizontal split |
SPLIT_VERTICAL_DUAL_STACK | Master stack vertical split with dual stack |
SPLIT_HORIZONTAL_DUAL_STACK | Master stack vertical split with dual stack |
FLOATING_MASTER | Fake floating master |
By default the layout splits will reduce if there are not enough clients to cover all areas. What this means is that if a vertical split is used, as in the default tile layout for example, and there is only one client then that client, or more more specifically the master area, will take up the entire workspace.
Similarly if a centered master layout is used that has three areas (master, primary stack and secondary stack) and there are only two clients then the layout will reduce to a vertical split with only a master and stack area.
If the number of clients in the master area, controlled by the nmaster
value, is 0 then the layout will reduce to a "no split" layout only showing the (primary) stack
area. See the incnmaster function for more information on nmaster
.
A negative split, e.g. -SPLIT_VERTICAL
will result in a reversed split, e.g. the stack area
being on the left and the master area being on the right. Refer to the mirrorlayout
function for more details.
Then there are fixed versions of the above splits which do not reduce regardless of the number of clients.
Fixed Split | Description |
---|---|
SPLIT_VERTICAL_FIXED | Fixed master stack vertical split |
SPLIT_HORIZONTAL_FIXED | Fixed master stack horizontal split |
SPLIT_CENTERED_VERTICAL_FIXED | Fixed centered master vertical split |
SPLIT_CENTERED_HORIZONTAL_FIXED | Fixed centered master horizontal split |
SPLIT_VERTICAL_DUAL_STACK_FIXED | Fixed master stack vertical split with dual stack |
SPLIT_HORIZONTAL_DUAL_STACK_FIXED | Fixed master stack vertical split with dual stack |
FLOATING_MASTER_FIXED | Fixed fake floating master |
These are primarily intended for superwide monitors where it may be a disadvantage to have a master window take up the entirety of the screen when it first opens.
Each area of a layout is arranged independently from other areas.
In a traditional tile layout for example clients are tiled top to bottom in the master area as well as in the stack area. Should you want it there is nothing stopping you from having a gappless grid arrangement in the master area and a fibonacci arrangement in the stack area.
The possible arrangements are:
Arrangement | Description |
---|---|
TOP_TO_BOTTOM | Clients arrange vertically (like rows) |
LEFT_TO_RIGHT | Clients arrange horizontally (like columns) |
MONOCLE | Clients arrange in deck / monocle mode |
GAPPLESSGRID | Clients arrange in a gappless grid (original formula) |
GAPPLESSGRID_CFACTS | Clients arrange in a gappless grid that takes cfacts into account |
GAPPLESSGRID_ALT1 | Clients arrange in a gappless grid (alt. 1, fills rows first, cfacts for rows) |
GAPPLESSGRID_ALT2 | Clients arrange in a gappless grid (alt. 2, fills columns first, cfacts for columns) |
GRIDMODE | Clients arrange in a grid |
HORIZGRID | Clients arrange in a horizontal grid |
DWINDLE | Clients arrange in fibonacci dwindle mode |
DWINDLE_CFACTS | Clients arrange in fibonacci dwindle mode and takes cfacts into account |
SPIRAL | Clients arrange in fibonacci spiral mode |
SPIRAL_CFACTS | Clients arrange in fibonacci spiral mode and takes cfacts into account |
TATAMI | Clients arrange as tatami mats |
TATAMI_CFACTS | Clients arrange as tatami mats that takes cfacts into account |
Some of the arrangements take cfacts into account which means that the size of a tiled client is relative to the size of other tiled clients within the same area. In practice this allows for a tiled client to be resized within the respective area. See the setcfact function for more information on that.
Predefined layouts are configured through the layouts
array in config.h.
static const Layout layouts[] = {
/* symbol arrange function, { nmaster, nstack, layout, master axis, stack axis, secondary stack axis, symbol func }, name */
{ "[]=", flextile, { -1, -1, SPLIT_VERTICAL, TOP_TO_BOTTOM, TOP_TO_BOTTOM, 0, NULL }, "tile" },
{ "|||", flextile, { -1, -1, NO_SPLIT, LEFT_TO_RIGHT, LEFT_TO_RIGHT, 0, NULL }, "columns" },
{ "===", flextile, { -1, -1, NO_SPLIT, TOP_TO_BOTTOM, TOP_TO_BOTTOM, 0, NULL }, "rows" },
{ "[M]", flextile, { -1, -1, NO_SPLIT, MONOCLE, MONOCLE, 0, NULL }, "monocle" },
{ "||=", flextile, { -1, -1, SPLIT_VERTICAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, 0, NULL }, "col" },
{ ">M>", flextile, { -1, -1, FLOATING_MASTER, LEFT_TO_RIGHT, LEFT_TO_RIGHT, 0, NULL }, "floating master" },
{ "[D]", flextile, { -1, -1, SPLIT_VERTICAL, TOP_TO_BOTTOM, MONOCLE, 0, NULL }, "deck" },
{ "TTT", flextile, { -1, -1, SPLIT_HORIZONTAL, LEFT_TO_RIGHT, LEFT_TO_RIGHT, 0, NULL }, "bstack" },
{ "===", flextile, { -1, -1, SPLIT_HORIZONTAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, 0, NULL }, "bstackhoriz" },
{ "==#", flextile, { -1, -1, SPLIT_HORIZONTAL, TOP_TO_BOTTOM, GAPPLESSGRID_CFACTS, 0, NULL }, "bstackgrid" },
{ "|M|", flextile, { -1, -1, SPLIT_CENTERED_VERTICAL, LEFT_TO_RIGHT, TOP_TO_BOTTOM, TOP_TO_BOTTOM, NULL }, "centeredmaster" },
{ "-M-", flextile, { -1, -1, SPLIT_CENTERED_HORIZONTAL, TOP_TO_BOTTOM, LEFT_TO_RIGHT, LEFT_TO_RIGHT, NULL }, "centeredmaster horiz" },
{ ":::", flextile, { -1, -1, NO_SPLIT, GAPPLESSGRID_CFACTS, GAPPLESSGRID_CFACTS, 0, NULL }, "gappless grid" },
{ "[\\]", flextile, { -1, -1, NO_SPLIT, DWINDLE_CFACTS, DWINDLE_CFACTS, 0, NULL }, "fibonacci dwindle" },
{ "(@)", flextile, { -1, -1, NO_SPLIT, SPIRAL_CFACTS, SPIRAL_CFACTS, 0, NULL }, "fibonacci spiral" },
{ "[T]", flextile, { -1, -1, SPLIT_VERTICAL, LEFT_TO_RIGHT, TATAMI_CFACTS, 0, NULL }, "tatami mats" },
{ "><>", NULL, { -1, -1 }, "floating" }, /* no layout function means floating behavior */
};
Each entry has a layout "symbol", a function (flextile
), and a layout preset which contains
instructions which define the splits, arrangements per area and more.
The symbol
is by default presented in the bar via the LtSymbol bar module
indicating which layout is currently being used.
The function
used is flextile
here, but bespoke arrange functions can also be added if needed.
If the function is NULL
then that means that there is no arrange function and thus windows will be
floating.
The layout preset consists of seven fields.
The nmaster (number of master clients) and the
nstack (number of primary stack clients) options will explicitly set the
corresponding variables when the layout is selected. If the values are -1
then they have no
effect.
In practice it is best if:
- all of these are set to
-1
or - all of these have values
The reason for this is that cycling through preset layouts can give results that can be confusing
for the end user if only one of the layouts override the nmaster
value by setting it to 0 for
example.
Next there are four axes to consider:
- the layout split
- the arrangement for the master area
- the arrangement for the primary stack area
- the arrangement for the secondary stack area
These are referred to as axes because each of these can be rotated via the rotatelayoutaxis function to dynamically change the layout.
The layout
(split) takes a value from the splits section above while the other three
takes a value from the arrangements section.
The number of clients placed in the master area depends on the current nmaster
value.
Superfluous clients that do not fit into the master area overflow to the primary stack area and in turn to the secondary stack area if a dual stack split is used.
Clients are divided evenly between the primary and secondary stack areas if nstack
is 0, otherwise
the value indicates the number of clients in the primary stack area. See the incnstack
function for more information on that.
Last but not least there is an optional symbol function that you can read more about here.
Here is a list of functions relating to the layout.
Function | Description |
---|---|
cyclelayout | Cycles through the predefined layouts |
mirrorlayout | Creates a reversed view (mirror) of the current layout |
rotatelayoutaxis | Cycles through the various layout axes in a flextile-deluxe layout |
setlayoutaxisex | Sets flextile-deluxe layout split or arrangements externally |
setlayout | Internal function to set the layout via index |
layoutconvert | Switches between horizontal and vertical orientation of the layout |
Here is a list of functionality that are related to the layout.
Functionality | Description |
---|---|
AutoReduceNmaster | Automatically reduce the number of master clients if one is closed |
CenterSizeHintsClients | Center tiled clients subject to size hints within their tiled area |
SmartLayoutConvertion | Automatically adjust layout based on monitor orientation when moving a workspace from one monitor to another |
Also refer to the Gaps topic.
Back to Features.