]> git.sur5r.net Git - i3/i3.github.io/blobdiff - _docs/ipc
update docs for 4.14.1
[i3/i3.github.io] / _docs / ipc
index 6572357704a92064a0b33cb7c830f22f10623e5d..997a3055fb1c22b5393e4409d8fc18e450f08372 100644 (file)
--- a/_docs/ipc
+++ b/_docs/ipc
@@ -1,7 +1,7 @@
 IPC interface (interprocess communication)
 ==========================================
 Michael Stapelberg <michael@i3wm.org>
-October 2014
+September 2017
 
 This document describes how to interface with i3 from a separate process. This
 is useful for example to remote-control i3 (to write test cases for example) or
@@ -50,38 +50,21 @@ The magic string currently is "i3-ipc" and will only be changed when a change
 in the IPC API is done which breaks compatibility (we hope that we don’t need
 to do that).
 
-Currently implemented message types are the following:
-
-COMMAND (0)::
-       The payload of the message is a command for i3 (like the commands you
-       can bind to keys in the configuration file) and will be executed
-       directly after receiving it.
-GET_WORKSPACES (1)::
-       Gets the current workspaces. The reply will be a JSON-encoded list of
-       workspaces (see the reply section).
-SUBSCRIBE (2)::
-       Subscribes your connection to certain events. See <<events>> for a
-       description of this message and the concept of events.
-GET_OUTPUTS (3)::
-       Gets the current outputs. The reply will be a JSON-encoded list of outputs
-       (see the reply section).
-GET_TREE (4)::
-       Gets the layout tree. i3 uses a tree as data structure which includes
-       every container. The reply will be the JSON-encoded tree (see the reply
-       section).
-GET_MARKS (5)::
-       Gets a list of marks (identifiers for containers to easily jump to them
-       later). The reply will be a JSON-encoded list of window marks (see
-       reply section).
-GET_BAR_CONFIG (6)::
-       Gets the configuration (as JSON map) of the workspace bar with the
-       given ID. If no ID is provided, an array with all configured bar IDs is
-       returned instead.
-GET_VERSION (7)::
-       Gets the version of i3. The reply will be a JSON-encoded dictionary
-       with the major, minor, patch and human-readable version.
-GET_BINDING_MODES (8)::
-        Gets a list of currently configured binding modes.
+.Currently implemented message types
+[options="header",cols="^10%,^20%,^20%,^50%"]
+|======================================================
+| Type (numeric) | Type (name) | Reply type | Purpose
+| 0 | +RUN_COMMAND+ | <<_command_reply,COMMAND>> | Run the payload as an i3 command (like the commands you can bind to keys).
+| 1 | +GET_WORKSPACES+ | <<_workspaces_reply,WORKSPACES>> | Get the list of current workspaces.
+| 2 | +SUBSCRIBE+ | <<_subscribe_reply,SUBSCRIBE>> | Subscribe this IPC connection to the event types specified in the message payload. See <<events>>.
+| 3 | +GET_OUTPUTS+ | <<_outputs_reply,OUTPUTS>> | Get the list of current outputs.
+| 4 | +GET_TREE+ | <<_tree_reply,TREE>> | Get the i3 layout tree.
+| 5 | +GET_MARKS+ | <<_marks_reply,MARKS>> | Gets the names of all currently set marks.
+| 6 | +GET_BAR_CONFIG+ | <<_bar_config_reply,BAR_CONFIG>> | Gets the specified bar configuration or the names of all bar configurations if payload is empty.
+| 7 | +GET_VERSION+ | <<_version_reply,VERSION>> | Gets the i3 version.
+| 8 | +GET_BINDING_MODES+ | <<_binding_modes_reply,BINDING_MODES>> | Gets the names of all currently configured binding modes.
+| 9 | +GET_CONFIG+ | <<_config_reply,CONFIG>> | Returns the last loaded i3 config.
+|======================================================
 
 So, a typical message could look like this:
 --------------------------------------------------
@@ -124,7 +107,7 @@ payload.
 The following reply types are implemented:
 
 COMMAND (0)::
-       Confirmation/Error code for the COMMAND message.
+       Confirmation/Error code for the RUN_COMMAND message.
 WORKSPACES (1)::
        Reply to the GET_WORKSPACES message.
 SUBSCRIBE (2)::
@@ -141,7 +124,10 @@ VERSION (7)::
        Reply to the GET_VERSION message.
 BINDING_MODES (8)::
         Reply to the GET_BINDING_MODES message.
+GET_CONFIG (9)::
+       Reply to the GET_CONFIG message.
 
+[[_command_reply]]
 === COMMAND reply
 
 The reply consists of a list of serialized maps for each command that was
@@ -153,6 +139,7 @@ human-readable error message in the property +error (string)+.
 [{ "success": true }]
 -------------------
 
+[[_workspaces_reply]]
 === WORKSPACES reply
 
 The reply consists of a serialized list of workspaces. Each workspace has the
@@ -212,6 +199,7 @@ output (string)::
 ]
 -------------------
 
+[[_subscribe_reply]]
 === SUBSCRIBE reply
 
 The reply consists of a single serialized map. The only property is
@@ -223,6 +211,7 @@ default) or whether a JSON parse error occurred.
 { "success": true }
 -------------------
 
+[[_outputs_reply]]
 === OUTPUTS reply
 
 The reply consists of a serialized list of outputs. Each output has the
@@ -269,6 +258,7 @@ rect (map)::
 ]
 -------------------
 
+[[_tree_reply]]
 === TREE reply
 
 The reply consists of a serialized tree. Each node in the tree (representing
@@ -335,9 +325,22 @@ window (integer)::
        containers. This ID corresponds to what xwininfo(1) and other
        X11-related tools display (usually in hex).
 urgent (bool)::
-       Whether this container (window or workspace) has the urgency hint set.
+       Whether this container (window, split container, floating container or
+       workspace) has the urgency hint set, directly or indirectly. All parent
+       containers up until the workspace container will be marked urgent if they
+       have at least one urgent child.
 focused (bool)::
        Whether this container is currently focused.
+focus (array of integer)::
+       List of child node IDs (see +nodes+, +floating_nodes+ and +id+) in focus
+       order. Traversing the tree by following the first entry in this array
+       will result in eventually reaching the one node with +focused+ set to
+       true.
+nodes (array of node)::
+       The tiling (i.e. non-floating) child containers of this node.
+floating_nodes (array of node)::
+       The floating child containers of this node. Only non-empty on nodes with
+       type +workspace+.
 
 Please note that in the following example, I have left out some keys/values
 which are not relevant for the type of the node. Otherwise, the example would
@@ -471,6 +474,7 @@ JSON dump:
 }
 ------------------------
 
+[[_marks_reply]]
 === MARKS reply
 
 The reply consists of a single array of strings for each container that has a
@@ -479,6 +483,7 @@ The order of that array is undefined.
 
 If no window has a mark the response will be the empty array [].
 
+[[_bar_config_reply]]
 === BAR_CONFIG reply
 
 This can be used by third-party workspace bars (especially i3bar, but others
@@ -578,6 +583,7 @@ binding_mode_text/binding_mode_bg/binding_mode_border::
 }
 --------------
 
+[[_version_reply]]
 === VERSION reply
 
 The reply consists of a single JSON dictionary with the following keys:
@@ -610,6 +616,7 @@ loaded_config_file_name (string)::
 }
 -------------------
 
+[[_binding_modes_reply]]
 === BINDING_MODES reply
 
 The reply consists of an array of all currently configured binding modes.
@@ -619,6 +626,18 @@ The reply consists of an array of all currently configured binding modes.
 ["default", "resize"]
 ---------------------
 
+[[_config_reply]]
+=== CONFIG reply
+
+The config reply is a map which currently only contains the "config" member,
+which is a string containing the config file as loaded by i3 most recently.
+
+*Example:*
+-------------------
+{ "config": "font pango:monospace 8\nbindsym Mod4+q exit\n" }
+-------------------
+
+
 == Events
 
 [[events]]
@@ -879,3 +898,63 @@ Rust::
        * https://github.com/tmerr/i3ipc-rs
 OCaml::
        * https://github.com/Armael/ocaml-i3ipc
+
+== Appendix A: Detecting byte order in memory-safe languages
+
+Some programming languages such as Go don’t offer a way to serialize data in the
+native byte order of the machine they’re running on without resorting to tricks
+involving the +unsafe+ package.
+
+The following technique can be used (and will not be broken by changes to i3) to
+detect the byte order i3 is using:
+
+1. The byte order dependent fields of an IPC message are message type and
+   payload length.
+
+   * The message type +RUN_COMMAND+ (0) is the same in big and little endian, so
+     we can use it in either byte order to elicit a reply from i3.
+
+   * The payload length 65536 + 256 (+0x00 01 01 00+) is the same in big and
+     little endian, and also small enough to not worry about memory allocations
+     of that size. We must use payloads of length 65536 + 256 in every message
+     we send, so that i3 will be able to read the entire message regardless of
+     the byte order it uses.
+
+2. Send a big endian encoded message of type +SUBSCRIBE+ (2) with payload `[]`
+   followed by 65536 + 256 - 2 +SPACE+ (ASCII 0x20) bytes.
+
+   * If i3 is running in big endian, this message is treated as a noop,
+     resulting in a +SUBSCRIBE+ reply with payload `{"success":true}`
+     footnote:[A small payload is important: that way, we circumvent dealing
+     with UNIX domain socket buffer sizes, whose size depends on the
+     implementation/operating system. Exhausting such a buffer results in an i3
+     deadlock unless you concurrently read and write, which — depending on the
+     programming language — makes the technique much more complicated.].
+
+   * If i3 is running in little endian, this message is read in its entirety due
+     to the byte order independent payload length, then
+     https://github.com/i3/i3/blob/d726d09d496577d1c337a4b97486f2c9fbc914f1/src/ipc.c#L1188[silently
+     discarded] due to the unknown message type.
+
+3. Send a byte order independent message, i.e. type +RUN_COMMAND+ (0) with
+   payload +nop byte order detection. padding:+, padded to 65536 + 256 bytes
+   with +a+ (ASCII 0x61) bytes. i3 will reply to this message with a reply of
+   type +COMMAND+ (0).
+
+   * The human-readable prefix is in there to not confuse readers of the i3 log.
+
+   * This messages serves as a synchronization primitive so that we know whether
+     i3 discarded the +SUBSCRIBE+ message or didn’t answer it yet.
+
+4. Receive a message header from i3, decoding the message type as big endian.
+
+   * If the message’s reply type is +COMMAND+ (0), i3 is running in little
+     endian (because the +SUBSCRIBE+ message was discarded). Decode the message
+     payload length as little endian, receive the message payload.
+
+   * If the message’s reply type is anything else, i3 is running in big endian
+     (because our big endian encoded +SUBSCRIBE+ message was answered). Decode
+     the message payload length in big endian, receive the message
+     payload. Then, receive the pending +COMMAND+ message reply in big endian.
+
+5. From here on out, send/receive all messages using the detected byte order.