40c21b6d0f
This commit fixes a regression introduced by "window_layouter: add dynamic screen handling", rendering the sub-division of screens in columns and row unusable. The said commit removed a condition needed for the correct window placement. This patch restores the condition. Issues #3646 |
||
---|---|---|
.. | ||
action.h | ||
assign_list.h | ||
assign.h | ||
decorator_margins.h | ||
focus_history.h | ||
key_sequence_tracker.h | ||
layout_rules.h | ||
main.cc | ||
operations.h | ||
README | ||
target_list.h | ||
target.h | ||
target.mk | ||
types.h | ||
user_state.h | ||
window_list.h | ||
window.h |
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. 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.