]> git.sur5r.net Git - i3/i3.github.io/blobdiff - docs/4.0/hacking-howto.html
add (versioned) docs for 4.0
[i3/i3.github.io] / docs / 4.0 / hacking-howto.html
diff --git a/docs/4.0/hacking-howto.html b/docs/4.0/hacking-howto.html
new file mode 100644 (file)
index 0000000..382b5c3
--- /dev/null
@@ -0,0 +1,1046 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"\r
+    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\r
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\r
+<head>\r
+<link rel="icon" type="image/png" href="/favicon.png">\r
+<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />\r
+<meta name="generator" content="AsciiDoc 8.6.4" />\r
+<title>i3: Hacking i3: How To</title>\r
+<link rel="stylesheet" href="/css/style.css" type="text/css" />\r
+<link rel="stylesheet" href="/css/xhtml11.css" type="text/css" />\r
+<script type="text/javascript">\r
+/*<![CDATA[*/\r
+window.onload = function(){asciidoc.footnotes(); asciidoc.toc(2);}\r
+/*]]>*/\r
+</script>\r
+<script type="text/javascript" src="/js/asciidoc-xhtml11.js"></script>\r
+</head>\r
+<body class="article">\r
+\r
+        <div id="main">\r
+            <a href="/"><h1 id="title">i3 - improved tiling WM</h1></a>\r
+                        <ul id="nav">\r
+                                <li><a style="border-bottom: 2px solid #fff" href="/docs">Docs</a></li>\r
+                                <li><a href="/screenshots">Screens</a></li>\r
+                                <li><a href="/contact">Contact</a></li>\r
+                                <li><a href="http://bugs.i3wm.org/">Bugs</a></li>\r
+                        </ul>\r
+        <br style="clear: both">\r
+<div id="content">\r
+<div id="header">\r
+<h1>Hacking i3: How To</h1>\r
+<span id="author">Michael Stapelberg</span><br />\r
+<span id="email"><tt>&lt;<a href="mailto:michael+i3@stapelberg.de">michael+i3@stapelberg.de</a>&gt;</tt></span><br />\r
+<span id="revdate">July 2011</span>\r
+<div id="toc">
+  <div id="toctitle">Table of Contents</div>
+  <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
+</div>\r
+</div>\r
+<div id="preamble">\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>This document is intended to be the first thing you read before looking and/or\r
+touching i3’s source code. It should contain all important information to help\r
+you understand why things are like they are. If it does not mention something\r
+you find necessary, please do not hesitate to contact me.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_window_managers">1. Window Managers</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>A window manager is not necessarily needed to run X, but it is usually used in\r
+combination with X to facilitate some things. The window manager&#8217;s job is to\r
+take care of the placement of windows, to provide the user with some mechanisms\r
+to change the position/size of windows and to communicate with clients to a\r
+certain extent (for example handle fullscreen requests of clients such as\r
+MPlayer).</p></div>\r
+<div class="paragraph"><p>There are no different contexts in which X11 clients run, so a window manager\r
+is just another client, like all other X11 applications. However, it handles\r
+some events which normal clients usually don’t handle.</p></div>\r
+<div class="paragraph"><p>In the case of i3, the tasks (and order of them) are the following:</p></div>\r
+<div class="olist arabic"><ol class="arabic">\r
+<li>\r
+<p>\r
+Grab the key bindings (events will be sent upon keypress/keyrelease)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Iterate through all existing windows (if the window manager is not started as\r
+  the first client of X) and manage them (reparent them, create window\r
+  decorations, etc.)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+When new windows are created, manage them\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Handle the client’s <tt>_WM_STATE</tt> property, but only the <tt>_WM_STATE_FULLSCREEN</tt>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Handle the client’s <tt>WM_NAME</tt> property\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Handle the client’s size hints to display them proportionally\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Handle the client’s urgency hint\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Handle enter notifications (focus follows mouse)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Handle button (as in mouse buttons) presses for focus/raise on click\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Handle expose events to re-draw own windows such as decorations\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+React to the user’s commands: Change focus, Move windows, Switch workspaces,\r
+  Change the layout mode of a container (default/stacking/tabbed), start a new\r
+  application, restart the window manager\r
+</p>\r
+</li>\r
+</ol></div>\r
+<div class="paragraph"><p>In the following chapters, each of these tasks and their implementation details\r
+will be discussed.</p></div>\r
+<div class="sect2">\r
+<h3 id="_tiling_window_managers">1.1. Tiling window managers</h3>\r
+<div class="paragraph"><p>Traditionally, there are two approaches to managing windows: The most common\r
+one nowadays is floating, which means the user can freely move/resize the\r
+windows. The other approach is called tiling, which means that your window\r
+manager distributes windows to use as much space as possible while not\r
+overlapping each other.</p></div>\r
+<div class="paragraph"><p>The idea behind tiling is that you should not need to waste your time\r
+moving/resizing windows while you usually want to get some work done. After\r
+all, most users sooner or later tend to lay out their windows in a way which\r
+corresponds to tiling or stacking mode in i3. Therefore, why not let i3 do this\r
+for you? Certainly, it’s faster than you could ever do it.</p></div>\r
+<div class="paragraph"><p>The problem with most tiling window managers is that they are too unflexible.\r
+In my opinion, a window manager is just another tool, and similar to vim which\r
+can edit all kinds of text files (like source code, HTML, …) and is not limited\r
+to a specific file type, a window manager should not limit itself to a certain\r
+layout (like dwm, awesome, …) but provide mechanisms for you to easily create\r
+the layout you need at the moment.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_the_layout_table">1.2. The layout table</h3>\r
+<div class="sidebarblock">\r
+<div class="content">\r
+<div class="paragraph"><p>This section has not been updated for v4.0 yet, sorry! We wanted to release on\r
+time, but we will update this soon. Please talk to us on IRC if you need to\r
+know stuff <strong>NOW</strong> :).</p></div>\r
+</div></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_files">2. Files</h2>\r
+<div class="sectionbody">\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+include/atoms.xmacro\r
+</dt>\r
+<dd>\r
+<p>\r
+A file containing all X11 atoms which i3 uses. This file will be included\r
+various times (for defining, requesting and receiving the atoms), each time\r
+with a different definition of xmacro().\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+include/data.h\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains data definitions used by nearly all files. You really need to read\r
+this first.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+include/*.h\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains forward definitions for all public functions, as well as\r
+doxygen-compatible comments (so if you want to get a bit more of the big\r
+picture, either browse all header files or use doxygen if you prefer that).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/cfgparse.l\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains the lexer for i3’s configuration file, written for <tt>flex(1)</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/cfgparse.y\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains the parser for i3’s configuration file, written for <tt>bison(1)</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/click.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains all functions which handle mouse button clicks (right mouse button\r
+clicks initiate resizing and thus are relatively complex).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/cmdparse.l\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains the lexer for i3 commands, written for <tt>flex(1)</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/cmdparse.y\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains the parser for i3 commands, written for <tt>bison(1)</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/con.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains all functions which deal with containers directly (creating\r
+containers, searching containers, getting specific properties from containers,\r
+…).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/config.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains all functions handling the configuration file (calling the parser\r
+(src/cfgparse.y) with the correct path, switching key bindings mode).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/debug.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains debugging functions to print unhandled X events.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/ewmh.c\r
+</dt>\r
+<dd>\r
+<p>\r
+iFunctions to get/set certain EWMH properties easily.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/floating.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains functions for floating mode (mostly resizing/dragging).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/handlers.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains all handlers for all kinds of X events (new window title, new hints,\r
+unmapping, key presses, button presses, …).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/ipc.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains code for the IPC interface.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/load_layout.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains code for loading layouts from JSON files.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/log.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Handles the setting of loglevels, contains the logging functions.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/main.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Initializes the window manager.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/manage.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Looks at existing or new windows and decides whether to manage them. If so, it\r
+reparents the window and inserts it into our data structures.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/match.c\r
+</dt>\r
+<dd>\r
+<p>\r
+A "match" is a data structure which acts like a mask or expression to match\r
+certain windows or not. For example, when using commands, you can specify a\r
+command like this: [title="<strong>Firefox</strong>"] kill. The title member of the match\r
+data structure will then be filled and i3 will check each window using\r
+match_matches_window() to find the windows affected by this command.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/move.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains code to move a container in a specific direction.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/output.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Functions to handle CT_OUTPUT cons.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/randr.c\r
+</dt>\r
+<dd>\r
+<p>\r
+The RandR API is used to get (and re-query) the configured outputs (monitors,\r
+…).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/render.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Renders the tree data structure by assigning coordinates to every node. These\r
+values will later be pushed to X11 in <tt>src/x.c</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/resize.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains the functions to resize containers.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/sighandler.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Handles <tt>SIGSEGV</tt>, <tt>SIGABRT</tt> and <tt>SIGFPE</tt> by showing a dialog that i3 crashed.\r
+You can chose to let it dump core, to restart it in-place or to restart it\r
+in-place but forget about the layout.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/tree.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains functions which open or close containers in the tree, change focus or\r
+cleanup ("flatten") the tree. See also <tt>src/move.c</tt> for another similar\r
+function, which was moved into its own file because it is so long.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/util.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains useful functions which are not really dependant on anything.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/window.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Handlers to update X11 window properties like <tt>WM_CLASS</tt>, <tt>_NET_WM_NAME</tt>,\r
+<tt>CLIENT_LEADER</tt>, etc.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/workspace.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains all functions related to workspaces (displaying, hiding, renaming…)\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/x.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Transfers our in-memory tree (see <tt>src/render.c</tt>) to X11.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/xcb.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Contains wrappers to use xcb more easily.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/xcursor.c\r
+</dt>\r
+<dd>\r
+<p>\r
+XCursor functions (for cursor themes).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+src/xinerama.c\r
+</dt>\r
+<dd>\r
+<p>\r
+Legacy support for Xinerama. See <tt>src/randr.c</tt> for the preferred API.\r
+</p>\r
+</dd>\r
+</dl></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_data_structures">3. Data structures</h2>\r
+<div class="sectionbody">\r
+<div class="sidebarblock">\r
+<div class="content">\r
+<div class="paragraph"><p>This section has not been updated for v4.0 yet, sorry! We wanted to release on\r
+time, but we will update this soon. Please talk to us on IRC if you need to\r
+know stuff <strong>NOW</strong> :).</p></div>\r
+</div></div>\r
+<div class="paragraph"><p>So, the hierarchy is:</p></div>\r
+<div class="olist arabic"><ol class="arabic">\r
+<li>\r
+<p>\r
+<strong>X11 root window</strong>, the root container\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<strong>Virtual screens</strong> (Screen 0 in this example)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<strong>Content container</strong> (there are also containers for dock windows)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<strong>Workspaces</strong> (Workspace 1 in this example, with horizontal orientation)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<strong>Split container</strong> (vertically split)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<strong>X11 window containers</strong>\r
+</p>\r
+</li>\r
+</ol></div>\r
+<div class="paragraph"><p>The data type is <tt>Con</tt>, in all cases.</p></div>\r
+<div class="sect2">\r
+<h3 id="_virtual_screens">3.1. Virtual screens</h3>\r
+<div class="paragraph"><p>A virtual screen (type <tt>i3Screen</tt>) is generated from the connected outputs\r
+obtained through RandR. The difference to the raw RandR outputs as seen\r
+when using <tt>xrandr(1)</tt> is that it falls back to the lowest common resolution of\r
+the actual enabled outputs.</p></div>\r
+<div class="paragraph"><p>For example, if your notebook has a screen resolution of 1280x800 px and you\r
+connect a video projector with a resolution of 1024x768 px, set it up in clone\r
+mode (<tt>xrandr --output VGA1 --mode 1024x768 --same-as LVDS1</tt>), i3 will have\r
+one virtual screen.</p></div>\r
+<div class="paragraph"><p>However, if you configure it using <tt>xrandr --output VGA1 --mode 1024x768\r
+--right-of LVDS1</tt>, i3 will generate two virtual screens. For each virtual\r
+screen, a new workspace will be assigned. New workspaces are created on the\r
+screen you are currently on.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_workspace">3.2. Workspace</h3>\r
+<div class="paragraph"><p>A workspace is identified by its name. Basically, you could think of\r
+workspaces as different desks in your office, if you like the desktop\r
+methaphor. They just contain different sets of windows and are completely\r
+separate of each other. Other window managers also call this &#8220;Virtual\r
+desktops&#8221;.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_the_layout_table_2">3.3. The layout table</h3>\r
+<div class="sidebarblock">\r
+<div class="content">\r
+<div class="paragraph"><p>This section has not been updated for v4.0 yet, sorry! We wanted to release on\r
+time, but we will update this soon. Please talk to us on IRC if you need to\r
+know stuff <strong>NOW</strong> :).</p></div>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_container">3.4. Container</h3>\r
+<div class="sidebarblock">\r
+<div class="content">\r
+<div class="paragraph"><p>This section has not been updated for v4.0 yet, sorry! We wanted to release on\r
+time, but we will update this soon. Please talk to us on IRC if you need to\r
+know stuff <strong>NOW</strong> :).</p></div>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_client">3.5. Client</h3>\r
+<div class="paragraph"><p>A client is x11-speak for a window.</p></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_list_queue_macros">4. List/queue macros</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>i3 makes heavy use of the list macros defined in BSD operating systems. To\r
+ensure that the operating system on which i3 is compiled has all the expected\r
+features, i3 comes with <tt>include/queue.h</tt>. On BSD systems, you can use man\r
+<tt>queue(3)</tt>. On Linux, you have to use google (or read the source).</p></div>\r
+<div class="paragraph"><p>The lists used are <tt>SLIST</tt> (single linked lists), <tt>CIRCLEQ</tt> (circular\r
+queues) and <tt>TAILQ</tt> (tail queues). Usually, only forward traversal is necessary,\r
+so an <tt>SLIST</tt> works fine. If inserting elements at arbitrary positions or at\r
+the end of a list is necessary, a <tt>TAILQ</tt> is used instead. However, for the\r
+windows inside a container, a <tt>CIRCLEQ</tt> is necessary to go from the currently\r
+selected window to the window above/below.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_naming_conventions">5. Naming conventions</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>There is a row of standard variables used in many events. The following names\r
+should be chosen for those:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+&#8220;conn&#8221; is the xcb_connection_t\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+&#8220;event&#8221; is the event of the particular type\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+&#8220;con&#8221; names a container\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+&#8220;current&#8221; is a loop variable when using <tt>TAILQ_FOREACH</tt> etc.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_startup_src_mainx_c_main">6. Startup (src/mainx.c, main())</h2>\r
+<div class="sectionbody">\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Establish the xcb connection\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Check for XKB extension on the separate X connection, load Xcursor\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Check for RandR screens (with a fall-back to Xinerama)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Grab the keycodes for which bindings exist\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Manage all existing windows\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+Enter the event loop\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_keybindings">7. Keybindings</h2>\r
+<div class="sectionbody">\r
+<div class="sect2">\r
+<h3 id="_grabbing_the_bindings">7.1. Grabbing the bindings</h3>\r
+<div class="paragraph"><p>Grabbing the bindings is quite straight-forward. You pass X your combination of\r
+modifiers and the keycode you want to grab and whether you want to grab them\r
+actively or passively. Most bindings (everything except for bindings using\r
+Mode_switch) are grabbed passively, that is, just the window manager gets the\r
+event and cannot replay it.</p></div>\r
+<div class="paragraph"><p>We need to grab bindings that use Mode_switch actively because of a bug in X.\r
+When the window manager receives the keypress/keyrelease event for an actively\r
+grabbed keycode, it has to decide what to do with this event: It can either\r
+replay it so that other applications get it or it can prevent other\r
+applications from receiving it.</p></div>\r
+<div class="paragraph"><p>So, why do we need to grab keycodes actively? Because X does not set the\r
+state-property of keypress/keyrelease events properly. The Mode_switch bit is\r
+not set and we need to get it using XkbGetState. This means we cannot pass X\r
+our combination of modifiers containing Mode_switch when grabbing the key and\r
+therefore need to grab the keycode itself without any modifiers. This means,\r
+if you bind Mode_switch + keycode 38 ("a"), i3 will grab keycode 38 ("a") and\r
+check on each press of "a" if the Mode_switch bit is set using XKB. If yes, it\r
+will handle the event, if not, it will replay the event.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_handling_a_keypress">7.2. Handling a keypress</h3>\r
+<div class="paragraph"><p>As mentioned in "Grabbing the bindings", upon a keypress event, i3 first gets\r
+the correct state.</p></div>\r
+<div class="paragraph"><p>Then, it looks through all bindings and gets the one which matches the received\r
+event.</p></div>\r
+<div class="paragraph"><p>The bound command is parsed by the cmdparse lexer/parser, see <tt>parse_cmd</tt> in\r
+<tt>src/cmdparse.y</tt>.</p></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_manage_windows_src_main_c_manage_window_and_reparent_window">8. Manage windows (src/main.c, manage_window() and reparent_window())</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p><tt>manage_window()</tt> does some checks to decide whether the window should be\r
+managed at all:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Windows have to be mapped, that is, visible on screen\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+The override_redirect must not be set. Windows with override_redirect shall\r
+   not be managed by a window manager\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p>Afterwards, i3 gets the intial geometry and reparents the window (see\r
+<tt>reparent_window()</tt>) if it wasn’t already managed.</p></div>\r
+<div class="paragraph"><p>Reparenting means that for each window which is reparented, a new window,\r
+slightly larger than the original one, is created. The original window is then\r
+reparented to the bigger one (called "frame").</p></div>\r
+<div class="paragraph"><p>After reparenting, the window type (<tt>_NET_WM_WINDOW_TYPE</tt>) is checked to see\r
+whether this window is a dock (<tt>_NET_WM_WINDOW_TYPE_DOCK</tt>), like dzen2 for\r
+example. Docks are handled differently, they don’t have decorations and are not\r
+assigned to a specific container. Instead, they are positioned at the bottom\r
+of the screen. To get the height which needs to be reserved for the window,\r
+the <tt>_NET_WM_STRUT_PARTIAL</tt> property is used.</p></div>\r
+<div class="paragraph"><p>Furthermore, the list of assignments (to other workspaces, which may be on\r
+other screens) is checked. If the window matches one of the user’s criteria,\r
+it may either be put in floating mode or moved to a different workspace. If the\r
+target workspace is not visible, the window will not be mapped.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_what_happens_when_an_application_is_started">9. What happens when an application is started?</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>i3 does not care for applications. All it notices is when new windows are\r
+mapped (see <tt>src/handlers.c</tt>, <tt>handle_map_request()</tt>). The window is then\r
+reparented (see section "Manage windows").</p></div>\r
+<div class="paragraph"><p>After reparenting the window, <tt>render_tree()</tt> is called which renders the\r
+internal layout table. The new window has been placed in the currently focused\r
+container and therefore the new window and the old windows (if any) need to be\r
+moved/resized so that the currently active layout (default/stacking/tabbed mode)\r
+is rendered correctly. To move/resize windows, a window is &#8220;configured&#8221; in\r
+X11-speak.</p></div>\r
+<div class="paragraph"><p>Some applications, such as MPlayer obviously assume the window manager is\r
+stupid and try to configure their windows by themselves. This generates an\r
+event called configurerequest. i3 handles these events and tells the window the\r
+size it had before the configurerequest (with the exception of not yet mapped\r
+windows, which get configured like they want to, and floating windows, which\r
+can reconfigure themselves).</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_net_wm_state">10. _NET_WM_STATE</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Only the _NET_WM_STATE_FULLSCREEN atom is handled. It calls\r
+&#8220;toggle_fullscreen()&#8221; for the specific client which just configures the\r
+client to use the whole screen on which it currently is. Also, it is set as\r
+fullscreen_client for the i3Screen.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_wm_name">11. WM_NAME</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>When the WM_NAME property of a window changes, its decoration (containing the\r
+title) is re-rendered. Note that WM_NAME is in COMPOUND_TEXT encoding which is\r
+totally uncommon and cumbersome. Therefore, the _NET_WM_NAME atom will be used\r
+if present.</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_net_wm_name">12. _NET_WM_NAME</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Like WM_NAME, this atom contains the title of a window. However, _NET_WM_NAME\r
+is encoded in UTF-8. i3 will recode it to UCS-2 in order to be able to pass it\r
+to X. Using an appropriate font (ISO-10646), you can see most special\r
+characters (every special character contained in your font).</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_size_hints">13. Size hints</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Size hints specify the minimum/maximum size for a given window as well as its\r
+aspect ratio.  This is important for clients like mplayer, who only set the\r
+aspect ratio and resize their window to be as small as possible (but only with\r
+some video outputs, for example in Xv, while when using x11, mplayer does the\r
+necessary centering for itself).</p></div>\r
+<div class="paragraph"><p>So, when an aspect ratio was specified, i3 adjusts the height of the window\r
+until the size maintains the correct aspect ratio. For the code to do this, see\r
+src/layout.c, function resize_client().</p></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_rendering_src_layout_c_render_layout_and_render_container">14. Rendering (src/layout.c, render_layout() and render_container())</h2>\r
+<div class="sectionbody">\r
+<div class="sidebarblock">\r
+<div class="content">\r
+<div class="paragraph"><p>This section has not been updated for v4.0 yet, sorry! We wanted to release on\r
+time, but we will update this soon. Please talk to us on IRC if you need to\r
+know stuff <strong>NOW</strong> :).</p></div>\r
+</div></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_user_commands_commandmode_src_cmdparse_l_y">15. User commands / commandmode (src/cmdparse.{l,y})</h2>\r
+<div class="sectionbody">\r
+<div class="sidebarblock">\r
+<div class="content">\r
+<div class="paragraph"><p>This section has not been updated for v4.0 yet, sorry! We wanted to release on\r
+time, but we will update this soon. Please talk to us on IRC if you need to\r
+know stuff <strong>NOW</strong> :).</p></div>\r
+</div></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_moving_containers">16. Moving containers</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>The movement code is pretty delicate. You need to consider all cases before\r
+making any changes or before being able to fully understand how it works.</p></div>\r
+<div class="sect2">\r
+<h3 id="_case_1_moving_inside_the_same_container">16.1. Case 1: Moving inside the same container</h3>\r
+<div class="paragraph"><p>The reference layout for this case is a single workspace in horizontal\r
+orientation with two containers on it. Focus is on the left container (1).</p></div>\r
+<div class="tableblock">\r
+<table rules="all"\r
+width="15%"\r
+frame="border"\r
+cellspacing="0" cellpadding="4">\r
+<col width="50%" />\r
+<col width="50%" />\r
+<tbody>\r
+<tr>\r
+<td align="center" valign="top"><p class="table">1</p></td>\r
+<td align="center" valign="top"><p class="table">2</p></td>\r
+</tr>\r
+</tbody>\r
+</table>\r
+</div>\r
+<div class="paragraph"><p>When moving the left window to the right (command <tt>move right</tt>), tree_move will\r
+look for a container with horizontal orientation and finds the parent of the\r
+left container, that is, the workspace. Afterwards, it runs the code branch\r
+commented with "the easy case": it calls TAILQ_NEXT to get the container right\r
+of the current one and swaps both containers.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_case_2_move_a_container_into_a_split_container">16.2. Case 2: Move a container into a split container</h3>\r
+<div class="paragraph"><p>The reference layout for this case is a horizontal workspace with two\r
+containers. The right container is a v-split with two containers. Focus is on\r
+the left container (1).</p></div>\r
+<div class="tableblock">\r
+<table rules="all"\r
+width="15%"\r
+frame="border"\r
+cellspacing="0" cellpadding="4">\r
+<col width="50%" />\r
+<col width="50%" />\r
+<tbody>\r
+<tr>\r
+<td rowspan="2" align="center" valign="middle"><p class="table">1</p></td>\r
+<td align="center" valign="top"><p class="table">2</p></td>\r
+</tr>\r
+<tr>\r
+<td align="center" valign="top"><p class="table">3</p></td>\r
+</tr>\r
+</tbody>\r
+</table>\r
+</div>\r
+<div class="paragraph"><p>When moving to the right (command <tt>move right</tt>), i3 will work like in case 1\r
+("the easy case"). However, as the right container is not a leaf container, but\r
+a v-split, the left container (1) will be inserted at the right position (below\r
+2, assuming that 2 is focused inside the v-split) by calling <tt>insert_con_into</tt>.</p></div>\r
+<div class="paragraph"><p><tt>insert_con_into</tt> detaches the container from its parent and inserts it\r
+before/after the given target container. Afterwards, the on_remove_child\r
+callback is called on the old parent container which will then be closed, if\r
+empty.</p></div>\r
+<div class="paragraph"><p>Afterwards, <tt>con_focus</tt> will be called to fix the focus stack and the tree will\r
+be flattened.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_case_3_moving_to_non_existant_top_bottom">16.3. Case 3: Moving to non-existant top/bottom</h3>\r
+<div class="paragraph"><p>Like in case 1, the reference layout for this case is a single workspace in\r
+horizontal orientation with two containers on it. Focus is on the left\r
+container:</p></div>\r
+<div class="tableblock">\r
+<table rules="all"\r
+width="15%"\r
+frame="border"\r
+cellspacing="0" cellpadding="4">\r
+<col width="50%" />\r
+<col width="50%" />\r
+<tbody>\r
+<tr>\r
+<td align="center" valign="top"><p class="table">1</p></td>\r
+<td align="center" valign="top"><p class="table">2</p></td>\r
+</tr>\r
+</tbody>\r
+</table>\r
+</div>\r
+<div class="paragraph"><p>This time however, the command is <tt>move up</tt> or <tt>move down</tt>. tree_move will look\r
+for a container with vertical orientation. As it will not find any,\r
+<tt>same_orientation</tt> is NULL and therefore i3 will perform a forced orientation\r
+change on the workspace by creating a new h-split container, moving the\r
+workspace contents into it and then changing the workspace orientation to\r
+vertical. Now it will again search for parent containers with vertical\r
+orientation and it will find the workspace.</p></div>\r
+<div class="paragraph"><p>This time, the easy case code path will not be run as we are not moving inside\r
+the same container. Instead, <tt>insert_con_into</tt> will be called with the focused\r
+container and the container above/below the current one (on the level of\r
+<tt>same_orientation</tt>).</p></div>\r
+<div class="paragraph"><p>Now, <tt>con_focus</tt> will be called to fix the focus stack and the tree will be\r
+flattened.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_case_4_moving_to_existant_top_bottom">16.4. Case 4: Moving to existant top/bottom</h3>\r
+<div class="paragraph"><p>The reference layout for this case is a vertical workspace with two containers.\r
+The bottom one is a h-split containing two containers (1 and 2). Focus is on\r
+the bottom left container (1).</p></div>\r
+<div class="tableblock">\r
+<table rules="all"\r
+width="15%"\r
+frame="border"\r
+cellspacing="0" cellpadding="4">\r
+<col width="50%" />\r
+<col width="50%" />\r
+<tbody>\r
+<tr>\r
+<td colspan="2" align="center" valign="top"><p class="table">3</p></td>\r
+</tr>\r
+<tr>\r
+<td align="center" valign="top"><p class="table">1</p></td>\r
+<td align="center" valign="top"><p class="table">2</p></td>\r
+</tr>\r
+</tbody>\r
+</table>\r
+</div>\r
+<div class="paragraph"><p>This case is very much like case 3, only this time the forced workspace\r
+orientation change does not need to be performed because the workspace already\r
+is in vertical orientation.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_case_5_moving_in_one_child_h_split">16.5. Case 5: Moving in one-child h-split</h3>\r
+<div class="paragraph"><p>The reference layout for this case is a horizontal workspace with two\r
+containers having a v-split on the left side with a one-child h-split on the\r
+bottom. Focus is on the bottom left container (2(h)):</p></div>\r
+<div class="tableblock">\r
+<table rules="all"\r
+width="15%"\r
+frame="border"\r
+cellspacing="0" cellpadding="4">\r
+<col width="50%" />\r
+<col width="50%" />\r
+<tbody>\r
+<tr>\r
+<td align="center" valign="top"><p class="table">1</p></td>\r
+<td rowspan="2" align="center" valign="middle"><p class="table">3</p></td>\r
+</tr>\r
+<tr>\r
+<td align="center" valign="top"><p class="table">2(h)</p></td>\r
+</tr>\r
+</tbody>\r
+</table>\r
+</div>\r
+<div class="paragraph"><p>In this case, <tt>same_orientation</tt> will be set to the h-split container around\r
+the focused container. However, when trying the easy case, the next/previous\r
+container <tt>swap</tt> will be NULL. Therefore, i3 will search again for a\r
+<tt>same_orientation</tt> container, this time starting from the parent of the h-split\r
+container.</p></div>\r
+<div class="paragraph"><p>After determining a new <tt>same_orientation</tt> container (if it is NULL, the\r
+orientation will be force-changed), this case is equivalent to case 2 or case\r
+4.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_case_6_floating_containers">16.6. Case 6: Floating containers</h3>\r
+<div class="paragraph"><p>The reference layout for this case is a horizontal workspace with two\r
+containers plus one floating h-split container. Focus is on the floating\r
+container.</p></div>\r
+<div class="paragraph"><p>TODO: nice illustration. table not possible?</p></div>\r
+<div class="paragraph"><p>When moving up/down, the container needs to leave the floating container and it\r
+needs to be placed on the workspace (at workspace level). This is accomplished\r
+by calling the function <tt>attach_to_workspace</tt>.</p></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_click_handling">17. Click handling</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>Without much ado, here is the list of cases which need to be considered:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+click to focus (tiling + floating) and raise (floating)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+click to focus/raise when in stacked/tabbed mode\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+floating_modifier + left mouse button to drag a floating con\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+floating_modifier + right mouse button to resize a floating con\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+click on decoration in a floating con to either initiate a resize (if there\r
+  is more than one child in the floating con) or to drag the\r
+  floating con (if it’s the one at the top).\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+click on border in a floating con to resize the floating con\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+floating_modifier + right mouse button to resize a tiling con\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+click on border/decoration to resize a tiling con\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_gotchas">18. Gotchas</h2>\r
+<div class="sectionbody">\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+Forgetting to call <tt>xcb_flush(conn);</tt> after sending a request. This usually\r
+  leads to code which looks like it works fine but which does not work under\r
+  certain conditions.\r
+</p>\r
+</li>\r
+</ul></div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_using_git_sending_patches">19. Using git / sending patches</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph"><p>For a short introduction into using git, see\r
+<a href="http://www.spheredev.org/wiki/Git_for_the_lazy">http://www.spheredev.org/wiki/Git_for_the_lazy</a> or, for more documentation, see\r
+<a href="http://git-scm.com/documentation">http://git-scm.com/documentation</a></p></div>\r
+<div class="paragraph"><p>When you want to send a patch because you fixed a bug or implemented a cool\r
+feature (please talk to us before working on features to see whether they are\r
+maybe already implemented, not possible for some some reason, or don’t fit\r
+into the concept), please use git to create a patchfile.</p></div>\r
+<div class="paragraph"><p>First of all, update your working copy to the latest version of the master\r
+branch:</p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>git pull</tt></pre>\r
+</div></div>\r
+<div class="paragraph"><p>Afterwards, make the necessary changes for your bugfix/feature. Then, review\r
+the changes using <tt>git diff</tt> (you might want to enable colors in the diff using\r
+<tt>git config diff.color auto</tt>).  When you are definitely done, use <tt>git commit\r
+-a</tt> to commit all changes you’ve made.</p></div>\r
+<div class="paragraph"><p>Then, use the following command to generate a patchfile which we can directly\r
+apply to the branch, preserving your commit message and name:</p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>git format-patch origin</tt></pre>\r
+</div></div>\r
+<div class="paragraph"><p>Just send us the generated file via email.</p></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div id="footnotes"><hr /></div>\r
+<div id="footer" lang="de">\r
+© 2009-2011 Michael Stapelberg, <a href="/impress.html">Impressum</a>\r
+</div>\r
+</body>\r
+</html>\r