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 @@ - + i3: IPC interface (interprocess communication) @@ -32,7 +32,7 @@ document.addEventListener("DOMContentLoaded", function(){asciidoc.footnotes(); a

IPC interface (interprocess communication)

Michael Stapelberg
<michael@i3wm.org>
-October 2014 +September 2017
Table of Contents
@@ -92,93 +92,100 @@ they are in native byte order).

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. -

-
-
+
+ + +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1. Currently implemented message types
Type (numeric) Type (name) Reply type Purpose

0

RUN_COMMAND

COMMAND

Run the payload as an i3 command (like the commands you can bind to keys).

1

GET_WORKSPACES

WORKSPACES

Get the list of current workspaces.

2

SUBSCRIBE

SUBSCRIBE

Subscribe this IPC connection to the event types specified in the message payload. See [events].

3

GET_OUTPUTS

OUTPUTS

Get the list of current outputs.

4

GET_TREE

TREE

Get the i3 layout tree.

5

GET_MARKS

MARKS

Gets the names of all currently set marks.

6

GET_BAR_CONFIG

BAR_CONFIG

Gets the specified bar configuration or the names of all bar configurations if payload is empty.

7

GET_VERSION

VERSION

Gets the i3 version.

8

GET_BINDING_MODES

BINDING_MODES

Gets the names of all currently configured binding modes.

9

GET_CONFIG

CONFIG

Returns the last loaded i3 config.

10

SEND_TICK

TICK

Sends a tick event with the specified payload.

11

SYNC

SYNC

Sends an i3 sync event with the specified random value to the specified window.

+

So, a typical message could look like this:

@@ -225,7 +232,7 @@ COMMAND (0)

- Confirmation/Error code for the COMMAND message. + Confirmation/Error code for the RUN_COMMAND message.

@@ -292,6 +299,22 @@ BINDING_MODES (8) Reply to the GET_BINDING_MODES message.

+
+GET_CONFIG (9) +
+
+

+ Reply to the GET_CONFIG message. +

+
+
+TICK (10) +
+
+

+ Reply to the SEND_TICK message. +

+
@@ -639,11 +662,22 @@ window (integer)

+window_properties (map) +
+
+

+ X11 window properties title, instance, class, window_role and transient_for. +

+
+
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.

@@ -654,6 +688,34 @@ 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 @@ -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"]
+
+

3.11. 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" }
+
+
+
+

3.12. TICK reply

+

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 }
+
+
+
+

3.13. SYNC reply

+

The reply is a map containing the "success" member. After the reply was +received, the i3 sync message was +responded to.

+

Example:

+
+
+
{ "success": true }
+
+
@@ -1159,6 +1261,13 @@ situation can happen: You send a GET_WORKSPACES request but you receive a program does not want to cope which such kinds of race conditions (an event based library may not have a problem here), I suggest you create a separate connection to receive events.

+

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.

4.1. Subscribing to events

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

+
+tick (7) +
+
+

+ 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:

@@ -1476,6 +1595,27 @@ because of a user action such as a restart or exit command. Th }
+
+

4.10. tick event

+

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"
+}
+
+
@@ -1524,6 +1664,11 @@ Go https://github.com/mdirkse/i3ipc-go

+
  • +

    +https://github.com/i3/go-i3 +

    +
  • @@ -1628,6 +1773,118 @@ OCaml +
    +

    6. 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. +
    3. +

      +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. +

        +
      • +
      +
    4. +
    5. +

      +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. +

        +
      • +
      +
    6. +
    7. +

      +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. +

        +
      • +
      +
    8. +
    9. +

      +From here on out, send/receive all messages using the detected byte order. +

      +
    10. +
    +

    Find an example implementation of this technique in +https://github.com/i3/go-i3/blob/master/byteorder.go

    +
    +