- Confirmation/Error code for the COMMAND message. + Confirmation/Error code for the RUN_COMMAND message.
+ Reply to the GET_CONFIG message. +
++ Reply to the SEND_TICK message. +
+X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=docs%2Fipc.html;h=12d7fe831479039151dfd92a5004f60d9d4f6a91;hb=6176c0889b1da4eb1e71dfbb54fee3f48f9781fd;hp=8780aed6288127da18d055d4189f1a0189456c85;hpb=0a716379dbf172d480de4a7fba89dc9c79d6a204;p=i3%2Fi3.github.io diff --git a/docs/ipc.html b/docs/ipc.html index 8780aed..12d7fe8 100644 --- a/docs/ipc.html +++ b/docs/ipc.html @@ -4,7 +4,7 @@
- +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:
- 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. -
-- Gets the current workspaces. The reply will be a JSON-encoded list of - workspaces (see the reply section). -
-- Subscribes your connection to certain events. See [events] for a - description of this message and the concept of events. -
-- Gets the current outputs. The reply will be a JSON-encoded list of outputs - (see the reply section). -
-- 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). -
-- 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). -
-- 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. -
-- Gets the version of i3. The reply will be a JSON-encoded dictionary - with the major, minor, patch and human-readable version. -
-- Gets a list of currently configured binding modes. -
-Type (numeric) | +Type (name) | +Reply type | +Purpose | +
---|---|---|---|
0 |
+RUN_COMMAND |
++ | Run the payload as an i3 command (like the commands you can bind to keys). |
+
1 |
+GET_WORKSPACES |
++ | Get the list of current workspaces. |
+
2 |
+SUBSCRIBE |
++ | Subscribe this IPC connection to the event types specified in the message payload. See [events]. |
+
3 |
+GET_OUTPUTS |
++ | Get the list of current outputs. |
+
4 |
+GET_TREE |
++ | Get the i3 layout tree. |
+
5 |
+GET_MARKS |
++ | Gets the names of all currently set marks. |
+
6 |
+GET_BAR_CONFIG |
++ | Gets the specified bar configuration or the names of all bar configurations if payload is empty. |
+
7 |
+GET_VERSION |
++ | Gets the i3 version. |
+
8 |
+GET_BINDING_MODES |
++ | Gets the names of all currently configured binding modes. |
+
9 |
+GET_CONFIG |
++ | Returns the last loaded i3 config. |
+
10 |
+SEND_TICK |
++ | Sends a tick event with the specified payload. |
+
11 |
+SYNC |
++ | Sends an i3 sync event with the specified random value to the specified window. |
+
So, a typical message could look like this:
- Confirmation/Error code for the COMMAND message. + Confirmation/Error code for the RUN_COMMAND message.
+ Reply to the GET_CONFIG message. +
++ Reply to the SEND_TICK message. +
++ X11 window properties title, instance, class, window_role and transient_for. +
+- 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.
+ 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. +
++ The tiling (i.e. non-floating) child containers of this 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 @@ -778,6 +840,12 @@ VGA1 "width": 1280, "height": 782 }, + "window_properties": { + "class": "Evince", + "instance": "evince", + "title": "Properties", + "transient_for": 52428808 + }, "floating_nodes": [], "nodes": [ @@ -1142,6 +1210,40 @@ loaded_config_file_name (string)
["default", "resize"]
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" }+
The reply is a map containing the "success" member. After the reply was +received, the tick event has been written to all IPC connections which subscribe +to tick events. UNIX sockets are usually buffered, but you can be certain that +once you receive the tick event you just triggered, you must have received all +events generated prior to the SEND_TICK message (happened-before relation).
Example:
{ "success": true }+
The reply is a map containing the "success" member. After the reply was +received, the i3 sync message was +responded to.
Example:
{ "success": true }+
If an event message needs to be sent and the socket is not writeable (write +returns EAGAIN, happens when the socket doesn’t have enough buffer space for +writing new data) then i3 uses a queue system to store outgoing messages for +each client. This is combined with a timer: if the message queue for a client is +not empty and no data where successfully written in the past 10 seconds, the +connection is killed. Practically, this means that your client should try to +always read events from the socket to avoid having its connection closed.
By sending a message of type SUBSCRIBE with a JSON-encoded array as payload @@ -1238,6 +1347,16 @@ shutdown (6) Sent when the ipc shuts down because of a restart or exit by user command
++ Sent when the ipc client subscribes to the tick event (with "first": + true) or when any ipc client sends a SEND_TICK message (with "first": + false). +
+Example:
This event is triggered by a subscription to tick events or by a SEND_TICK +message.
Example (upon subscription):
{ + "first": true, + "payload": "" +}+
Example (upon SEND_TICK with a payload of arbitrary string):
{ + "first": false, + "payload": "arbitrary string" +}+
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:
+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. +
++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}
+
[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 + silently + discarded due to the unknown message type. +
++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. +
++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. +
++From here on out, send/receive all messages using the detected byte order. +
+Find an example implementation of this technique in +https://github.com/i3/go-i3/blob/master/byteorder.go