1# RLayout
2
3
4## TODO
5
6This should be expanded to walk a little more through the codepaths the
7various examples take, with some detail of the structure contents in the
8various cases.
9
10Also, the meat of the examples should probably migrate into user-level
11documentation at some point, when we have things in shape to do that
12(_i.e._, not having a manpage as the main user doc).
13
14
15## Summary
16
17The RLayout code came in as part of the support for the RandR X
18extension, but isn't tied to RandR itself.  Rather, it's a generalized
19scheme for describing and determining intersecting layouts of abstract
20things.
21
22In practice, most uses boil down to a description of the layout of your
23monitor[s], and its functions are used to map windows onto them, figure
24out which monitor[s] the window is on, and figure out what it would mean
25to `f.*zoom` that window in various ways, either keeping it on a single
26monitor or crossing multiple.
27
28This document attempts to give an overview of the pieces defined in the
29various `r_area*.[ch]` and `r_layout.[ch]` files.  There is fairly
30extensive documentation in Doxygen comments on the structures and
31functions (x-ref <<doxygen.adoc,Doxygen bits>> in this manual for how to
32build and use them), as well as fairly extensive narrative comments
33through the code.  This document won't attempt to cover all those sort of
34details, but rather to give a high level view of the goals of the code.
35
36
37
38## Data Structures
39
40### RArea
41
42`RArea` defines an area of space, given by X/Y coordinates, and
43width/height extents.  In the global layout sense, each monitor is
44represented by an RArea giving its position on the whole desktop space.
45When positioning or sizing windows, an (emphemeral) `RArea` is created
46defining the window's size/position, to be used by the various
47`RArea*()` or `RLayout*()` functions.
48
49### RAreaList
50
51`RAreaList` is just a container for a set of ``RArea``'s.  It's used
52anywhere we need to build or pass around lists of ``RArea``'s.  Commonly
53these will involve monitors.  _e.g._, the list of all your monitors is an
54`RAreaList`, as would be the result of asking "`Which monitor[s] is this
55window being displayed on?`", etc.
56
57
58### RLayout
59
60`RLayout` is used to hold derived attributes of an `RAreaList`.  This
61generally means "`the layout of your monitors`".  It holds the list of
62monitors, and also separately (if your setup provides such) the list of
63output names provided by RandR, which can be used to set the geometry
64of things like icon managers in an output-relative way.
65
66It also contains pre-built ``RAreaList``'s of all the rectangular
67horizontal and vertical stripes that make up the space covered by the
68union of your monitors.  This is used in calculating horizontal and
69vertical ``f.zoom``'s of windows, so they cover the maximum available
70space without stretching outside the area covered by monitors.  This is
71important when your monitor setup doesn't make a single rectangle
72(_e.g._, you have 2 monitors with different resolutions).
73
74
75## Examples
76
77Let's consider an example layout.
78
79image::static/monitors.svg#v_monitors=1[opts=interactive]
80
81When starting up, ctwm will find the maximal horizontal:
82
83image::static/monitors.svg#v_hstripe=1[opts=interactive]
84
85and vertical:
86
87image::static/monitors.svg#v_vstripe=1[opts=interactive]
88
89stripes.  This get stashed up in the `RLayout` for the Screen, and will
90be used when figuring various zooms.
91
92
93### Zooming
94
95Let's put a window on the screen, and see what various ``f.zoom``'s will
96do to it.
97
98#### Horizontal zooming
99
100image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_x=300&g_xwin_y=40[opts=interactive]
101
102This window is now _mostly_ on `Mon1`, and mostly on the "top half" of
103things.  If we `f.horizoom` it, it thus zooms up to the full width of
104`Mon1`:
105
106image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_w=400&g_xwin_x=3&g_xwin_y=40[opts=interactive]
107
108But if we `f.xhorizoom` it, it takes up the full width of the horizontal
109stripe it's on (_note showing stripes in the background here, not
110monitors like the surrounding images_):
111
112image::static/monitors.svg#v_hstripe=1&v_xwin=1&g_xwin_w=600&g_xwin_x=3&g_xwin_y=40[opts=interactive]
113
114Or, if we moved it over so most of it was on `Mon2` instead,
115
116image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_x=350&g_xwin_y=40[opts=interactive]
117
118then the `f.horizoom` would zoom it up to the full width of `Mon2`:
119
120image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_w=200&g_xwin_x=403&g_xwin_y=40[opts=interactive]
121
122and `f.xhorizoom` would do the same thing as above.
123
124
125#### Vertical zooming
126
127Imagine the same thing, except adjusting the height on the vertical stripes.
128
129
130#### Full zooming
131
132Now let's consider `f.fullscreenzoom` and its `x` variant.
133
134image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_x=300&g_xwin_y=100[opts=interactive]
135
136The window is still mostly on `Mon1`.  Note that part of the window is
137currently in dead space, and so not visible.  If `f.fullscreenzoom` it,
138because it's mostly on `Mon1`, it will cover that monitor completely:
139
140image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_w=400&g_xwin_h=200&g_xwin_x=3&g_xwin_y=3[opts=interactive]
141
142Or, if we pushed it over to be mostly on `Mon2`,
143
144image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_x=350&g_xwin_y=100[opts=interactive]
145
146then `f.fullscreenzoom` will fill that out:
147
148image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_w=200&g_xwin_h=400&g_xwin_x=403&g_xwin_y=3[opts=interactive]
149
150`f.xfullscreenzoom`, like the other `x` variants, will span monitors.  In
151the case of `fullscreenzoom`, it will consider both the horizontal and
152vertical stripes the window lives in, and fill it over whichever makes
153the window bigger.
154
155In both cases above, the top horizontal stripe is the biggest; it's a
156full monitor size, plus half of another.  The bottom horizontal stripe is
157only half a monitor's size, and both vertical stripes are the same size
158as a monitor.  So ``f.xfullscreenzoom``'ing the window will make it cover
159up the whole top horizontal stripe:
160
161image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_w=600&g_xwin_h=200&g_xwin_x=3&g_xwin_y=3[opts=interactive]
162
163If, however, we first moved it down so it didn't occupy the top
164horizontal stripe at all,
165
166image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_x=350&g_xwin_y=225[opts=interactive]
167
168then the largest stripe available for it to fill would be the right
169vertical stripe, leading to the same result as the right-size
170`f.fullscreenzoom` above:
171
172image::static/monitors.svg#v_monitors=1&v_xwin=1&g_xwin_w=200&g_xwin_h=400&g_xwin_x=403&g_xwin_y=3[opts=interactive]
173
174In this case, it's technically filling `Vstripe2`, rather than `Mon2`,
175but in the case of the particular layout we're working with, it's the
176same thing.
177
178In the case where your layout doesn't have any dead space (_e.g._, 2
179same-resolution monitors stacked horizontally or vertically, 4
180same-resolution monitors in a square, etc), there will only be one
181horizontal and one vertical stripe, which cover the whole desktop area.
182So `f.xfullscreenzoom` will always wind up covering the whole thing.
183