The window-layouter component complements the window manager (wm) with the
policy of how windows are positioned on screen and how windows behave when the
user interacts with window elements like the maximize button or the window
title. Whereas the decorator defines how windows look, the layouter defines how
they behave.


Layout rules
------------

The window layouter positions windows according to rules defined by the
component's configuration. The rules consist of two parts, the definition
of the screen's layout and the assignment of client windows to the defined
parts of the screen's layout.

! <config>
!   <rules>
!     <screen>
!       ...definition of screen layout...
!     </screen>
!     <assign label_prefix="..." target="..."/>
!     ,,,
!   </rules>
!   ...
! </config>

The '<screen>' node can host any number of '<column>' nodes, which partition
the screen horizontally into columns. By default, each column has the same
size. By specifying an optional 'weight' attribute, column sizes can be
weighted relative to one another. The default weight is '1'. Alternatively,
the 'width' of a column can be explicitly specified in pixels.
Each column can host any number of '<row>' nodes, which subdivide the column
vertically. Analogously to columns, rows can be dimensioned via an optional
'weight' attribute or an explicit 'height' in pixels. A '<row>' can, in turn,
contain '<column>' nodes, thereby further subdividing the screen.
Each '<column>' or '<row>' can be used as window-placement target when
equipped with a 'name' attribute. Each name must occur only once within
the '<screen>'. In the following, a named column or row is referred to as
_target_. Each target can host an optional 'layer' attribute. If not
specified, the layer 9999 is assumed. A target with a lower layer overlaps
targets with higher layers.

The assignment of windows to targets is defined via '<assign>' nodes. Each
'<assign>' node must be equipped with a 'label', 'label_prefix', or
'label_suffix' attribute, which is used to match window labels. For a given
window, the first matching '<assign>' node takes effect.

Each '<assign>' node must have a 'target' attribute that refers to the name
of a column or row. By default, the window is sized to fit the target area.
However, it is possible to position the window relative to the target area by
specifying the 'xpos', 'ypos', 'width', and 'height' attributes together with
the 'maximized="no"' attribute.

If multiple windows are assigned to the same target area, the order of their
'<assign>' rules defines their stacking order. The window with earliest
'<assign>' rule is displayed in front.


Dynamic layouts
---------------

The window layouter is able to respond to rule changes at runtime.

By specifying the '<config>' attribute 'rules="rom"', the window layouter
tries to obtain the layout rules from a distinct ROM module. Should the ROM
module not contain valid rules, the '<rules>' sub node of the '<config>' comes
into effect.

Any window-layout change such as the movement of a floating window is
realized as a change of the window-layout rules. To support interactive
adjustments of the window layout, the layouter responds to certain user
interactions by generating new rules by itself in the form of a "rules"
report. The generation of such rules can be enabled via the '<report>' sub
node of the configuration:

! <config>
!   <report rules="yes"/>
!   ...
! </config>

By feeding back the rules generated by the window layouter into the window
layouter itself via a 'report_rom' service, the window layout becomes
adjustable interactively. As the rules entail the complete state of the
present window layout, it is possible to save/restore the layout state.


Dynamic rule-generation mechanism
---------------------------------

Whenever a new window appears that solely matches a wildcard '<assign>' rule
(one that uses a 'label_prefix' or 'label_suffix'), the layouter generates a
new '<assign>' rule with the window's label as 'label' attribute. The
explicitly labeled '<assign>' rules appear before any wildcard '<assign>'
rules.

If the user brings a window to front, the window layouter will change the order
of the explicit '<assign>' rules such that the window's '<assign>' rule comes
first. When moving or resizing a window, the 'xpos', 'ypos', 'width', and
'height' attribute of the window's assign rule are updated. When maximizing
or unmaximizing a window, the 'maximized' attribute of its '<assign>' rule is
toggled.


Multi-monitor support
---------------------

The layouter rules can host any number of display declarations as follows.

! <display name="primary"/>

Optional attributes 'xpos', 'ypos', 'width', and 'height' can be specified to
assign a specific rectangle of the panorama to the display. Otherwise, the
window layouter applies the following policy. The captured rectangles present
in the panorama are assigned to displays in left to right order. This gives the
opportunity to assign the notion of a "primary" or "secondary" display to
different parts of the panorama by the mere order of '<display>' nodes. If
more displays are declared than present, all unassigned displays will refer to
the left-most captured rectangle of the panorama.

To get more precise control over the assignment of captured areas to displays,
a display node can host any number of '<capture>' sub nodes that are matched
against the captured areas present within the panorama. The panorama areas are
named after the labels of capture clients (i.e., display drivers) present at
the nitpicker GUI server. The matching can be expressed via the attributes
'label', 'label_prefix', and 'label_suffix'. The first match applies.
E.g., the following configuration may be useful for a laptop that is sometimes
connected to an HDMI display at work or a Display-Port display at home.

! <display name="primary">
!   <capture label_suffix="HDMI-1"/>
!   <capture label_suffix="DP-2"/>
!   <capture label_suffix="eDP-1"/>
! </display>
! <display name="secondary">
!   <capture label_suffix="eDP-1"/>
! </display>

When neither the HDMI-1 display nor the DP-2 display is present, the laptop's
internal eDP display is used as both primary and secondary display. Once an
external display is connected, the external display acts as primary display
while the laptop's internal display takes the role of the secondary display.

Once declared, the display names can be specified as 'display' attribute to
'<screen>' nodes, thereby assigning virtual desktops to displays. Screens
referring to the same portion of the panorama are organized as a stack
where only the top-most screen is visible at a time. As each display has
its own distinct stack of screens, one screen cannot be visible at multiple
displays. To mirror the same content on multiple displays, it is best to
leverage the '<merge>' feature of the display driver. Should a '<screen>' lack
a valid display attribute, it spans the entire panorama.


Keyboard shortcuts
------------------

The window layouter is able to respond to key sequences. However, normally,
the layouter is not a regular nitpicker client but receives only those
input events that refer to the window decorations. It never owns the keyboard
focus. In order to propagate global key sequences to the layouter, nitpicker
must be explicitly configured to direct key sequences initiated with certain
keys to the decorator. For example, the following nitpicker configuration
routes key sequences starting with the left windows key to the decorator. The
window manager, in turn, forwards those events to the layouter.

! <start name="nitpicker">
!   ...
!   <config>
!     ...
!     <global-key name="KEY_LEFTMETA" label="wm -> decorator" />
!     ...
!   </config>
!   ...
! </start>

The response of the window layouter to key sequences can be expressed in the
layouter configuration as follows:

! <config>
!   ...
!   <press key="KEY_LEFTMETA">
!     <press key="KEY_TAB"              action="next_window">
!       <release key="KEY_TAB">
!         <release key="KEY_LEFTMETA"   action="raise_window"/>
!       </release>
!     </press>
!     <press key="KEY_LEFTSHIFT">
!       <press key="KEY_TAB"            action="prev_window">
!         <release key="KEY_TAB">
!           <release key="KEY_LEFTMETA" action="raise_window"/>
!         </release>
!       </press>
!     </press>
!     <press key="KEY_ENTER"            action="toggle_fullscreen"/>
!   </press>
! </config>

Each '<press>' node defines the policy when the specified 'key' is pressed.
It can be equipped with an 'action' attribute that triggers a window action.
The supported window actions are:

:next_window:       Focus the next window in the focus history.
:prev_window:       Focus the previous window in the focus history.
:raise_window:      Bring the focused window to the front.
:toggle_fullscreen: Maximize/unmaximize the focused window.

By nesting '<press>' nodes, actions can be tied to key sequences. In the
example above, the 'next_window' action is executed only if TAB is pressed
while the left windows-key is kept pressed. Furthermore, key sequences can
contain specific release events. In the example above, the release of the left
windows key brings the focused window to front, but only if TAB was pressed
before.


