Merge pull request #4057 from orestisfl/hacking-howto

Update first 1/3 of hacking-howto document
This commit is contained in:
Orestis Floros 2020-05-06 17:30:58 +02:00 committed by GitHub
commit e4629d678e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 175 additions and 177 deletions

View File

@ -38,4 +38,4 @@ Note that bug reports and feature requests for related projects should be filed
* Find a [reproducible bug](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Areproducible+label%3Abug+) from the issue tracker. These issues have been reviewed and confirmed by a project contributor. * Find a [reproducible bug](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Areproducible+label%3Abug+) from the issue tracker. These issues have been reviewed and confirmed by a project contributor.
* Find an [accepted enhancement](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Aaccepted+label%3Aenhancement) from the issue tracker. These have been approved and are ok to start working on. * Find an [accepted enhancement](https://github.com/i3/i3/issues?utf8=%E2%9C%93&q=is%3Aopen+label%3Aaccepted+label%3Aenhancement) from the issue tracker. These have been approved and are ok to start working on.
There's a very good [overview of the codebase](https://i3wm.org/docs/hacking-howto.html) available to get you started. There's an [overview of the codebase](https://i3wm.org/docs/hacking-howto.html) available to get you started.

19
docs/bigpicture.asy Normal file
View File

@ -0,0 +1,19 @@
import drawtree;
treeLevelStep = 2cm;
TreeNode n94457831379296 = makeNode("``root'' (splith) []");
TreeNode n94457831380944 = makeNode(n94457831379296, "``\_\_i3'' (output) []");
TreeNode n94457831384048 = makeNode(n94457831380944, "``content'' (splith) []");
TreeNode n94457831387184 = makeNode(n94457831384048, "``\_\_i3\_scratch'' (splith) []");
TreeNode n94457831390576 = makeNode(n94457831379296, "``eDP-1'' (output) []");
TreeNode n94457831393744 = makeNode(n94457831390576, "``topdock'' (dockarea) []");
TreeNode n94457831396992 = makeNode(n94457831390576, "``content'' (splith) []");
TreeNode n94457831628304 = makeNode(n94457831396992, "``1'' (splith) []");
TreeNode n94457831571040 = makeNode(n94457831628304, "``Hacking i3: How To - Mozilla Firefox'' (leaf) []");
TreeNode n94457831246384 = makeNode(n94457831628304, "``vim'' (leaf) []");
TreeNode n94457831461088 = makeNode(n94457831396992, "``Named workspace'' (splith) []");
TreeNode n94457831471424 = makeNode(n94457831461088, "``[Empty]'' (tabbed) []");
TreeNode n94457831570576 = makeNode(n94457831471424, "``contrib/dump-asy.pl --no-gv'' (leaf) [Marks go here]");
TreeNode n94457831645488 = makeNode(n94457831471424, "``ipython'' (leaf) []");
TreeNode n94457831400192 = makeNode(n94457831390576, "``bottomdock'' (dockarea) []");
TreeNode n94457831424848 = makeNode(n94457831400192, "``i3bar for output eDP-1'' (leaf) []");
draw(n94457831379296, (0, 0));

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

View File

@ -8,6 +8,19 @@ touching i3s source code. It should contain all important information to help
you understand why things are like they are. If it does not mention something you understand why things are like they are. If it does not mention something
you find necessary, please do not hesitate to contact me. you find necessary, please do not hesitate to contact me.
++++
<div style="background-color:red; color:white; padding:20px;">
<strong style="color:white;">WARNING!</strong>
<p>
++++
This document is not 100% up to date. Specifically, everything up to and
including <<data_structures>> has been updated recently. The rest might contain
outdated information.
++++
</p>
</div>
++++
== Building i3 == Building i3
You can build i3 like you build any other software package which uses autotools. You can build i3 like you build any other software package which uses autotools.
@ -18,60 +31,51 @@ Heres a memory refresher:
$ ../configure $ ../configure
$ make -j8 $ make -j8
(The autoreconf -fi step is unnecessary if you are building from a release tarball, The autoreconf -fi step is unnecessary if you are building from a release
but shouldnt hurt either.) tarball, but shouldnt hurt either.
=== Build system features === Build system features
* We use the AX_ENABLE_BUILDDIR macro to enforce builds happening in a separate * We use the +AX_ENABLE_BUILDDIR+ macro to enforce builds happening in a separate
directory. This is a prerequisite for the AX_EXTEND_SRCDIR macro and building directory. This is a prerequisite for the +AX_EXTEND_SRCDIR+ macro and building
in a separate directory is common practice anyway. In case this causes any in a separate directory is common practice anyway. In case this causes any
trouble when packaging i3 for your distribution, please open an issue. trouble when packaging i3 for your distribution, please open an issue.
* “make check” runs the i3 testsuite. See docs/testsuite for details. * +make check+ runs the i3 testsuite. See docs/testsuite for details.
* “make distcheck” (runs testsuite on “make dist” result, tiny bit quicker * +make distcheck+ (runs testsuite on +make dist+ result, tiny bit quicker
feedback cycle than waiting for the travis build to catch the issue). feedback cycle than waiting for the travis build to catch the issue).
* “make uninstall” (occasionally requested by users who compile from source) * +make uninstall+ (occasionally requested by users who compile from source)
* “make” will build manpages/docs by default if the tools are installed. * +make+ will build manpages/docs by default if the tools are installed.
Conversely, manpages/docs are not tried to be built for users who dont want Conversely, manpages/docs are not tried to be built for users who dont want
to install all these dependencies to get started hacking on i3. to install all these dependencies to get started hacking on i3. Manpages and
docs can be disabled with the +--disable-mans++ and ++--disable-docs++
configure options respectively.
* non-release builds will enable address sanitizer by default. Use the * non-release builds will enable address sanitizer by default. Use the
--disable-sanitizers configure option to turn off all sanitizers, and see +--disable-sanitizers+ configure option to turn off all sanitizers, and see
--help for available sanitizers. +--help+ for available sanitizers.
* Support for pre-compiled headers (PCH) has been dropped for now in the * Coverage reports are now generated using +make check-code-coverage+, which
interest of simplicity. If you need support for PCH, please open an issue. requires specifying +--enable-code-coverage+ when calling configure.
* Coverage reports are now generated using “make check-code-coverage”, which == Pull requests
requires specifying --enable-code-coverage when calling configure.
== Using git / sending patches
For a short introduction into using git, see
https://web.archive.org/web/20121024222556/http://www.spheredev.org/wiki/Git_for_the_lazy
or, for more documentation, see https://git-scm.com/documentation
Please talk to us before working on new features to see whether they will be Please talk to us before working on new features to see whether they will be
accepted. A good way for this is to open an issue and asking for opinions on it. accepted. A good way for this is to open an issue and asking for opinions on it.
Even for accepted features, this can be a good way to refine an idea upfront. However, Even for accepted features, this can be a good way to refine an idea upfront.
we don't want to see certain features in i3, e.g., switching window focus in an However, we don't want to see certain features in i3, e.g., switching window
Alt+Tab like way. focus in an Alt+Tab like way.
When working on bugfixes, please make sure you mention that you are working on When working on bugfixes, please make sure you mention that you are working on it
it in the corresponding bug report at https://github.com/i3/i3/issues. In case in the corresponding bug report at https://github.com/i3/i3/issues. In case there
there is no bug report yet, please create one. is no bug report yet, please create one.
After you are done, please submit your work for review as a pull request at After you are done, please submit your work for review as a pull request at
https://github.com/i3/i3. https://github.com/i3/i3. In order to make your review go as fast as possible,
you could have a look at previous reviews and see what the common mistakes are.
Do not send emails to the mailing list or any author directly, and dont submit
them in the bugtracker, since all reviews should be done in public at
https://github.com/i3/i3. In order to make your review go as fast as possible, you
could have a look at previous reviews and see what the common mistakes are.
=== Which branch to use? === Which branch to use?
@ -82,9 +86,8 @@ repository).
The contents of “master” are always stable. That is, it contains the source code The contents of “master” are always stable. That is, it contains the source code
of the latest release, plus any bugfixes that were applied since that release. of the latest release, plus any bugfixes that were applied since that release.
New features are only found in the “next” branch. Therefore, if you are working New features are only found in the “next” branch. Always use this branch when
on a new feature, use the “next” branch. If you are working on a bugfix, use the writing new code (both bugfixes and features).
“next” branch, too, but make sure your code also works on “master”.
== Window Managers == Window Managers
@ -106,9 +109,9 @@ In the case of i3, the tasks (and order of them) are the following:
the first client of X) and manage them (reparent them, create window the first client of X) and manage them (reparent them, create window
decorations, etc.) decorations, etc.)
. When new windows are created, manage them . When new windows are created, manage them
. Handle the clients `_WM_STATE` property, but only `_WM_STATE_FULLSCREEN` and . Handle the clients +_WM_STATE+ property, but only +_WM_STATE_FULLSCREEN+ and
`_NET_WM_STATE_DEMANDS_ATTENTION` +_NET_WM_STATE_DEMANDS_ATTENTION+
. Handle the clients `WM_NAME` property . Handle the clients +WM_NAME+ property
. Handle the clients size hints to display them proportionally . Handle the clients size hints to display them proportionally
. Handle the clients urgency hint . Handle the clients urgency hint
. Handle enter notifications (focus follows mouse) . Handle enter notifications (focus follows mouse)
@ -123,11 +126,11 @@ will be discussed.
=== Tiling window managers === Tiling window managers
Traditionally, there are two approaches to managing windows: The most common Traditionally, there are two approaches to managing windows: The most common one
one nowadays is floating, which means the user can freely move/resize the nowadays is stacking (or floating, using i3's terminology), which means the user
windows. The other approach is called tiling, which means that your window can freely move/resize the windows, potentially overlapping them. The other
manager distributes windows to use as much space as possible while not approach is called tiling, which means that the window manager distributes
overlapping each other. windows to use as much space as possible while not overlapping each other.
The idea behind tiling is that you should not need to waste your time The idea behind tiling is that you should not need to waste your time
moving/resizing windows while you usually want to get some work done. After moving/resizing windows while you usually want to get some work done. After
@ -161,63 +164,67 @@ example.
== Files == Files
include/atoms.xmacro:: i3's source code is in the +src+ folder while header files reside in +include+.
A file containing all X11 atoms which i3 uses. This file will be included Other tools such as i3bar and i3-nagbar have their own folders. i3 and its tools
various times (for defining, requesting and receiving the atoms), each time share an internal library called ``libi3'' which also has its own folder.
with a different definition of xmacro().
The following list gives an overview of the codebase, explaining the
functionality of the most important, core source code files. Other files in the
tree that are not mentioned here implement specific functionalities: for example,
+src/scratchpad.c+ is obviously about the scratchpad functionality.
include/data.h:: include/data.h::
Contains data definitions used by nearly all files. You really need to read Contains data definitions used by nearly all files.
this first.
include/*.h:: include/*.h::
Contains forward definitions for all public functions, as well as Contains forward definitions for all public functions, as well as
doxygen-compatible comments (so if you want to get a bit more of the big doxygen-compatible comments (so if you want to get a bit more of the big
picture, either browse all header files or use doxygen if you prefer that). picture, either browse all header files or use doxygen if you prefer that).
src/config_parser.c:: src/config_directives.c::
Contains a custom configuration parser. See src/command_parser.c for rationale src/commands.c::
on why we use a custom parser. Contain the definitions for all high-level config and command directives. These
are excellent places to start with a top-to-bottom approach to understand
src/click.c:: specific i3 behavior. For example, if you want to investigate a bug that happens
Contains all functions which handle mouse button clicks (right mouse button for the +move to mark+ command, you can use gdb to pause in
clicks initiate resizing and thus are relatively complex). +cmd_move_con_to_mark+ and then work your way from there, stepping into
lower-level functions.
src/command_parser.c::
Contains a hand-written parser to parse commands (commands are what
you bind on keys and what you can send to i3 using the IPC interface, like
'move left' or 'workspace 4').
src/con.c:: src/con.c::
Contains all functions which deal with containers directly (creating Contains all functions which deal with containers directly (creating containers,
containers, searching containers, getting specific properties from containers, searching containers, getting specific properties from containers, …). Contains
…). abstractions and auxiliary functions necessary to work with the container
structure which is used in almost all parts of the codebase.
src/config.c:: src/tree.c::
Contains all functions handling the configuration file (calling the parser Contains functions which deal with the tree abstraction. However, be aware that
src/config_parser.c) with the correct path, switching key bindings mode). +src/con.c+ also contains functions that heavily interact with the tree
structure. Some functions that are included in +str/tree.c+ are those that handle
opening and closing containers in the tree, finding the container that should be
focused next and flattening the tree. See also +src/move.c+ for other
move-specific functions that interact with the tree, which were moved into their
own file because they are so long.
src/ewmh.c:: src/workspace.c::
Functions to get/set certain EWMH properties easily. Contains functions which deal with workspaces. Includes code that creates new
workspaces, shows existing ones and deals with workspace assignments.
src/floating.c::
Contains functions for floating mode (mostly resizing/dragging).
src/handlers.c:: src/handlers.c::
Contains all handlers for all kinds of X events (new window title, new hints, Contains all handlers for all kinds of X events (new window title, new hints,
unmapping, key presses, button presses, …). unmapping, key presses, button presses, …). This is a very important file to
understand how i3 interacts with changes to its environment.
src/ipc.c:: src/command_parser.c::
Contains code for the IPC interface. src/config_parser.c::
Contain a hand-written parser to parse commands and configuration (commands are what
you bind on keys and what you can send to i3 using the IPC interface, like
+move left+ or +workspace 4+). +src/config.c+ is responsible for calling the
configuration parser.
src/load_layout.c:: src/click.c::
Contains code for loading layouts from JSON files. src/resize.c::
Contain functions which handle mouse button clicks (right mouse button
src/log.c:: clicks initiate resizing and thus are relatively complex).
Contains the logging functions.
src/main.c::
Initializes the window manager.
src/manage.c:: src/manage.c::
Looks at existing or new windows and decides whether to manage them. If so, it Looks at existing or new windows and decides whether to manage them. If so, it
@ -226,93 +233,66 @@ reparents the window and inserts it into our data structures.
src/match.c:: src/match.c::
A "match" is a data structure which acts like a mask or expression to match A "match" is a data structure which acts like a mask or expression to match
certain windows or not. For example, when using commands, you can specify a certain windows or not. For example, when using commands, you can specify a
command like this: [title="*Firefox*"] kill. The title member of the match command like this: +[title="*Firefox*"] kill+. The title member of the match
data structure will then be filled and i3 will check each window using data structure will then be filled and i3 will check each window using
match_matches_window() to find the windows affected by this command. +match_matches_window()+ to find the windows affected by this command.
src/move.c::
Contains code to move a container in a specific direction.
src/output.c::
Functions to handle CT_OUTPUT cons.
src/randr.c:: src/randr.c::
The RandR API is used to get (and re-query) the configured outputs (monitors, The RandR API is used to get (and re-query) the configured outputs (monitors,
…). …). Legacy Xinerama support resides in +src/xinerama.c+.
src/render.c:: src/render.c::
Renders the tree data structure by assigning coordinates to every node. These Renders the tree data structure by assigning coordinates to every node. These
values will later be pushed to X11 in +src/x.c+. values will later be pushed to X11 in +src/x.c+.
src/resize.c::
Contains the functions to resize containers.
src/restore_layout.c::
Everything for restored containers that is not pure state parsing (which can be
found in load_layout.c).
src/sighandler.c:: src/sighandler.c::
Handles +SIGSEGV+, +SIGABRT+ and +SIGFPE+ by showing a dialog that i3 crashed. Handles +SIGSEGV+, +SIGABRT+ and +SIGFPE+ by showing a dialog that i3 crashed.
You can chose to let it dump core, to restart it in-place or to restart it You can choose to let it dump core and restart i3 in-place (either trying to
in-place but forget about the layout. preserve layout or forget about it).
src/tree.c::
Contains functions which open or close containers in the tree, change focus or
cleanup ("flatten") the tree. See also +src/move.c+ for another similar
function, which was moved into its own file because it is so long.
src/util.c::
Contains useful functions which are not really dependent on anything.
src/window.c:: src/window.c::
Handlers to update X11 window properties like +WM_CLASS+, +_NET_WM_NAME+, Handlers to update X11 window properties like +WM_CLASS+, +_NET_WM_NAME+,
+CLIENT_LEADER+, etc. +CLIENT_LEADER+, etc.
src/workspace.c:: include/atoms.xmacro::
Contains all functions related to workspaces (displaying, hiding, renaming…) A file containing all X11 atoms which i3 uses. This file will be included
various times (for defining, requesting and receiving the atoms), each time
src/x.c:: with a different definition of xmacro().
Transfers our in-memory tree (see +src/render.c+) to X11.
src/xcb.c::
Contains wrappers to use xcb more easily.
src/xcursor.c::
XCursor functions (for cursor themes).
src/xinerama.c::
Legacy support for Xinerama. See +src/randr.c+ for the preferred API.
[[data_structures]]
== Data structures == Data structures
See +include/data.h+ for documented data structures. The most important ones are
explained here.
See include/data.h for documented data structures. The most important ones are The following picture is generated by the +contrib/dump-asy.pl+ script.
explained right here.
///////////////////////////////////////////////////////////////////////////////// image:bigpicture.png["The Big Picture",width=1000,link="bigpicture.png"]
// TODO: update image
image:bigpicture.png[The Big Picture] The hierarchy is:
///////////////////////////////////////////////////////////////////////////////// . *Root container*
. *Output containers*: +eDP-1+ in this example and the internal +__i3++ output
So, the hierarchy is: . *Content and 2 dockarea containers*
. *Workspaces*: Numbered workspace ``1'' and a ``Named workspace''
. *X11 root window*, the root container . *Split containers*: One horizontal in the first workspace and a tabbed one in
. *Output container* (LVDS1 in this example) the named one.
. *Content container* (there are also containers for dock windows) . *Leaf containers*: Windows like vim and an i3bar dock.
. *Workspaces* (Workspace 1 in this example, with horizontal orientation)
. *Split container* (vertically split)
. *X11 window containers*
The data type is +Con+, in all cases. The data type is +Con+, in all cases.
=== X11 root window === Root container
The X11 root window is a single window per X11 display (a display is identified The root container (global variable +croot+) is the up-most ascendant of every i3
by +:0+ or +:1+ etc.). The root window is what you draw your background image container. It can be used to iterate over the whole tree structure. E.g., it is
on. It spans all the available outputs, e.g. +VGA1+ is a specific part of the used to reply to the +GET_WORKSPACES+ request, iterating over it's children to
root window and +LVDS1+ is a specific part of the root window. find all workspaces. This is different from the X11 root window.
The X11 root window (global variable +root+) is a single window per X11 display
(a display is identified by +:0+ or +:1+ etc.). The root window is what you draw
your background image on. It spans all the available outputs, e.g. +VGA1+ is a
specific part of the root window and +LVDS1+ is a specific part of the root
window.
=== Output container === Output container
@ -334,8 +314,8 @@ currently on.
=== Content container === Content container
Each output has multiple children. Two of them are dock containers which hold Each output has multiple children. Two of them are dock containers which hold
dock clients. The other one is the content container, which holds the actual the top and bottom dock clients. The other one is the content container, which
content (workspaces) of this output. holds the actual content (workspaces) of this output.
=== Workspace === Workspace
@ -354,21 +334,20 @@ vertical) and a layout.
Split containers (and X11 window containers, which are a subtype of split Split containers (and X11 window containers, which are a subtype of split
containers) can have different border styles. containers) can have different border styles.
=== X11 window container === Leaf containers
An X11 window container holds exactly one X11 window. These are the leaf nodes A leaf container holds exactly one X11 window. They can't have any children.
of the layout tree, they cannot have any children.
== List/queue macros == List/queue macros
i3 makes heavy use of the list macros defined in BSD operating systems. To i3 makes heavy use of the list macros defined in BSD operating systems. To
ensure that the operating system on which i3 is compiled has all the expected ensure that the operating system on which i3 is compiled has all the expected
features, i3 comes with `include/queue.h`. On BSD systems, you can use man features, i3 comes with +include/queue.h+. On BSD systems, you can use +man
`queue(3)`. On Linux, you have to use google (or read the source). queue(3)+. On Linux, you have to use google (or read the source).
The lists used are +SLIST+ (single linked lists), +CIRCLEQ+ (circular The lists used are +SLIST+ (single linked lists), +CIRCLEQ+ (circular
queues) and +TAILQ+ (tail queues). Usually, only forward traversal is necessary, queues) and +TAILQ+ (tail queues). Usually, only forward traversal is necessary,
so an `SLIST` works fine. If inserting elements at arbitrary positions or at so an +SLIST+ works fine. If inserting elements at arbitrary positions or at
the end of a list is necessary, a +TAILQ+ is used instead. However, for the the end of a list is necessary, a +TAILQ+ is used instead. However, for the
windows inside a container, a +CIRCLEQ+ is necessary to go from the currently windows inside a container, a +CIRCLEQ+ is necessary to go from the currently
selected window to the window above/below. selected window to the window above/below.
@ -378,10 +357,10 @@ selected window to the window above/below.
There is a row of standard variables used in many events. The following names There is a row of standard variables used in many events. The following names
should be chosen for those: should be chosen for those:
* ``conn'' is the xcb_connection_t * +conn+ is the xcb_connection_t
* ``event'' is the event of the particular type * +event+ is the event of the particular type
* ``con'' names a container * +con+ names a container
* ``current'' is a loop variable when using +TAILQ_FOREACH+ etc. * +current+ is a loop variable when using +TAILQ_FOREACH+ etc.
== Startup (src/mainx.c, main()) == Startup (src/mainx.c, main())
@ -430,7 +409,7 @@ The bound command is parsed by the cmdparse lexer/parser, see +parse_cmd+ in
== Manage windows (src/main.c, manage_window() and reparent_window()) == Manage windows (src/main.c, manage_window() and reparent_window())
`manage_window()` does some checks to decide whether the window should be +manage_window()+ does some checks to decide whether the window should be
managed at all: managed at all:
* Windows have to be mapped, that is, visible on screen * Windows have to be mapped, that is, visible on screen
@ -438,18 +417,18 @@ managed at all:
not be managed by a window manager not be managed by a window manager
Afterwards, i3 gets the initial geometry and reparents the window (see Afterwards, i3 gets the initial geometry and reparents the window (see
`reparent_window()`) if it wasnt already managed. +reparent_window()+) if it wasnt already managed.
Reparenting means that for each window which is reparented, a new window, Reparenting means that for each window which is reparented, a new window,
slightly larger than the original one, is created. The original window is then slightly larger than the original one, is created. The original window is then
reparented to the bigger one (called "frame"). reparented to the bigger one (called "frame").
After reparenting, the window type (`_NET_WM_WINDOW_TYPE`) is checked to see After reparenting, the window type (+_NET_WM_WINDOW_TYPE+) is checked to see
whether this window is a dock (`_NET_WM_WINDOW_TYPE_DOCK`), like dzen2 for whether this window is a dock (+_NET_WM_WINDOW_TYPE_DOCK+), like dzen2 for
example. Docks are handled differently, they dont have decorations and are not example. Docks are handled differently, they dont have decorations and are not
assigned to a specific container. Instead, they are positioned at the bottom assigned to a specific container. Instead, they are positioned at the bottom
or top of the screen (in the appropriate dock area containers). To get the or top of the screen (in the appropriate dock area containers). To get the
height which needs to be reserved for the window, the `_NET_WM_STRUT_PARTIAL` height which needs to be reserved for the window, the +_NET_WM_STRUT_PARTIAL+
property is used. property is used.
Furthermore, the list of assignments (to other workspaces, which may be on Furthermore, the list of assignments (to other workspaces, which may be on
@ -460,10 +439,10 @@ target workspace is not visible, the window will not be mapped.
== What happens when an application is started? == What happens when an application is started?
i3 does not care about applications. All it notices is when new windows are i3 does not care about applications. All it notices is when new windows are
mapped (see `src/handlers.c`, `handle_map_request()`). The window is then mapped (see +src/handlers.c+, +handle_map_request()+). The window is then
reparented (see section "Manage windows"). reparented (see section "Manage windows").
After reparenting the window, `render_tree()` is called which renders the After reparenting the window, +render_tree()+ is called which renders the
internal layout table. The new window has been placed in the currently focused internal layout table. The new window has been placed in the currently focused
container and therefore the new window and the old windows (if any) need to be container and therefore the new window and the old windows (if any) need to be
moved/resized so that the currently active layout (default/stacking/tabbed mode) moved/resized so that the currently active layout (default/stacking/tabbed mode)
@ -482,7 +461,7 @@ can reconfigure themselves).
Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms
are handled. are handled.
The former calls ``toggle_fullscreen()'' for the specific client which just The former calls +toggle_fullscreen()+ for the specific client which just
configures the client to use the whole screen on which it currently is. configures the client to use the whole screen on which it currently is.
Also, it is set as fullscreen_client for the i3Screen. Also, it is set as fullscreen_client for the i3Screen.
@ -539,7 +518,7 @@ container) to the bottom.
=== Rendering the root container === Rendering the root container
The i3 root container (`con->type == CT_ROOT`) represents the X11 root window. The i3 root container (+con->type == CT_ROOT+) represents the X11 root window.
It contains one child container for every output (like LVDS1, VGA1, …), which It contains one child container for every output (like LVDS1, VGA1, …), which
is available on your computer. is available on your computer.
@ -558,7 +537,7 @@ only called for the global fullscreen window.
=== Rendering an output === Rendering an output
Output containers (`con->layout == L_OUTPUT`) represent a hardware output like Output containers (+con->layout == L_OUTPUT+) represent a hardware output like
LVDS1, VGA1, etc. An output container has three children (at the moment): One LVDS1, VGA1, etc. An output container has three children (at the moment): One
content container (having workspaces as children) and the top/bottom dock area content container (having workspaces as children) and the top/bottom dock area
containers. containers.
@ -566,7 +545,7 @@ containers.
The rendering happens in the function +render_l_output()+ in the following The rendering happens in the function +render_l_output()+ in the following
steps: steps:
1. Find the content container (`con->type == CT_CON`) 1. Find the content container (+con->type == CT_CON+)
2. Get the currently visible workspace (+con_get_fullscreen_con(content, 2. Get the currently visible workspace (+con_get_fullscreen_con(content,
CF_OUTPUT)+). CF_OUTPUT)+).
3. If there is a fullscreened window on that workspace, directly render it and 3. If there is a fullscreened window on that workspace, directly render it and
@ -574,22 +553,22 @@ steps:
4. Sum up the space used by all the dock windows (they have a variable height 4. Sum up the space used by all the dock windows (they have a variable height
only). only).
5. Set the workspace rects (x/y/width/height) based on the position of the 5. Set the workspace rects (x/y/width/height) based on the position of the
output (stored in `con->rect`) and the usable space output (stored in +con->rect+) and the usable space
(`con->rect.{width,height}` without the space used for dock windows). (+con->rect.{width,height}+ without the space used for dock windows).
6. Recursively raise and render the outputs child containers (meaning dock 6. Recursively raise and render the outputs child containers (meaning dock
area containers and the content container). area containers and the content container).
=== Rendering a workspace or split container === Rendering a workspace or split container
From here on, there really is no difference anymore. All containers are of From here on, there really is no difference anymore. All containers are of
`con->type == CT_CON` (whether workspace or split container) and some of them +con->type == CT_CON+ (whether workspace or split container) and some of them
have a `con->window`, meaning they represent an actual window instead of a have a +con->window+, meaning they represent an actual window instead of a
split container. split container.
==== Default layout ==== Default layout
In default layout, containers are placed horizontally or vertically next to In default layout, containers are placed horizontally or vertically next to
each other (depending on the `con->orientation`). If a child is a leaf node (as each other (depending on the +con->orientation+). If a child is a leaf node (as
opposed to a split container) and has border style "normal", appropriate space opposed to a split container) and has border style "normal", appropriate space
will be reserved for its window decoration. will be reserved for its window decoration.
@ -835,8 +814,8 @@ workspace <direction>::
the beginning. + the beginning. +
NOTE: Note that you can specify multiple literals in the same line. This has NOTE: Note that you can specify multiple literals in the same line. This has
exactly the same effect as if you specified `direction = exactly the same effect as if you specified +direction =
'next_on_output' -> call cmd_workspace($direction)` and so forth. + 'next_on_output' -> call cmd_workspace($direction)+ and so forth. +
NOTE: Also note that the order of literals is important here: If 'next' were NOTE: Also note that the order of literals is important here: If 'next' were
ordered before 'next_on_output', then 'next_on_output' would never ordered before 'next_on_output', then 'next_on_output' would never
@ -1020,11 +999,11 @@ Without much ado, here is the list of cases which need to be considered:
== Gotchas == Gotchas
* Forgetting to call `xcb_flush(conn);` after sending a request. This usually * Forgetting to call +xcb_flush(conn);+ after sending a request. This usually
leads to code which looks like it works fine but which does not work under leads to code which looks like it works fine but which does not work under
certain conditions. certain conditions.
* Forgetting to call `floating_fix_coordinates(con, old_rect, new_rect)` after * Forgetting to call +floating_fix_coordinates(con, old_rect, new_rect)+ after
moving workspaces across outputs. Coordinates for floating containers are moving workspaces across outputs. Coordinates for floating containers are
not relative to workspace boundaries, so you must correct their coordinates not relative to workspace boundaries, so you must correct their coordinates
or those containers will show up in the wrong workspace or not at all. or those containers will show up in the wrong workspace or not at all.