]> git.sur5r.net Git - i3/i3.github.io/blobdiff - docs/ipc.html
update docs for 4.13
[i3/i3.github.io] / docs / ipc.html
index 88b13b7d331aa0684a1998c4feddc2e169896a33..39f6182959aa8b4e95e8ae52e7dfb05daaaf683e 100644 (file)
@@ -2,15 +2,15 @@
     "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
+<link rel="icon" type="image/x-icon" href="/favicon.ico">\r
 <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />\r
-<meta name="generator" content="AsciiDoc 8.6.4" />\r
+<meta name="generator" content="AsciiDoc 8.6.9" />\r
 <title>i3: IPC interface (interprocess communication)</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
+document.addEventListener("DOMContentLoaded", function(){asciidoc.footnotes(); asciidoc.toc(2);}, false);\r
 /*]]>*/\r
 </script>\r
 <script type="text/javascript" src="/js/asciidoc-xhtml11.js"></script>\r
@@ -22,16 +22,17 @@ window.onload = function(){asciidoc.footnotes(); asciidoc.toc(2);}
                         <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="https://www.reddit.com/r/i3wm/">FAQ</a></li>\r
                                 <li><a href="/contact">Contact</a></li>\r
-                                <li><a href="http://bugs.i3wm.org/">Bugs</a></li>\r
+                                <li><a href="https://github.com/i3/i3/issues">Bugs</a></li>\r
                         </ul>\r
         <br style="clear: both">\r
 <div id="content">\r
 <div id="header">\r
 <h1>IPC interface (interprocess communication)</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">March 2010</span>\r
+<span id="email"><tt>&lt;<a href="mailto:michael@i3wm.org">michael@i3wm.org</a>&gt;</tt></span><br />\r
+<span id="revdate">October 2014</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>
@@ -45,9 +46,25 @@ to get various information like the current workspaces to implement an external
 workspace bar.</p></div>\r
 <div class="paragraph"><p>The method of choice for IPC in our case is a unix socket because it has very\r
 little overhead on both sides and is usually available without headaches in\r
-most languages. In the default configuration file, no ipc-socket path is\r
-specified and thus no socket is created. The standard path (which <tt>i3-msg</tt> and\r
-<tt>i3-input</tt> use) is <tt>~/.i3/ipc.sock</tt>.</p></div>\r
+most languages. In the default configuration file, the ipc-socket gets created\r
+in <tt>/tmp/i3-%u.XXXXXX/ipc-socket.%p</tt> where <tt>%u</tt> is your UNIX username, <tt>%p</tt> is\r
+the PID of i3 and XXXXXX is a string of random characters from the portable\r
+filename character set (see mkdtemp(3)). You can get the socketpath from i3 by\r
+calling <tt>i3 --get-socketpath</tt>.</p></div>\r
+<div class="paragraph"><p>All i3 utilities, like <tt>i3-msg</tt> and <tt>i3-input</tt> will read the <tt>I3_SOCKET_PATH</tt>\r
+X11 property, stored on the X11 root window.</p></div>\r
+<div class="admonitionblock">\r
+<table><tr>\r
+<td class="icon">\r
+<div class="title">Warning</div>\r
+</td>\r
+<td class="content">\r
+<div class="title">Use an existing library!</div>There are existing libraries for many languages. You can have a look at\r
+<a href="#libraries">[libraries]</a> or search the web if your language of choice is not mentioned.\r
+Usually, it is not necessary to implement low-level communication with i3\r
+directly.</td>\r
+</tr></table>\r
+</div>\r
 </div>\r
 </div>\r
 <div class="sect1">\r
@@ -58,7 +75,8 @@ snippet illustrates this in Perl:</p></div>
 <div class="listingblock">\r
 <div class="content">\r
 <pre><tt>use IO::Socket::UNIX;\r
-my $sock = IO::Socket::UNIX-&gt;new(Peer =&gt; '~/.i3/ipc.sock');</tt></pre>\r
+chomp(my $path = qx(i3 --get-socketpath));\r
+my $sock = IO::Socket::UNIX-&gt;new(Peer =&gt; $path);</tt></pre>\r
 </div></div>\r
 </div>\r
 </div>\r
@@ -83,7 +101,7 @@ COMMAND (0)
 <p>\r
         The payload of the message is a command for i3 (like the commands you\r
         can bind to keys in the configuration file) and will be executed\r
-        directly after receiving it. There is no reply to this message.\r
+        directly after receiving it.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -113,6 +131,53 @@ GET_OUTPUTS (3)
         (see the reply section).\r
 </p>\r
 </dd>\r
+<dt class="hdlist1">\r
+GET_TREE (4)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Gets the layout tree. i3 uses a tree as data structure which includes\r
+        every container. The reply will be the JSON-encoded tree (see the reply\r
+        section).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+GET_MARKS (5)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Gets a list of marks (identifiers for containers to easily jump to them\r
+        later). The reply will be a JSON-encoded list of window marks (see\r
+        reply section).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+GET_BAR_CONFIG (6)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Gets the configuration (as JSON map) of the workspace bar with the\r
+        given ID. If no ID is provided, an array with all configured bar IDs is\r
+        returned instead.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+GET_VERSION (7)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Gets the version of i3. The reply will be a JSON-encoded dictionary\r
+        with the major, minor, patch and human-readable version.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+GET_BINDING_MODES (8)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Gets a list of currently configured binding modes.\r
+</p>\r
+</dd>\r
 </dl></div>\r
 <div class="paragraph"><p>So, a typical message could look like this:</p></div>\r
 <div class="listingblock">\r
@@ -123,7 +188,7 @@ GET_OUTPUTS (3)
 <div class="listingblock">\r
 <div class="content">\r
 <pre><tt>00000000  69 33 2d 69 70 63 04 00  00 00 00 00 00 00 65 78  |i3-ipc........ex|\r
-00000010  69 74 0a                                          |it.|</tt></pre>\r
+00000010  69 74                                             |it|</tt></pre>\r
 </div></div>\r
 <div class="paragraph"><p>To generate and send such a message, you could use the following code in Perl:</p></div>\r
 <div class="listingblock">\r
@@ -164,7 +229,7 @@ COMMAND (0)
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
-GET_WORKSPACES (1)\r
+WORKSPACES (1)\r
 </dt>\r
 <dd>\r
 <p>\r
@@ -180,27 +245,68 @@ SUBSCRIBE (2)
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
-GET_OUTPUTS (3)\r
+OUTPUTS (3)\r
 </dt>\r
 <dd>\r
 <p>\r
         Reply to the GET_OUTPUTS message.\r
 </p>\r
 </dd>\r
+<dt class="hdlist1">\r
+TREE (4)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Reply to the GET_TREE message.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+MARKS (5)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Reply to the GET_MARKS message.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+BAR_CONFIG (6)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Reply to the GET_BAR_CONFIG message.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+VERSION (7)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Reply to the GET_VERSION message.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+BINDING_MODES (8)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Reply to the GET_BINDING_MODES message.\r
+</p>\r
+</dd>\r
 </dl></div>\r
 </div>\r
 <div class="sect2">\r
 <h3 id="_command_reply">3.2. COMMAND reply</h3>\r
-<div class="paragraph"><p>The reply consists of a single serialized map. At the moment, the only\r
-property is <tt>success (bool)</tt>, but this will be expanded in future versions.</p></div>\r
+<div class="paragraph"><p>The reply consists of a list of serialized maps for each command that was\r
+parsed. Each has the property <tt>success (bool)</tt> and may also include a\r
+human-readable error message in the property <tt>error (string)</tt>.</p></div>\r
 <div class="paragraph"><p><strong>Example:</strong></p></div>\r
 <div class="listingblock">\r
 <div class="content">\r
-<pre><tt>{ "success": true }</tt></pre>\r
+<pre><tt>[{ "success": true }]</tt></pre>\r
 </div></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_get_workspaces_reply">3.3. GET_WORKSPACES reply</h3>\r
+<h3 id="_workspaces_reply">3.3. WORKSPACES reply</h3>\r
 <div class="paragraph"><p>The reply consists of a serialized list of workspaces. Each workspace has the\r
 following properties:</p></div>\r
 <div class="dlist"><dl>\r
@@ -210,7 +316,7 @@ num (integer)
 <dd>\r
 <p>\r
         The logical number of the workspace. Corresponds to the command\r
-        to switch to this workspace.\r
+        to switch to this workspace. For named workspaces, this will be -1.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -313,7 +419,7 @@ default) or whether a JSON parse error occurred.</p></div>
 </div></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_get_outputs_reply">3.5. GET_OUTPUTS reply</h3>\r
+<h3 id="_outputs_reply">3.5. OUTPUTS reply</h3>\r
 <div class="paragraph"><p>The reply consists of a serialized list of outputs. Each output has the\r
 following properties:</p></div>\r
 <div class="dlist"><dl>\r
@@ -334,12 +440,12 @@ active (boolean)
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
-current_workspace (integer)\r
+current_workspace (string)\r
 </dt>\r
 <dd>\r
 <p>\r
-        The current workspace which is visible on this output. <tt>null</tt> if the\r
-        output is not active.\r
+        The name of the current workspace that is visible on this output. <tt>null</tt> if\r
+        the output is not active.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
@@ -359,7 +465,7 @@ rect (map)
  {\r
   "name": "LVDS1",\r
   "active": true,\r
-  "current_workspace": 4,\r
+  "current_workspace": "4",\r
   "rect": {\r
    "x": 0,\r
    "y": 0,\r
@@ -370,7 +476,7 @@ rect (map)
  {\r
   "name": "VGA1",\r
   "active": true,\r
-  "current_workspace": 1,\r
+  "current_workspace": "1",\r
   "rect": {\r
    "x": 1280,\r
    "y": 0,\r
@@ -381,141 +487,1101 @@ rect (map)
 ]</tt></pre>\r
 </div></div>\r
 </div>\r
-</div>\r
-</div>\r
-<div class="sect1">\r
-<h2 id="_events">4. Events</h2>\r
-<div class="sectionbody">\r
-<div class="paragraph" id="events"><p>To get informed when certain things happen in i3, clients can subscribe to\r
-events. Events consist of a name (like "workspace") and an event reply type\r
-(like I3_IPC_EVENT_WORKSPACE). The events sent by i3 are in the same format\r
-as replies to specific commands. However, the highest bit of the message type\r
-is set to 1 to indicate that this is an event reply instead of a normal reply.</p></div>\r
-<div class="paragraph"><p>Caveat: As soon as you subscribe to an event, it is not guaranteed any longer\r
-that the requests to i3 are processed in order. This means, the following\r
-situation can happen: You send a GET_WORKSPACES request but you receive a\r
-"workspace" event before receiving the reply to GET_WORKSPACES. If your\r
-program does not want to cope which such kinds of race conditions (an\r
-event based library may not have a problem here), I suggest you create a\r
-separate connection to receive events.</p></div>\r
-<div class="sect2">\r
-<h3 id="_subscribing_to_events">4.1. Subscribing to events</h3>\r
-<div class="paragraph"><p>By sending a message of type SUBSCRIBE with a JSON-encoded array as payload\r
-you can register to an event.</p></div>\r
-<div class="paragraph"><p><strong>Example:</strong></p></div>\r
-<div class="listingblock">\r
-<div class="content">\r
-<pre><tt>type: SUBSCRIBE\r
-payload: [ "workspace", "focus" ]</tt></pre>\r
-</div></div>\r
-</div>\r
 <div class="sect2">\r
-<h3 id="_available_events">4.2. Available events</h3>\r
-<div class="paragraph"><p>The numbers in parenthesis is the event type (keep in mind that you need to\r
-strip the highest bit first).</p></div>\r
+<h3 id="_tree_reply">3.6. TREE reply</h3>\r
+<div class="paragraph"><p>The reply consists of a serialized tree. Each node in the tree (representing\r
+one container) has at least the properties listed below. While the nodes might\r
+have more properties, please do not use any properties which are not documented\r
+here. They are not yet finalized and will probably change!</p></div>\r
 <div class="dlist"><dl>\r
 <dt class="hdlist1">\r
-workspace (0)\r
+id (integer)\r
 </dt>\r
 <dd>\r
 <p>\r
-        Sent when the user switches to a different workspace, when a new\r
-        workspace is initialized or when a workspace is removed (because the\r
-        last client vanished).\r
+        The internal ID (actually a C pointer value) of this container. Do not\r
+        make any assumptions about it. You can use it to (re-)identify and\r
+        address containers when talking to i3.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
-output (1)\r
+name (string)\r
 </dt>\r
 <dd>\r
 <p>\r
-        Sent when RandR issues a change notification (of either screens,\r
-        outputs, CRTCs or output properties).\r
+        The internal name of this container. For all containers which are part\r
+        of the tree structure down to the workspace contents, this is set to a\r
+        nice human-readable name of the container.\r
+        For containers that have an X11 window, the content is the title\r
+        (_NET_WM_NAME property) of that window.\r
+        For all other containers, the content is not defined (yet).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+type (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Type of this container. Can be one of "root", "output", "con",\r
+        "floating_con", "workspace" or "dockarea".\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+border (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Can be either "normal", "none" or "pixel", depending on the\r
+        container’s border style.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+current_border_width (integer)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Number of pixels of the border width.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+layout (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Can be either "splith", "splitv", "stacked", "tabbed", "dockarea" or\r
+        "output".\r
+        Other values might be possible in the future, should we add new\r
+        layouts.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+orientation (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Can be either "none" (for non-split containers), "horizontal" or\r
+        "vertical".\r
+        THIS FIELD IS OBSOLETE. It is still present, but your code should not\r
+        use it. Instead, rely on the layout field.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+percent (float)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The percentage which this container takes in its parent. A value of\r
+        <tt>null</tt> means that the percent property does not make sense for this\r
+        container, for example for the root container.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+rect (map)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The absolute display coordinates for this container. Display\r
+        coordinates means that when you have two 1600x1200 monitors on a single\r
+        X11 Display (the standard way), the coordinates of the first window on\r
+        the second monitor are <tt>{ "x": 1600, "y": 0, "width": 1600, "height":\r
+        1200 }</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+window_rect (map)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The coordinates of the <strong>actual client window</strong> inside its container.\r
+        These coordinates are relative to the container and do not include the\r
+        window decoration (which is actually rendered on the parent container).\r
+        So, when using the <tt>default</tt> layout, you will have a 2 pixel border on\r
+        each side, making the window_rect <tt>{ "x": 2, "y": 0, "width": 632,\r
+        "height": 366 }</tt> (for example).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+deco_rect (map)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The coordinates of the <strong>window decoration</strong> inside its container. These\r
+        coordinates are relative to the container and do not include the actual\r
+        client window.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+geometry (map)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The original geometry the window specified when i3 mapped it. Used when\r
+        switching a window to floating mode, for example.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+window (integer)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The X11 window ID of the <strong>actual client window</strong> inside this container.\r
+        This field is set to null for split containers or otherwise empty\r
+        containers. This ID corresponds to what xwininfo(1) and other\r
+        X11-related tools display (usually in hex).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+urgent (bool)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Whether this container (window or workspace) has the urgency hint set.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+focused (bool)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Whether this container is currently focused.\r
 </p>\r
 </dd>\r
 </dl></div>\r
+<div class="paragraph"><p>Please note that in the following example, I have left out some keys/values\r
+which are not relevant for the type of the node. Otherwise, the example would\r
+be by far too long (it already is quite long, despite showing only 1 window and\r
+one dock window).</p></div>\r
+<div class="paragraph"><p>It is useful to have an overview of the structure before taking a look at the\r
+JSON dump:</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+root\r
+</p>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+LVDS1\r
+</p>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+topdock\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+content\r
+</p>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+workspace 1\r
+</p>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+window 1\r
+</p>\r
+</li>\r
+</ul></div>\r
+</li>\r
+</ul></div>\r
+</li>\r
+<li>\r
+<p>\r
+bottomdock\r
+</p>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+dock window 1\r
+</p>\r
+</li>\r
+</ul></div>\r
+</li>\r
+</ul></div>\r
+</li>\r
+<li>\r
+<p>\r
+VGA1\r
+</p>\r
+</li>\r
+</ul></div>\r
+</li>\r
+</ul></div>\r
 <div class="paragraph"><p><strong>Example:</strong></p></div>\r
 <div class="listingblock">\r
 <div class="content">\r
-<pre><tt># the appropriate 4 bytes read from the socket are stored in $input\r
+<pre><tt>{\r
+ "id": 6875648,\r
+ "name": "root",\r
+ "rect": {\r
+   "x": 0,\r
+   "y": 0,\r
+   "width": 1280,\r
+   "height": 800\r
+ },\r
+ "nodes": [\r
 \r
-# unpack a 32-bit unsigned integer\r
-my $message_type = unpack("L", $input);\r
+   {\r
+    "id": 6878320,\r
+    "name": "LVDS1",\r
+    "layout": "output",\r
+    "rect": {\r
+      "x": 0,\r
+      "y": 0,\r
+      "width": 1280,\r
+      "height": 800\r
+    },\r
+    "nodes": [\r
 \r
-# check if the highest bit is 1\r
-my $is_event = (($message_type &gt;&gt; 31) == 1);\r
+      {\r
+       "id": 6878784,\r
+       "name": "topdock",\r
+       "layout": "dockarea",\r
+       "orientation": "vertical",\r
+       "rect": {\r
+         "x": 0,\r
+         "y": 0,\r
+         "width": 1280,\r
+         "height": 0\r
+       },\r
+      },\r
 \r
-# use the other bits\r
-my $event_type = ($message_type &amp; 0x7F);\r
+      {\r
+       "id": 6879344,\r
+       "name": "content",\r
+       "rect": {\r
+         "x": 0,\r
+         "y": 0,\r
+         "width": 1280,\r
+         "height": 782\r
+       },\r
+       "nodes": [\r
 \r
-if ($is_event) {\r
-  say "Received event of type $event_type";\r
+         {\r
+          "id": 6880464,\r
+          "name": "1",\r
+          "orientation": "horizontal",\r
+          "rect": {\r
+            "x": 0,\r
+            "y": 0,\r
+            "width": 1280,\r
+            "height": 782\r
+          },\r
+          "floating_nodes": [],\r
+          "nodes": [\r
+\r
+            {\r
+             "id": 6929968,\r
+             "name": "#aa0000",\r
+             "border": "normal",\r
+             "percent": 1,\r
+             "rect": {\r
+               "x": 0,\r
+               "y": 18,\r
+               "width": 1280,\r
+               "height": 782\r
+             }\r
+            }\r
+\r
+          ]\r
+         }\r
+\r
+       ]\r
+      },\r
+\r
+      {\r
+       "id": 6880208,\r
+       "name": "bottomdock",\r
+       "layout": "dockarea",\r
+       "orientation": "vertical",\r
+       "rect": {\r
+         "x": 0,\r
+         "y": 782,\r
+         "width": 1280,\r
+         "height": 18\r
+       },\r
+       "nodes": [\r
+\r
+         {\r
+          "id": 6931312,\r
+          "name": "#00aa00",\r
+          "percent": 1,\r
+          "rect": {\r
+            "x": 0,\r
+            "y": 782,\r
+            "width": 1280,\r
+            "height": 18\r
+          }\r
+         }\r
+\r
+       ]\r
+      }\r
+    ]\r
+   }\r
+ ]\r
 }</tt></pre>\r
 </div></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_workspace_event">4.3. workspace event</h3>\r
-<div class="paragraph"><p>This event consists of a single serialized map containing a property\r
-<tt>change (string)</tt> which indicates the type of the change ("focus", "init",\r
-"empty", "urgent").</p></div>\r
-<div class="paragraph"><p><strong>Example:</strong></p></div>\r
-<div class="listingblock">\r
-<div class="content">\r
-<pre><tt>{ "change": "focus" }</tt></pre>\r
-</div></div>\r
+<h3 id="_marks_reply">3.7. MARKS reply</h3>\r
+<div class="paragraph"><p>The reply consists of a single array of strings for each container that has a\r
+mark. A mark can only be set on one container, so the array is unique.\r
+The order of that array is undefined.</p></div>\r
+<div class="paragraph"><p>If no window has a mark the response will be the empty array [].</p></div>\r
 </div>\r
 <div class="sect2">\r
-<h3 id="_output_event">4.4. output event</h3>\r
-<div class="paragraph"><p>This event consists of a single serialized map containing a property\r
-<tt>change (string)</tt> which indicates the type of the change (currently only\r
-"unspecified").</p></div>\r
-<div class="paragraph"><p><strong>Example:</strong></p></div>\r
-<div class="listingblock">\r
-<div class="content">\r
-<pre><tt>{ "change": "unspecified" }</tt></pre>\r
-</div></div>\r
-</div>\r
-</div>\r
-</div>\r
-<div class="sect1">\r
-<h2 id="_see_also">5. See also</h2>\r
-<div class="sectionbody">\r
-<div class="paragraph"><p>For some languages, libraries are available (so you don’t have to implement\r
-all this on your own). This list names some (if you wrote one, please let me\r
-know):</p></div>\r
+<h3 id="_bar_config_reply">3.8. BAR_CONFIG reply</h3>\r
+<div class="paragraph"><p>This can be used by third-party workspace bars (especially i3bar, but others\r
+are free to implement compatible alternatives) to get the <tt>bar</tt> block\r
+configuration from i3.</p></div>\r
+<div class="paragraph"><p>Depending on the input, the reply is either:</p></div>\r
 <div class="dlist"><dl>\r
 <dt class="hdlist1">\r
-C\r
+empty input\r
 </dt>\r
 <dd>\r
 <p>\r
-        i3 includes a headerfile <tt>i3/ipc.h</tt> which provides you all constants.\r
-        However, there is no library yet.\r
+        An array of configured bar IDs\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
-Ruby\r
+Bar ID\r
 </dt>\r
 <dd>\r
 <p>\r
-        <a href="http://github.com/badboy/i3-ipc">http://github.com/badboy/i3-ipc</a>\r
+        A JSON map containing the configuration for the specified bar.\r
 </p>\r
 </dd>\r
+</dl></div>\r
+<div class="paragraph"><p>Each bar configuration has the following properties:</p></div>\r
+<div class="dlist"><dl>\r
 <dt class="hdlist1">\r
-Perl\r
+id (string)\r
 </dt>\r
 <dd>\r
 <p>\r
-        <a href="http://search.cpan.org/search?query=AnyEvent::I3">http://search.cpan.org/search?query=AnyEvent::I3</a>\r
+        The ID for this bar. Included in case you request multiple\r
+        configurations and want to differentiate the different replies.\r
 </p>\r
 </dd>\r
 <dt class="hdlist1">\r
-Python\r
+mode (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Either <tt>dock</tt> (the bar sets the dock window type) or <tt>hide</tt> (the bar\r
+        does not show unless a specific key is pressed).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+position (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Either <tt>bottom</tt> or <tt>top</tt> at the moment.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+status_command (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Command which will be run to generate a statusline. Each line on stdout\r
+        of this command will be displayed in the bar. At the moment, no\r
+        formatting is supported.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+font (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The font to use for text on the bar.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+workspace_buttons (boolean)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Display workspace buttons or not? Defaults to true.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+binding_mode_indicator (boolean)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Display the mode indicator or not? Defaults to true.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+verbose (boolean)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Should the bar enable verbose output for debugging? Defaults to false.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+colors (map)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Contains key/value pairs of colors. Each value is a color code in hex,\r
+        formatted #rrggbb (like in HTML).\r
+</p>\r
+</dd>\r
+</dl></div>\r
+<div class="paragraph"><p>The following colors can be configured at the moment:</p></div>\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+background\r
+</dt>\r
+<dd>\r
+<p>\r
+        Background color of the bar.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+statusline\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text color to be used for the statusline.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+separator\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text color to be used for the separator.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+focused_background\r
+</dt>\r
+<dd>\r
+<p>\r
+        Background color of the bar on the currently focused monitor output.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+focused_statusline\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text color to be used for the statusline on the currently focused\r
+        monitor output.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+focused_separator\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text color to be used for the separator on the currently focused\r
+        monitor output.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+focused_workspace_text/focused_workspace_bg/focused_workspace_border\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text/background/border color for a workspace button when the workspace\r
+        has focus.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+active_workspace_text/active_workspace_bg/active_workspace_border\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text/background/border color for a workspace button when the workspace\r
+        is active (visible) on some output, but the focus is on another one.\r
+        You can only tell this apart from the focused workspace when you are\r
+        using multiple monitors.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+inactive_workspace_text/inactive_workspace_bg/inactive_workspace_border\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text/background/border color for a workspace button when the workspace\r
+        does not have focus and is not active (visible) on any output. This\r
+        will be the case for most workspaces.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+urgent_workspace_text/urgent_workspace_bg/urgent_workspace_border\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text/background/border color for workspaces which contain at least one\r
+        window with the urgency hint set.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+binding_mode_text/binding_mode_bg/binding_mode_border\r
+</dt>\r
+<dd>\r
+<p>\r
+        Text/background/border color for the binding mode indicator.\r
+</p>\r
+</dd>\r
+</dl></div>\r
+<div class="paragraph"><p><strong>Example of configured bars:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>["bar-bxuqzf"]</tt></pre>\r
+</div></div>\r
+<div class="paragraph"><p><strong>Example of bar configuration:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>{\r
+ "id": "bar-bxuqzf",\r
+ "mode": "dock",\r
+ "position": "bottom",\r
+ "status_command": "i3status",\r
+ "font": "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1",\r
+ "workspace_buttons": true,\r
+ "binding_mode_indicator": true,\r
+ "verbose": false,\r
+ "colors": {\r
+   "background": "#c0c0c0",\r
+   "statusline": "#00ff00",\r
+   "focused_workspace_text": "#ffffff",\r
+   "focused_workspace_bg": "#000000"\r
+ }\r
+}</tt></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_version_reply">3.9. VERSION reply</h3>\r
+<div class="paragraph"><p>The reply consists of a single JSON dictionary with the following keys:</p></div>\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+major (integer)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The major version of i3, such as <tt>4</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+minor (integer)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The minor version of i3, such as <tt>2</tt>. Changes in the IPC interface (new\r
+        features) will only occur with new minor (or major) releases. However,\r
+        bugfixes might be introduced in patch releases, too.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+patch (integer)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The patch version of i3, such as <tt>1</tt> (when the complete version is\r
+        <tt>4.2.1</tt>). For versions such as <tt>4.2</tt>, patch will be set to <tt>0</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+human_readable (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        A human-readable version of i3 containing the precise git version,\r
+        build date and branch name. When you need to display the i3 version to\r
+        your users, use the human-readable version whenever possible (since\r
+        this is what <tt>i3 --version</tt> displays, too).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+loaded_config_file_name (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The current config path.\r
+</p>\r
+</dd>\r
+</dl></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>{\r
+   "human_readable" : "4.2-169-gf80b877 (2012-08-05, branch \"next\")",\r
+   "loaded_config_file_name" : "/home/hwangcc23/.i3/config",\r
+   "minor" : 2,\r
+   "patch" : 0,\r
+   "major" : 4\r
+}</tt></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_binding_modes_reply">3.10. BINDING_MODES reply</h3>\r
+<div class="paragraph"><p>The reply consists of an array of all currently configured binding modes.</p></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>["default", "resize"]</tt></pre>\r
+</div></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_events">4. Events</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph" id="events"><p>To get informed when certain things happen in i3, clients can subscribe to\r
+events. Events consist of a name (like "workspace") and an event reply type\r
+(like I3_IPC_EVENT_WORKSPACE). The events sent by i3 are in the same format\r
+as replies to specific commands. However, the highest bit of the message type\r
+is set to 1 to indicate that this is an event reply instead of a normal reply.</p></div>\r
+<div class="paragraph"><p>Caveat: As soon as you subscribe to an event, it is not guaranteed any longer\r
+that the requests to i3 are processed in order. This means, the following\r
+situation can happen: You send a GET_WORKSPACES request but you receive a\r
+"workspace" event before receiving the reply to GET_WORKSPACES. If your\r
+program does not want to cope which such kinds of race conditions (an\r
+event based library may not have a problem here), I suggest you create a\r
+separate connection to receive events.</p></div>\r
+<div class="sect2">\r
+<h3 id="_subscribing_to_events">4.1. Subscribing to events</h3>\r
+<div class="paragraph"><p>By sending a message of type SUBSCRIBE with a JSON-encoded array as payload\r
+you can register to an event.</p></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>type: SUBSCRIBE\r
+payload: [ "workspace", "output" ]</tt></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_available_events">4.2. Available events</h3>\r
+<div class="paragraph"><p>The numbers in parenthesis is the event type (keep in mind that you need to\r
+strip the highest bit first).</p></div>\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+workspace (0)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Sent when the user switches to a different workspace, when a new\r
+        workspace is initialized or when a workspace is removed (because the\r
+        last client vanished).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+output (1)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Sent when RandR issues a change notification (of either screens,\r
+        outputs, CRTCs or output properties).\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+mode (2)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Sent whenever i3 changes its binding mode.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+window (3)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Sent when a client&#8217;s window is successfully reparented (that is when i3\r
+        has finished fitting it into a container), when a window received input\r
+        focus or when certain properties of the window have changed.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+barconfig_update (4)\r
+</dt>\r
+<dd>\r
+<p>\r
+    Sent when the hidden_state or mode field in the barconfig of any bar\r
+    instance was updated and when the config is reloaded.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+binding (5)\r
+</dt>\r
+<dd>\r
+<p>\r
+        Sent when a configured command binding is triggered with the keyboard or\r
+        mouse\r
+</p>\r
+</dd>\r
+</dl></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt># the appropriate 4 bytes read from the socket are stored in $input\r
+\r
+# unpack a 32-bit unsigned integer\r
+my $message_type = unpack("L", $input);\r
+\r
+# check if the highest bit is 1\r
+my $is_event = (($message_type &gt;&gt; 31) == 1);\r
+\r
+# use the other bits\r
+my $event_type = ($message_type &amp; 0x7F);\r
+\r
+if ($is_event) {\r
+  say "Received event of type $event_type";\r
+}</tt></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_workspace_event">4.3. workspace event</h3>\r
+<div class="paragraph"><p>This event consists of a single serialized map containing a property\r
+<tt>change (string)</tt> which indicates the type of the change ("focus", "init",\r
+"empty", "urgent"). A <tt>current (object)</tt> property will be present with the\r
+affected workspace whenever the type of event affects a workspace (otherwise,\r
+it will be +null).</p></div>\r
+<div class="paragraph"><p>When the change is "focus", an <tt>old (object)</tt> property will be present with the\r
+previous workspace.  When the first switch occurs (when i3 focuses the\r
+workspace visible at the beginning) there is no previous workspace, and the\r
+<tt>old</tt> property will be set to <tt>null</tt>.  Also note that if the previous is empty\r
+it will get destroyed when switching, but will still be present in the "old"\r
+property.</p></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>{\r
+ "change": "focus",\r
+ "current": {\r
+  "id": 28489712,\r
+  "type": "workspace",\r
+  ...\r
+ }\r
+ "old": {\r
+  "id": 28489715,\r
+  "type": "workspace",\r
+  ...\r
+ }\r
+}</tt></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_output_event">4.4. output event</h3>\r
+<div class="paragraph"><p>This event consists of a single serialized map containing a property\r
+<tt>change (string)</tt> which indicates the type of the change (currently only\r
+"unspecified").</p></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>{ "change": "unspecified" }</tt></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_mode_event">4.5. mode event</h3>\r
+<div class="paragraph"><p>This event consists of a single serialized map containing a property\r
+<tt>change (string)</tt> which holds the name of current mode in use. The name\r
+is the same as specified in config when creating a mode. The default\r
+mode is simply named default. It contains a second property, <tt>pango_markup</tt>, which\r
+defines whether pango markup shall be used for displaying this mode.</p></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>{\r
+  "change": "default",\r
+  "pango_markup": true\r
+}</tt></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_window_event">4.6. window event</h3>\r
+<div class="paragraph"><p>This event consists of a single serialized map containing a property\r
+<tt>change (string)</tt> which indicates the type of the change</p></div>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<tt>new</tt> – the window has become managed by i3\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<tt>close</tt> – the window has closed\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<tt>focus</tt> – the window has received input focus\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<tt>title</tt> – the window&#8217;s title has changed\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<tt>fullscreen_mode</tt> – the window has entered or exited fullscreen mode\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<tt>move</tt> – the window has changed its position in the tree\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<tt>floating</tt> – the window has transitioned to or from floating\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<tt>urgent</tt> – the window has become urgent or lost its urgent status\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<tt>mark</tt> – a mark has been added to or removed from the window\r
+</p>\r
+</li>\r
+</ul></div>\r
+<div class="paragraph"><p>Additionally a <tt>container (object)</tt> field will be present, which consists\r
+of the window&#8217;s parent container. Be aware that for the "new" event, the\r
+container will hold the initial name of the newly reparented window (e.g.\r
+if you run urxvt with a shell that changes the title, you will still at\r
+this point get the window title as "urxvt").</p></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>{\r
+ "change": "new",\r
+ "container": {\r
+  "id": 35569536,\r
+  "type": "con",\r
+  ...\r
+ }\r
+}</tt></pre>\r
+</div></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_barconfig_update_event">4.7. barconfig_update event</h3>\r
+<div class="paragraph"><p>This event consists of a single serialized map reporting on options from the\r
+barconfig of the specified bar_id that were updated in i3. This event is the\r
+same as a <tt>GET_BAR_CONFIG</tt> reply for the bar with the given id.</p></div>\r
+</div>\r
+<div class="sect2">\r
+<h3 id="_binding_event">4.8. binding event</h3>\r
+<div class="paragraph"><p>This event consists of a single serialized map reporting on the details of a\r
+binding that ran a command because of user input. The <tt>change (sring)</tt> field\r
+indicates what sort of binding event was triggered (right now it will always be\r
+<tt>"run"</tt> but may be expanded in the future).</p></div>\r
+<div class="paragraph"><p>The <tt>binding (object)</tt> field contains details about the binding that was run:</p></div>\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+command (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The i3 command that is configured to run for this binding.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+event_state_mask (array of strings)\r
+</dt>\r
+<dd>\r
+<p>\r
+        The group and modifier keys that were configured with this binding.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+input_code (integer)\r
+</dt>\r
+<dd>\r
+<p>\r
+        If the binding was configured with <tt>bindcode</tt>, this will be the key code\r
+        that was given for the binding. If the binding is a mouse binding, it will be\r
+        the number of the mouse button that was pressed. Otherwise it will be 0.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+symbol (string or null)\r
+</dt>\r
+<dd>\r
+<p>\r
+        If this is a keyboard binding that was configured with <tt>bindsym</tt>, this\r
+        field will contain the given symbol. Otherwise it will be <tt>null</tt>.\r
+</p>\r
+</dd>\r
+<dt class="hdlist1">\r
+input_type (string)\r
+</dt>\r
+<dd>\r
+<p>\r
+        This will be <tt>"keyboard"</tt> or <tt>"mouse"</tt> depending on whether or not this was\r
+        a keyboard or a mouse binding.\r
+</p>\r
+</dd>\r
+</dl></div>\r
+<div class="paragraph"><p><strong>Example:</strong></p></div>\r
+<div class="listingblock">\r
+<div class="content">\r
+<pre><tt>{\r
+ "change": "run",\r
+ "binding": {\r
+  "command": "nop",\r
+  "event_state_mask": [\r
+    "shift",\r
+    "ctrl"\r
+  ],\r
+  "input_code": 0,\r
+  "symbol": "t",\r
+  "input_type": "keyboard"\r
+ }\r
+}</tt></pre>\r
+</div></div>\r
+</div>\r
+</div>\r
+</div>\r
+<div class="sect1">\r
+<h2 id="_see_also_existing_libraries">5. See also (existing libraries)</h2>\r
+<div class="sectionbody">\r
+<div class="paragraph" id="libraries"><p>For some languages, libraries are available (so you don’t have to implement\r
+all this on your own). This list names some (if you wrote one, please let me\r
+know):</p></div>\r
+<div class="dlist"><dl>\r
+<dt class="hdlist1">\r
+C\r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+i3 includes a headerfile <tt>i3/ipc.h</tt> which provides you all constants.\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<a href="https://github.com/acrisci/i3ipc-glib">https://github.com/acrisci/i3ipc-glib</a>\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+<dt class="hdlist1">\r
+C++\r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<a href="https://github.com/drmgc/i3ipcpp">https://github.com/drmgc/i3ipcpp</a>\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+<dt class="hdlist1">\r
+Go\r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<a href="https://github.com/proxypoke/i3ipc">https://github.com/proxypoke/i3ipc</a>\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+<dt class="hdlist1">\r
+JavaScript\r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<a href="https://github.com/acrisci/i3ipc-gjs">https://github.com/acrisci/i3ipc-gjs</a>\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+<dt class="hdlist1">\r
+Lua\r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<a href="https://github.com/acrisci/i3ipc-lua">https://github.com/acrisci/i3ipc-lua</a>\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+<dt class="hdlist1">\r
+Perl\r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<a href="https://metacpan.org/module/AnyEvent::I3">https://metacpan.org/module/AnyEvent::I3</a>\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+<dt class="hdlist1">\r
+Python\r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<a href="https://github.com/acrisci/i3ipc-python">https://github.com/acrisci/i3ipc-python</a>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<a href="https://github.com/whitelynx/i3ipc">https://github.com/whitelynx/i3ipc</a> (not maintained)\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<a href="https://github.com/ziberna/i3-py">https://github.com/ziberna/i3-py</a> (not maintained)\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+<dt class="hdlist1">\r
+Ruby\r
+</dt>\r
+<dd>\r
+<div class="ulist"><ul>\r
+<li>\r
+<p>\r
+<a href="https://github.com/veelenga/i3ipc-ruby">https://github.com/veelenga/i3ipc-ruby</a>\r
+</p>\r
+</li>\r
+<li>\r
+<p>\r
+<a href="https://github.com/badboy/i3-ipc">https://github.com/badboy/i3-ipc</a> (not maintained)\r
+</p>\r
+</li>\r
+</ul></div>\r
+</dd>\r
+<dt class="hdlist1">\r
+Rust\r
 </dt>\r
 <dd>\r
+<div class="ulist"><ul>\r
+<li>\r
 <p>\r
-        <a href="http://github.com/thepub/i3ipc">http://github.com/thepub/i3ipc</a>\r
+<a href="https://github.com/tmerr/i3ipc-rs">https://github.com/tmerr/i3ipc-rs</a>\r
 </p>\r
+</li>\r
+</ul></div>\r
 </dd>\r
 </dl></div>\r
 </div>\r