7 | 7 |
you understand why things are like they are. If it does not mention something
|
8 | 8 |
you find necessary, please do not hesitate to contact me.
|
9 | 9 |
|
|
10 |
++++
|
|
11 |
<div style="background-color:red; color:white; padding:20px;">
|
|
12 |
<strong style="color:white;">WARNING!</strong>
|
|
13 |
<p>
|
|
14 |
++++
|
|
15 |
This document is not 100% up to date. Specifically, everything up to and
|
|
16 |
including <<data_structures>> has been updated recently. The rest might contain
|
|
17 |
outdated information.
|
|
18 |
++++
|
|
19 |
</p>
|
|
20 |
</div>
|
|
21 |
++++
|
|
22 |
|
10 | 23 |
== Building i3
|
11 | 24 |
|
12 | 25 |
You can build i3 like you build any other software package which uses autotools.
|
|
17 | 30 |
$ ../configure
|
18 | 31 |
$ make -j8
|
19 | 32 |
|
20 | |
(The autoreconf -fi step is unnecessary if you are building from a release tarball,
|
21 | |
but shouldn’t hurt either.)
|
|
33 |
The autoreconf -fi step is unnecessary if you are building from a release
|
|
34 |
tarball, but shouldn’t hurt either.
|
22 | 35 |
|
23 | 36 |
=== Build system features
|
24 | 37 |
|
25 | |
* We use the AX_ENABLE_BUILDDIR macro to enforce builds happening in a separate
|
26 | |
directory. This is a prerequisite for the AX_EXTEND_SRCDIR macro and building
|
|
38 |
* We use the +AX_ENABLE_BUILDDIR+ macro to enforce builds happening in a separate
|
|
39 |
directory. This is a prerequisite for the +AX_EXTEND_SRCDIR+ macro and building
|
27 | 40 |
in a separate directory is common practice anyway. In case this causes any
|
28 | 41 |
trouble when packaging i3 for your distribution, please open an issue.
|
29 | 42 |
|
30 | |
* “make check” runs the i3 testsuite. See docs/testsuite for details.
|
31 | |
|
32 | |
* “make distcheck” (runs testsuite on “make dist” result, tiny bit quicker
|
|
43 |
* +make check+ runs the i3 testsuite. See docs/testsuite for details.
|
|
44 |
|
|
45 |
* +make distcheck+ (runs testsuite on +make dist+ result, tiny bit quicker
|
33 | 46 |
feedback cycle than waiting for the travis build to catch the issue).
|
34 | 47 |
|
35 | |
* “make uninstall” (occasionally requested by users who compile from source)
|
36 | |
|
37 | |
* “make” will build manpages/docs by default if the tools are installed.
|
|
48 |
* +make uninstall+ (occasionally requested by users who compile from source)
|
|
49 |
|
|
50 |
* +make+ will build manpages/docs by default if the tools are installed.
|
38 | 51 |
Conversely, manpages/docs are not tried to be built for users who don’t want
|
39 | |
to install all these dependencies to get started hacking on i3.
|
|
52 |
to install all these dependencies to get started hacking on i3. Manpages and
|
|
53 |
docs can be disabled with the +--disable-mans++ and ++--disable-docs++
|
|
54 |
configure options respectively.
|
40 | 55 |
|
41 | 56 |
* non-release builds will enable address sanitizer by default. Use the
|
42 | |
--disable-sanitizers configure option to turn off all sanitizers, and see
|
43 | |
--help for available sanitizers.
|
44 | |
|
45 | |
* Support for pre-compiled headers (PCH) has been dropped for now in the
|
46 | |
interest of simplicity. If you need support for PCH, please open an issue.
|
47 | |
|
48 | |
* Coverage reports are now generated using “make check-code-coverage”, which
|
49 | |
requires specifying --enable-code-coverage when calling configure.
|
50 | |
|
51 | |
== Using git / sending patches
|
52 | |
|
53 | |
For a short introduction into using git, see
|
54 | |
https://web.archive.org/web/20121024222556/http://www.spheredev.org/wiki/Git_for_the_lazy
|
55 | |
or, for more documentation, see https://git-scm.com/documentation
|
|
57 |
+--disable-sanitizers+ configure option to turn off all sanitizers, and see
|
|
58 |
+--help+ for available sanitizers.
|
|
59 |
|
|
60 |
* Coverage reports are now generated using +make check-code-coverage+, which
|
|
61 |
requires specifying +--enable-code-coverage+ when calling configure.
|
|
62 |
|
|
63 |
== Pull requests
|
56 | 64 |
|
57 | 65 |
Please talk to us before working on new features to see whether they will be
|
58 | 66 |
accepted. A good way for this is to open an issue and asking for opinions on it.
|
59 | |
Even for accepted features, this can be a good way to refine an idea upfront. However,
|
60 | |
we don't want to see certain features in i3, e.g., switching window focus in an
|
61 | |
Alt+Tab like way.
|
62 | |
|
63 | |
When working on bugfixes, please make sure you mention that you are working on
|
64 | |
it in the corresponding bug report at https://github.com/i3/i3/issues. In case
|
65 | |
there is no bug report yet, please create one.
|
|
67 |
Even for accepted features, this can be a good way to refine an idea upfront.
|
|
68 |
However, we don't want to see certain features in i3, e.g., switching window
|
|
69 |
focus in an Alt+Tab like way.
|
|
70 |
|
|
71 |
When working on bugfixes, please make sure you mention that you are working on it
|
|
72 |
in the corresponding bug report at https://github.com/i3/i3/issues. In case there
|
|
73 |
is no bug report yet, please create one.
|
66 | 74 |
|
67 | 75 |
After you are done, please submit your work for review as a pull request at
|
68 | |
https://github.com/i3/i3.
|
69 | |
|
70 | |
Do not send emails to the mailing list or any author directly, and don’t submit
|
71 | |
them in the bugtracker, since all reviews should be done in public at
|
72 | |
https://github.com/i3/i3. In order to make your review go as fast as possible, you
|
73 | |
could have a look at previous reviews and see what the common mistakes are.
|
|
76 |
https://github.com/i3/i3. In order to make your review go as fast as possible,
|
|
77 |
you could have a look at previous reviews and see what the common mistakes are.
|
74 | 78 |
|
75 | 79 |
=== Which branch to use?
|
76 | 80 |
|
|
81 | 85 |
The contents of “master” are always stable. That is, it contains the source code
|
82 | 86 |
of the latest release, plus any bugfixes that were applied since that release.
|
83 | 87 |
|
84 | |
New features are only found in the “next” branch. Therefore, if you are working
|
85 | |
on a new feature, use the “next” branch. If you are working on a bugfix, use the
|
86 | |
“next” branch, too, but make sure your code also works on “master”.
|
|
88 |
New features are only found in the “next” branch. Always use this branch when
|
|
89 |
writing new code (both bugfixes and features).
|
87 | 90 |
|
88 | 91 |
== Window Managers
|
89 | 92 |
|
|
105 | 108 |
the first client of X) and manage them (reparent them, create window
|
106 | 109 |
decorations, etc.)
|
107 | 110 |
. When new windows are created, manage them
|
108 | |
. Handle the client’s `_WM_STATE` property, but only `_WM_STATE_FULLSCREEN` and
|
109 | |
`_NET_WM_STATE_DEMANDS_ATTENTION`
|
110 | |
. Handle the client’s `WM_NAME` property
|
|
111 |
. Handle the client’s +_WM_STATE+ property, but only +_WM_STATE_FULLSCREEN+ and
|
|
112 |
+_NET_WM_STATE_DEMANDS_ATTENTION+
|
|
113 |
. Handle the client’s +WM_NAME+ property
|
111 | 114 |
. Handle the client’s size hints to display them proportionally
|
112 | 115 |
. Handle the client’s urgency hint
|
113 | 116 |
. Handle enter notifications (focus follows mouse)
|
|
122 | 125 |
|
123 | 126 |
=== Tiling window managers
|
124 | 127 |
|
125 | |
Traditionally, there are two approaches to managing windows: The most common
|
126 | |
one nowadays is floating, which means the user can freely move/resize the
|
127 | |
windows. The other approach is called tiling, which means that your window
|
128 | |
manager distributes windows to use as much space as possible while not
|
129 | |
overlapping each other.
|
|
128 |
Traditionally, there are two approaches to managing windows: The most common one
|
|
129 |
nowadays is stacking (or floating, using i3's terminology), which means the user
|
|
130 |
can freely move/resize the windows, potentially overlapping them. The other
|
|
131 |
approach is called tiling, which means that the window manager distributes
|
|
132 |
windows to use as much space as possible while not overlapping each other.
|
130 | 133 |
|
131 | 134 |
The idea behind tiling is that you should not need to waste your time
|
132 | 135 |
moving/resizing windows while you usually want to get some work done. After
|
|
160 | 163 |
|
161 | 164 |
== Files
|
162 | 165 |
|
|
166 |
i3's source code is in the +src+ folder while header files reside in +include+.
|
|
167 |
Other tools such as i3bar and i3-nagbar have their own folders. i3 and its tools
|
|
168 |
share an internal library called ``libi3'' which also has its own folder.
|
|
169 |
|
|
170 |
The following list gives an overview of the codebase, explaining the
|
|
171 |
functionality of the most important, core source code files. Other files in the
|
|
172 |
tree that are not mentioned here implement specific functionalities: for example,
|
|
173 |
+src/scratchpad.c+ is obviously about the scratchpad functionality.
|
|
174 |
|
|
175 |
include/data.h::
|
|
176 |
Contains data definitions used by nearly all files.
|
|
177 |
|
|
178 |
include/*.h::
|
|
179 |
Contains forward definitions for all public functions, as well as
|
|
180 |
doxygen-compatible comments (so if you want to get a bit more of the big
|
|
181 |
picture, either browse all header files or use doxygen if you prefer that).
|
|
182 |
|
|
183 |
src/config_directives.c::
|
|
184 |
src/commands.c::
|
|
185 |
Contain the definitions for all high-level config and command directives. These
|
|
186 |
are excellent places to start with a top-to-bottom approach to understand
|
|
187 |
specific i3 behavior. For example, if you want to investigate a bug that happens
|
|
188 |
for the +move to mark+ command, you can use gdb to pause in
|
|
189 |
+cmd_move_con_to_mark+ and then work your way from there, stepping into
|
|
190 |
lower-level functions.
|
|
191 |
|
|
192 |
src/con.c::
|
|
193 |
Contains all functions which deal with containers directly (creating containers,
|
|
194 |
searching containers, getting specific properties from containers, …). Contains
|
|
195 |
abstractions and auxiliary functions necessary to work with the container
|
|
196 |
structure which is used in almost all parts of the codebase.
|
|
197 |
|
|
198 |
src/tree.c::
|
|
199 |
Contains functions which deal with the tree abstraction. However, be aware that
|
|
200 |
+src/con.c+ also contains functions that heavily interact with the tree
|
|
201 |
structure. Some functions that are included in +str/tree.c+ are those that handle
|
|
202 |
opening and closing containers in the tree, finding the container that should be
|
|
203 |
focused next and flattening the tree. See also +src/move.c+ for other
|
|
204 |
move-specific functions that interact with the tree, which were moved into their
|
|
205 |
own file because they are so long.
|
|
206 |
|
|
207 |
src/workspace.c::
|
|
208 |
Contains functions which deal with workspaces. Includes code that creates new
|
|
209 |
workspaces, shows existing ones and deals with workspace assignments.
|
|
210 |
|
|
211 |
src/handlers.c::
|
|
212 |
Contains all handlers for all kinds of X events (new window title, new hints,
|
|
213 |
unmapping, key presses, button presses, …). This is a very important file to
|
|
214 |
understand how i3 interacts with changes to its environment.
|
|
215 |
|
|
216 |
src/command_parser.c::
|
|
217 |
src/config_parser.c::
|
|
218 |
Contain a hand-written parser to parse commands and configuration (commands are what
|
|
219 |
you bind on keys and what you can send to i3 using the IPC interface, like
|
|
220 |
+move left+ or +workspace 4+). +src/config.c+ is responsible for calling the
|
|
221 |
configuration parser.
|
|
222 |
|
|
223 |
src/click.c::
|
|
224 |
src/resize.c::
|
|
225 |
Contain functions which handle mouse button clicks (right mouse button
|
|
226 |
clicks initiate resizing and thus are relatively complex).
|
|
227 |
|
|
228 |
src/manage.c::
|
|
229 |
Looks at existing or new windows and decides whether to manage them. If so, it
|
|
230 |
reparents the window and inserts it into our data structures.
|
|
231 |
|
|
232 |
src/match.c::
|
|
233 |
A "match" is a data structure which acts like a mask or expression to match
|
|
234 |
certain windows or not. For example, when using commands, you can specify a
|
|
235 |
command like this: +[title="*Firefox*"] kill+. The title member of the match
|
|
236 |
data structure will then be filled and i3 will check each window using
|
|
237 |
+match_matches_window()+ to find the windows affected by this command.
|
|
238 |
|
|
239 |
src/randr.c::
|
|
240 |
The RandR API is used to get (and re-query) the configured outputs (monitors,
|
|
241 |
…). Legacy Xinerama support resides in +src/xinerama.c+.
|
|
242 |
|
|
243 |
src/render.c::
|
|
244 |
Renders the tree data structure by assigning coordinates to every node. These
|
|
245 |
values will later be pushed to X11 in +src/x.c+.
|
|
246 |
|
|
247 |
src/sighandler.c::
|
|
248 |
Handles +SIGSEGV+, +SIGABRT+ and +SIGFPE+ by showing a dialog that i3 crashed.
|
|
249 |
You can choose to let it dump core and restart i3 in-place (either trying to
|
|
250 |
preserve layout or forget about it).
|
|
251 |
|
|
252 |
src/window.c::
|
|
253 |
Handlers to update X11 window properties like +WM_CLASS+, +_NET_WM_NAME+,
|
|
254 |
+CLIENT_LEADER+, etc.
|
|
255 |
|
163 | 256 |
include/atoms.xmacro::
|
164 | 257 |
A file containing all X11 atoms which i3 uses. This file will be included
|
165 | 258 |
various times (for defining, requesting and receiving the atoms), each time
|
166 | 259 |
with a different definition of xmacro().
|
167 | 260 |
|
168 | |
include/data.h::
|
169 | |
Contains data definitions used by nearly all files. You really need to read
|
170 | |
this first.
|
171 | |
|
172 | |
include/*.h::
|
173 | |
Contains forward definitions for all public functions, as well as
|
174 | |
doxygen-compatible comments (so if you want to get a bit more of the big
|
175 | |
picture, either browse all header files or use doxygen if you prefer that).
|
176 | |
|
177 | |
src/config_parser.c::
|
178 | |
Contains a custom configuration parser. See src/command_parser.c for rationale
|
179 | |
on why we use a custom parser.
|
180 | |
|
181 | |
src/click.c::
|
182 | |
Contains all functions which handle mouse button clicks (right mouse button
|
183 | |
clicks initiate resizing and thus are relatively complex).
|
184 | |
|
185 | |
src/command_parser.c::
|
186 | |
Contains a hand-written parser to parse commands (commands are what
|
187 | |
you bind on keys and what you can send to i3 using the IPC interface, like
|
188 | |
'move left' or 'workspace 4').
|
189 | |
|
190 | |
src/con.c::
|
191 | |
Contains all functions which deal with containers directly (creating
|
192 | |
containers, searching containers, getting specific properties from containers,
|
193 | |
…).
|
194 | |
|
195 | |
src/config.c::
|
196 | |
Contains all functions handling the configuration file (calling the parser
|
197 | |
src/config_parser.c) with the correct path, switching key bindings mode).
|
198 | |
|
199 | |
src/ewmh.c::
|
200 | |
Functions to get/set certain EWMH properties easily.
|
201 | |
|
202 | |
src/floating.c::
|
203 | |
Contains functions for floating mode (mostly resizing/dragging).
|
204 | |
|
205 | |
src/handlers.c::
|
206 | |
Contains all handlers for all kinds of X events (new window title, new hints,
|
207 | |
unmapping, key presses, button presses, …).
|
208 | |
|
209 | |
src/ipc.c::
|
210 | |
Contains code for the IPC interface.
|
211 | |
|
212 | |
src/load_layout.c::
|
213 | |
Contains code for loading layouts from JSON files.
|
214 | |
|
215 | |
src/log.c::
|
216 | |
Contains the logging functions.
|
217 | |
|
218 | |
src/main.c::
|
219 | |
Initializes the window manager.
|
220 | |
|
221 | |
src/manage.c::
|
222 | |
Looks at existing or new windows and decides whether to manage them. If so, it
|
223 | |
reparents the window and inserts it into our data structures.
|
224 | |
|
225 | |
src/match.c::
|
226 | |
A "match" is a data structure which acts like a mask or expression to match
|
227 | |
certain windows or not. For example, when using commands, you can specify a
|
228 | |
command like this: [title="*Firefox*"] kill. The title member of the match
|
229 | |
data structure will then be filled and i3 will check each window using
|
230 | |
match_matches_window() to find the windows affected by this command.
|
231 | |
|
232 | |
src/move.c::
|
233 | |
Contains code to move a container in a specific direction.
|
234 | |
|
235 | |
src/output.c::
|
236 | |
Functions to handle CT_OUTPUT cons.
|
237 | |
|
238 | |
src/randr.c::
|
239 | |
The RandR API is used to get (and re-query) the configured outputs (monitors,
|
240 | |
…).
|
241 | |
|
242 | |
src/render.c::
|
243 | |
Renders the tree data structure by assigning coordinates to every node. These
|
244 | |
values will later be pushed to X11 in +src/x.c+.
|
245 | |
|
246 | |
src/resize.c::
|
247 | |
Contains the functions to resize containers.
|
248 | |
|
249 | |
src/restore_layout.c::
|
250 | |
Everything for restored containers that is not pure state parsing (which can be
|
251 | |
found in load_layout.c).
|
252 | |
|
253 | |
src/sighandler.c::
|
254 | |
Handles +SIGSEGV+, +SIGABRT+ and +SIGFPE+ by showing a dialog that i3 crashed.
|
255 | |
You can chose to let it dump core, to restart it in-place or to restart it
|
256 | |
in-place but forget about the layout.
|
257 | |
|
258 | |
src/tree.c::
|
259 | |
Contains functions which open or close containers in the tree, change focus or
|
260 | |
cleanup ("flatten") the tree. See also +src/move.c+ for another similar
|
261 | |
function, which was moved into its own file because it is so long.
|
262 | |
|
263 | |
src/util.c::
|
264 | |
Contains useful functions which are not really dependent on anything.
|
265 | |
|
266 | |
src/window.c::
|
267 | |
Handlers to update X11 window properties like +WM_CLASS+, +_NET_WM_NAME+,
|
268 | |
+CLIENT_LEADER+, etc.
|
269 | |
|
270 | |
src/workspace.c::
|
271 | |
Contains all functions related to workspaces (displaying, hiding, renaming…)
|
272 | |
|
273 | |
src/x.c::
|
274 | |
Transfers our in-memory tree (see +src/render.c+) to X11.
|
275 | |
|
276 | |
src/xcb.c::
|
277 | |
Contains wrappers to use xcb more easily.
|
278 | |
|
279 | |
src/xcursor.c::
|
280 | |
XCursor functions (for cursor themes).
|
281 | |
|
282 | |
src/xinerama.c::
|
283 | |
Legacy support for Xinerama. See +src/randr.c+ for the preferred API.
|
284 | |
|
|
261 |
[[data_structures]]
|
285 | 262 |
== Data structures
|
286 | 263 |
|
287 | |
|
288 | |
See include/data.h for documented data structures. The most important ones are
|
289 | |
explained right here.
|
290 | |
|
291 | |
/////////////////////////////////////////////////////////////////////////////////
|
292 | |
// TODO: update image
|
293 | |
|
294 | |
image:bigpicture.png[The Big Picture]
|
295 | |
|
296 | |
/////////////////////////////////////////////////////////////////////////////////
|
297 | |
|
298 | |
So, the hierarchy is:
|
299 | |
|
300 | |
. *X11 root window*, the root container
|
301 | |
. *Output container* (LVDS1 in this example)
|
302 | |
. *Content container* (there are also containers for dock windows)
|
303 | |
. *Workspaces* (Workspace 1 in this example, with horizontal orientation)
|
304 | |
. *Split container* (vertically split)
|
305 | |
. *X11 window containers*
|
|
264 |
See +include/data.h+ for documented data structures. The most important ones are
|
|
265 |
explained here.
|
|
266 |
|
|
267 |
The following picture is generated by the +contrib/dump-asy.pl+ script.
|
|
268 |
|
|
269 |
image:bigpicture.png["The Big Picture",width=1000,link="bigpicture.png"]
|
|
270 |
|
|
271 |
The hierarchy is:
|
|
272 |
|
|
273 |
. *Root container*
|
|
274 |
. *Output containers*: +eDP-1+ in this example and the internal +__i3++ output
|
|
275 |
. *Content and 2 dockarea containers*
|
|
276 |
. *Workspaces*: Numbered workspace ``1'' and a ``Named workspace''
|
|
277 |
. *Split containers*: One horizontal in the first workspace and a tabbed one in
|
|
278 |
the named one.
|
|
279 |
. *Leaf containers*: Windows like vim and an i3bar dock.
|
306 | 280 |
|
307 | 281 |
The data type is +Con+, in all cases.
|
308 | 282 |
|
309 | |
=== X11 root window
|
310 | |
|
311 | |
The X11 root window is a single window per X11 display (a display is identified
|
312 | |
by +:0+ or +:1+ etc.). The root window is what you draw your background image
|
313 | |
on. It spans all the available outputs, e.g. +VGA1+ is a specific part of the
|
314 | |
root window and +LVDS1+ is a specific part of the root window.
|
|
283 |
=== Root container
|
|
284 |
|
|
285 |
The root container (global variable +croot+) is the up-most ascendant of every i3
|
|
286 |
container. It can be used to iterate over the whole tree structure. E.g., it is
|
|
287 |
used to reply to the +GET_WORKSPACES+ request, iterating over it's children to
|
|
288 |
find all workspaces. This is different from the X11 root window.
|
|
289 |
|
|
290 |
The X11 root window (global variable +root+) is a single window per X11 display
|
|
291 |
(a display is identified by +:0+ or +:1+ etc.). The root window is what you draw
|
|
292 |
your background image on. It spans all the available outputs, e.g. +VGA1+ is a
|
|
293 |
specific part of the root window and +LVDS1+ is a specific part of the root
|
|
294 |
window.
|
315 | 295 |
|
316 | 296 |
=== Output container
|
317 | 297 |
|
|
333 | 313 |
=== Content container
|
334 | 314 |
|
335 | 315 |
Each output has multiple children. Two of them are dock containers which hold
|
336 | |
dock clients. The other one is the content container, which holds the actual
|
337 | |
content (workspaces) of this output.
|
|
316 |
the top and bottom dock clients. The other one is the content container, which
|
|
317 |
holds the actual content (workspaces) of this output.
|
338 | 318 |
|
339 | 319 |
=== Workspace
|
340 | 320 |
|
|
353 | 333 |
Split containers (and X11 window containers, which are a subtype of split
|
354 | 334 |
containers) can have different border styles.
|
355 | 335 |
|
356 | |
=== X11 window container
|
357 | |
|
358 | |
An X11 window container holds exactly one X11 window. These are the leaf nodes
|
359 | |
of the layout tree, they cannot have any children.
|
|
336 |
=== Leaf containers
|
|
337 |
|
|
338 |
A leaf container holds exactly one X11 window. They can't have any children.
|
360 | 339 |
|
361 | 340 |
== List/queue macros
|
362 | 341 |
|
363 | 342 |
i3 makes heavy use of the list macros defined in BSD operating systems. To
|
364 | 343 |
ensure that the operating system on which i3 is compiled has all the expected
|
365 | |
features, i3 comes with `include/queue.h`. On BSD systems, you can use man
|
366 | |
`queue(3)`. On Linux, you have to use google (or read the source).
|
|
344 |
features, i3 comes with +include/queue.h+. On BSD systems, you can use +man
|
|
345 |
queue(3)+. On Linux, you have to use google (or read the source).
|
367 | 346 |
|
368 | 347 |
The lists used are +SLIST+ (single linked lists), +CIRCLEQ+ (circular
|
369 | 348 |
queues) and +TAILQ+ (tail queues). Usually, only forward traversal is necessary,
|
370 | |
so an `SLIST` works fine. If inserting elements at arbitrary positions or at
|
|
349 |
so an +SLIST+ works fine. If inserting elements at arbitrary positions or at
|
371 | 350 |
the end of a list is necessary, a +TAILQ+ is used instead. However, for the
|
372 | 351 |
windows inside a container, a +CIRCLEQ+ is necessary to go from the currently
|
373 | 352 |
selected window to the window above/below.
|
|
377 | 356 |
There is a row of standard variables used in many events. The following names
|
378 | 357 |
should be chosen for those:
|
379 | 358 |
|
380 | |
* ``conn'' is the xcb_connection_t
|
381 | |
* ``event'' is the event of the particular type
|
382 | |
* ``con'' names a container
|
383 | |
* ``current'' is a loop variable when using +TAILQ_FOREACH+ etc.
|
|
359 |
* +conn+ is the xcb_connection_t
|
|
360 |
* +event+ is the event of the particular type
|
|
361 |
* +con+ names a container
|
|
362 |
* +current+ is a loop variable when using +TAILQ_FOREACH+ etc.
|
384 | 363 |
|
385 | 364 |
== Startup (src/mainx.c, main())
|
386 | 365 |
|
|
429 | 408 |
|
430 | 409 |
== Manage windows (src/main.c, manage_window() and reparent_window())
|
431 | 410 |
|
432 | |
`manage_window()` does some checks to decide whether the window should be
|
|
411 |
+manage_window()+ does some checks to decide whether the window should be
|
433 | 412 |
managed at all:
|
434 | 413 |
|
435 | 414 |
* Windows have to be mapped, that is, visible on screen
|
|
437 | 416 |
not be managed by a window manager
|
438 | 417 |
|
439 | 418 |
Afterwards, i3 gets the initial geometry and reparents the window (see
|
440 | |
`reparent_window()`) if it wasn’t already managed.
|
|
419 |
+reparent_window()+) if it wasn’t already managed.
|
441 | 420 |
|
442 | 421 |
Reparenting means that for each window which is reparented, a new window,
|
443 | 422 |
slightly larger than the original one, is created. The original window is then
|
444 | 423 |
reparented to the bigger one (called "frame").
|
445 | 424 |
|
446 | |
After reparenting, the window type (`_NET_WM_WINDOW_TYPE`) is checked to see
|
447 | |
whether this window is a dock (`_NET_WM_WINDOW_TYPE_DOCK`), like dzen2 for
|
|
425 |
After reparenting, the window type (+_NET_WM_WINDOW_TYPE+) is checked to see
|
|
426 |
whether this window is a dock (+_NET_WM_WINDOW_TYPE_DOCK+), like dzen2 for
|
448 | 427 |
example. Docks are handled differently, they don’t have decorations and are not
|
449 | 428 |
assigned to a specific container. Instead, they are positioned at the bottom
|
450 | 429 |
or top of the screen (in the appropriate dock area containers). To get the
|
451 | |
height which needs to be reserved for the window, the `_NET_WM_STRUT_PARTIAL`
|
|
430 |
height which needs to be reserved for the window, the +_NET_WM_STRUT_PARTIAL+
|
452 | 431 |
property is used.
|
453 | 432 |
|
454 | 433 |
Furthermore, the list of assignments (to other workspaces, which may be on
|
|
459 | 438 |
== What happens when an application is started?
|
460 | 439 |
|
461 | 440 |
i3 does not care about applications. All it notices is when new windows are
|
462 | |
mapped (see `src/handlers.c`, `handle_map_request()`). The window is then
|
|
441 |
mapped (see +src/handlers.c+, +handle_map_request()+). The window is then
|
463 | 442 |
reparented (see section "Manage windows").
|
464 | 443 |
|
465 | |
After reparenting the window, `render_tree()` is called which renders the
|
|
444 |
After reparenting the window, +render_tree()+ is called which renders the
|
466 | 445 |
internal layout table. The new window has been placed in the currently focused
|
467 | 446 |
container and therefore the new window and the old windows (if any) need to be
|
468 | 447 |
moved/resized so that the currently active layout (default/stacking/tabbed mode)
|
|
481 | 460 |
Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms
|
482 | 461 |
are handled.
|
483 | 462 |
|
484 | |
The former calls ``toggle_fullscreen()'' for the specific client which just
|
|
463 |
The former calls +toggle_fullscreen()+ for the specific client which just
|
485 | 464 |
configures the client to use the whole screen on which it currently is.
|
486 | 465 |
Also, it is set as fullscreen_client for the i3Screen.
|
487 | 466 |
|
|
538 | 517 |
|
539 | 518 |
=== Rendering the root container
|
540 | 519 |
|
541 | |
The i3 root container (`con->type == CT_ROOT`) represents the X11 root window.
|
|
520 |
The i3 root container (+con->type == CT_ROOT+) represents the X11 root window.
|
542 | 521 |
It contains one child container for every output (like LVDS1, VGA1, …), which
|
543 | 522 |
is available on your computer.
|
544 | 523 |
|
|
557 | 536 |
|
558 | 537 |
=== Rendering an output
|
559 | 538 |
|
560 | |
Output containers (`con->layout == L_OUTPUT`) represent a hardware output like
|
|
539 |
Output containers (+con->layout == L_OUTPUT+) represent a hardware output like
|
561 | 540 |
LVDS1, VGA1, etc. An output container has three children (at the moment): One
|
562 | 541 |
content container (having workspaces as children) and the top/bottom dock area
|
563 | 542 |
containers.
|
|
565 | 544 |
The rendering happens in the function +render_l_output()+ in the following
|
566 | 545 |
steps:
|
567 | 546 |
|
568 | |
1. Find the content container (`con->type == CT_CON`)
|
|
547 |
1. Find the content container (+con->type == CT_CON+)
|
569 | 548 |
2. Get the currently visible workspace (+con_get_fullscreen_con(content,
|
570 | 549 |
CF_OUTPUT)+).
|
571 | 550 |
3. If there is a fullscreened window on that workspace, directly render it and
|
|
573 | 552 |
4. Sum up the space used by all the dock windows (they have a variable height
|
574 | 553 |
only).
|
575 | 554 |
5. Set the workspace rects (x/y/width/height) based on the position of the
|
576 | |
output (stored in `con->rect`) and the usable space
|
577 | |
(`con->rect.{width,height}` without the space used for dock windows).
|
|
555 |
output (stored in +con->rect+) and the usable space
|
|
556 |
(+con->rect.{width,height}+ without the space used for dock windows).
|
578 | 557 |
6. Recursively raise and render the output’s child containers (meaning dock
|
579 | 558 |
area containers and the content container).
|
580 | 559 |
|
581 | 560 |
=== Rendering a workspace or split container
|
582 | 561 |
|
583 | 562 |
From here on, there really is no difference anymore. All containers are of
|
584 | |
`con->type == CT_CON` (whether workspace or split container) and some of them
|
585 | |
have a `con->window`, meaning they represent an actual window instead of a
|
|
563 |
+con->type == CT_CON+ (whether workspace or split container) and some of them
|
|
564 |
have a +con->window+, meaning they represent an actual window instead of a
|
586 | 565 |
split container.
|
587 | 566 |
|
588 | 567 |
==== Default layout
|
589 | 568 |
|
590 | 569 |
In default layout, containers are placed horizontally or vertically next to
|
591 | |
each other (depending on the `con->orientation`). If a child is a leaf node (as
|
|
570 |
each other (depending on the +con->orientation+). If a child is a leaf node (as
|
592 | 571 |
opposed to a split container) and has border style "normal", appropriate space
|
593 | 572 |
will be reserved for its window decoration.
|
594 | 573 |
|
|
834 | 813 |
the beginning. +
|
835 | 814 |
|
836 | 815 |
NOTE: Note that you can specify multiple literals in the same line. This has
|
837 | |
exactly the same effect as if you specified `direction =
|
838 | |
'next_on_output' -> call cmd_workspace($direction)` and so forth. +
|
|
816 |
exactly the same effect as if you specified +direction =
|
|
817 |
'next_on_output' -> call cmd_workspace($direction)+ and so forth. +
|
839 | 818 |
|
840 | 819 |
NOTE: Also note that the order of literals is important here: If 'next' were
|
841 | 820 |
ordered before 'next_on_output', then 'next_on_output' would never
|
|
1019 | 998 |
|
1020 | 999 |
== Gotchas
|
1021 | 1000 |
|
1022 | |
* Forgetting to call `xcb_flush(conn);` after sending a request. This usually
|
|
1001 |
* Forgetting to call +xcb_flush(conn);+ after sending a request. This usually
|
1023 | 1002 |
leads to code which looks like it works fine but which does not work under
|
1024 | 1003 |
certain conditions.
|
1025 | 1004 |
|
1026 | |
* Forgetting to call `floating_fix_coordinates(con, old_rect, new_rect)` after
|
|
1005 |
* Forgetting to call +floating_fix_coordinates(con, old_rect, new_rect)+ after
|
1027 | 1006 |
moving workspaces across outputs. Coordinates for floating containers are
|
1028 | 1007 |
not relative to workspace boundaries, so you must correct their coordinates
|
1029 | 1008 |
or those containers will show up in the wrong workspace or not at all.
|