Layout Engines
A "layout engine" or ILayoutEngine in Whim is responsible for arranging windows in a workspace. Each workspace has a single active layout engine, and can cycle through different layout engines.
There are two different types of layout engines:
- proxy layout engines
- leaf layout engines
Proxy layout engines wrap other engines, and can be used to modify the behavior of other engines. For example, the Gaps
plugin will add gaps between windows - normally layout engines won't leave gaps between windows.
Leaf layout engines are the lowest level layout engines, and are responsible for actually arranging windows.
Available layout engines
Engine | TL;DR |
---|---|
FocusLayoutEngine |
One window at a time |
SliceLayoutEngine |
Awesome /dwm -style dynamic tiling (primary/stack, multi-column, etc.) |
TreeLayoutEngine |
i3 -style dynamic tiling (arbitrary grids) |
FocusLayoutEngine
FocusLayoutEngine is a layout engine that displays one window at a time:
To focus the window in the specified direction, call FocusWindowInDirection(Direction, IWindow).
To reorder windows, calling SwapWindowInDirection(Direction, IWindow) will swap the current window with the window in the specified direction. This will not change the focused window.
Windows which are not focused are minimized to the taskbar.
SliceLayoutEngine
SliceLayoutEngine is an Awesome
/dwm
-style layout engine, which arranges following a deterministic algorithm filling a grid configured in the config file.
Each SliceLayoutEngine
is divided into a number of IAreas. There are three types of IArea
s:
- ParentArea: An area that can have any
IArea
implementation as a child - SliceArea: An ordered area that can have any
IWindow
as a child. There can be multipleSliceArea
s in aSliceLayoutEngine
, and they are ordered by theOrder
property/parameter. - OverflowArea: An area that can have any infinite number of
IWindow
s as a child. There can be only oneOverflowArea
in aSliceLayoutEngine
- any additionalOverflowArea
s will be ignored. If noOverflowArea
is specified, theSliceLayoutEngine
will replace the lastSliceArea
with anOverflowArea
.
OverflowArea
s are implicitly the last ordered area in the layout engine, in comparison to all SliceArea
s.
Internally, SliceLayoutEngine
stores a list of IWindows. Each IArea
corresponds to a "slice" of the IWindow
list.
Defining SliceLayoutEngine
s
The SliceLayouts
contains methods to create a few common layouts:
- primary/stack (master/stack)
- multi-column layout
- three-column layout, with the middle column being the primary
context.WorkspaceManager.CreateLayoutEngines = () => new CreateLeafLayoutEngine[]
{
(id) => SliceLayouts.CreatePrimaryStackLayout(context, sliceLayoutPlugin, id),
(id) => SliceLayouts.CreateMultiColumnLayout(context, sliceLayoutPlugin, id, 1, 2, 0),
(id) => CustomLayouts.CreateSecondaryPrimaryLayout(context, sliceLayoutPlugin, id)
}
Arbitrary layouts can be created by nesting areas:
context.WorkspaceManager.CreateLayoutEngines = () => new CreateLeafLayoutEngine[]
{
(id) => new SliceLayoutEngine(
context,
sliceLayoutPlugin,
id,
new ParentArea(
isRow: true,
(0.5, new OverflowArea()),
(0.5, new SliceArea(order: 0, maxChildren: 2))
)
) { Name = "Overflow on left" }
};
SliceLayoutEngine
requires the SliceLayoutPlugin to be added to the IPluginManager instance:
SliceLayoutPlugin sliceLayoutPlugin = new(context);
context.PluginManager.AddPlugin(sliceLayoutPlugin);
TreeLayoutEngine
TreeLayoutEngine is a layout that allows users to create arbitrary grid layouts, similar to i3
. Unlike SliceLayoutEngine
, windows can can be added in any location at runtime.
TreeLayoutEngine
requires the TreeLayoutPlugin to be added to the IPluginManager instance:
TreeLayoutPlugin treeLayoutPlugin = new(context);
context.PluginManager.AddPlugin(treeLayoutPlugin);