]> git.sur5r.net Git - i3/i3/blobdiff - docs/ipc
Merge branch 'master' into next
[i3/i3] / docs / ipc
index 91ab5fa8401f6df1df8690252e1328bb02720f1a..4093ffce26e2233b7258c62bedc4e180b3c70fad 100644 (file)
--- a/docs/ipc
+++ b/docs/ipc
@@ -10,9 +10,12 @@ workspace bar.
 
 The method of choice for IPC in our case is a unix socket because it has very
 little overhead on both sides and is usually available without headaches in
-most languages. In the default configuration file, no ipc-socket path is
-specified and thus no socket is created. The standard path (which +i3-msg+ and
-+i3-input+ use) is +/tmp/i3-ipc.sock+.
+most languages. In the default configuration file, the ipc-socket gets created
+in +/tmp/i3-%u/ipc-socket.%p+ where +%u+ is your UNIX username and +%p+ is the
+PID of i3.
+
+All i3 utilities, like +i3-msg+ and +i3-input+ will read the +I3_SOCKET_PATH+
+X11 property, stored on the X11 root window.
 
 == Establishing a connection
 
@@ -28,10 +31,10 @@ my $sock = IO::Socket::UNIX->new(Peer => '/tmp/i3-ipc.sock');
 
 To send a message to i3, you have to format in the binary message format which
 i3 expects. This format specifies a magic string in the beginning to ensure
-the integrity of messages (to prevent follow-up errors). Afterwards follows
-the length of the payload of the message as 32-bit integer and the type of
-the message as 32-bit integer (the integers are not converted, so they are
-in native byte order).
+the integrity of messages (to prevent follow-up errors). Following the magic
+string comes the length of the payload of the message as 32-bit integer, and
+the type of the message as 32-bit integer (the integers are not converted, so
+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
@@ -49,6 +52,17 @@ GET_WORKSPACES (1)::
 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).
 
 So, a typical message could look like this:
 --------------------------------------------------
@@ -72,11 +86,11 @@ sub format_ipc_command {
 }
 
 $sock->write(format_ipc_command("exit"));
-------------------------------------------------------------
+------------------------------------------------------------------------------
 
 == Receiving replies from i3
 
-Replies of i3 usually consist of a simple string (the length of the string
+Replies from i3 usually consist of a simple string (the length of the string
 is the message_length, so you can consider them length-prefixed) which in turn
 contain the JSON serialization of a data structure. For example, the
 GET_WORKSPACES message returns an array of workspaces (each workspace is a map
@@ -96,6 +110,12 @@ GET_WORKSPACES (1)::
        Reply to the GET_WORKSPACES message.
 SUBSCRIBE (2)::
        Confirmation/Error code for the SUBSCRIBE message.
+GET_OUTPUTS (3)::
+       Reply to the GET_OUTPUTS message.
+GET_TREE (4)::
+       Reply to the GET_TREE message.
+GET_MARKS (5)::
+       Reply to the GET_MARKS message.
 
 === COMMAND reply
 
@@ -124,6 +144,8 @@ visible (boolean)::
 focused (boolean)::
        Whether this workspace currently has the focus (only one workspace
        can have the focus at the same time).
+urgent (boolean)::
+       Whether a window on this workspace has the "urgent" flag set.
 rect (map)::
        The rectangle of this workspace (equals the rect of the output it
        is on), consists of x, y, width, height.
@@ -138,6 +160,7 @@ output (string)::
   "name": "1",
   "visible": true,
   "focused": true,
+  "urgent": false,
   "rect": {
    "x": 0,
    "y": 0,
@@ -151,6 +174,7 @@ output (string)::
   "name": "2",
   "visible": false,
   "focused": false,
+  "urgent": false,
   "rect": {
    "x": 0,
    "y": 0,
@@ -173,6 +197,244 @@ default) or whether a JSON parse error occurred.
 { "success": true }
 -------------------
 
+=== GET_OUTPUTS reply
+
+The reply consists of a serialized list of outputs. Each output has the
+following properties:
+
+name (string)::
+       The name of this output (as seen in +xrandr(1)+). Encoded in UTF-8.
+active (boolean)::
+       Whether this output is currently active (has a valid mode).
+current_workspace (integer)::
+       The current workspace which is visible on this output. +null+ if the
+       output is not active.
+rect (map)::
+       The rectangle of this output (equals the rect of the output it
+       is on), consists of x, y, width, height.
+
+*Example:*
+-------------------
+[
+ {
+  "name": "LVDS1",
+  "active": true,
+  "current_workspace": 4,
+  "rect": {
+   "x": 0,
+   "y": 0,
+   "width": 1280,
+   "height": 800
+  }
+ },
+ {
+  "name": "VGA1",
+  "active": true,
+  "current_workspace": 1,
+  "rect": {
+   "x": 1280,
+   "y": 0,
+   "width": 1280,
+   "height": 1024
+  },
+ }
+]
+-------------------
+
+=== GET_TREE reply
+
+The reply consists of a serialized tree. Each node in the tree (representing
+one container) has at least the properties listed below. While the nodes might
+have more properties, please do not use any properties which are not documented
+here. They are not yet finalized and will probably change!
+
+id (integer)::
+       The internal ID (actually a C pointer value) of this container. Do not
+       make any assumptions about it. You can use it to (re-)identify and
+       address containers when talking to i3.
+name (string)::
+       The internal name of this container. For all containers which are part
+       of the tree structure down to the workspace contents, this is set to a
+       nice human-readable name of the container.
+       For all other containers, the content is not defined (yet).
+border (string)::
+       Can be either "normal", "none" or "1pixel", dependending on the
+       container’s border style.
+layout (string)::
+       Can be either "default", "stacked", "tabbed", "dockarea" or "output".
+       Other values might be possible in the future, should we add new
+       layouts.
+orientation (string)::
+       Can be either "none" (for non-split containers), "horizontal" or
+       "vertical".
+percent (float)::
+       The percentage which this container takes in its parent. A value of
+       +null+ means that the percent property does not make sense for this
+       container, for example for the root container.
+rect (map)::
+       The absolute display coordinates for this container. Display
+       coordinates means that when you have two 1600x1200 monitors on a single
+       X11 Display (the standard way), the coordinates of the first window on
+       the second monitor are +{ "x": 1600, "y": 0, "width": 1600, "height":
+       1200 }+.
+window_rect (map)::
+       The coordinates of the *actual client window* inside its container.
+       These coordinates are relative to the container and do not include the
+       window decoration (which is actually rendered on the parent container).
+       So, when using the +default+ layout, you will have a 2 pixel border on
+       each side, making the window_rect +{ "x": 2, "y": 0, "width": 632,
+       "height": 366 }+ (for example).
+geometry (map)::
+       The original geometry the window specified when i3 mapped it. Used when
+       switching a window to floating mode, for example.
+urgent (bool)::
+       Whether this container (window or workspace) has the urgency hint set.
+focused (bool)::
+       Whether this container is currently focused.
+
+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
+be by far too long (it already is quite long, despite showing only 1 window and
+one dock window).
+
+It is useful to have an overview of the structure before taking a look at the
+JSON dump:
+
+* root
+** LVDS1
+*** topdock
+*** content
+**** workspace 1
+***** window 1
+*** bottomdock
+**** dock window 1
+** VGA1
+
+*Example:*
+-----------------------
+{
+ "id": 6875648,
+ "name": "root",
+ "rect": {
+   "x": 0,
+   "y": 0,
+   "width": 1280,
+   "height": 800
+ },
+ "nodes": [
+
+   {
+    "id": 6878320,
+    "name": "LVDS1",
+    "layout": "output",
+    "rect": {
+      "x": 0,
+      "y": 0,
+      "width": 1280,
+      "height": 800
+    },
+    "nodes": [
+
+      {
+       "id": 6878784,
+       "name": "topdock",
+       "layout": "dockarea",
+       "orientation": "vertical",
+       "rect": {
+         "x": 0,
+        "y": 0,
+        "width": 1280,
+        "height": 0
+       },
+      },
+
+      {
+       "id": 6879344,
+       "name": "content",
+       "rect": {
+         "x": 0,
+        "y": 0,
+        "width": 1280,
+        "height": 782
+       },
+       "nodes": [
+
+         {
+          "id": 6880464,
+         "name": "1",
+         "orientation": "horizontal",
+         "rect": {
+            "x": 0,
+           "y": 0,
+           "width": 1280,
+           "height": 782
+         },
+         "floating_nodes": [],
+         "nodes": [
+
+            {
+             "id": 6929968,
+            "name": "#aa0000",
+            "border": "normal",
+            "percent": 1,
+            "rect": {
+               "x": 0,
+              "y": 18,
+              "width": 1280,
+              "height": 782
+            }
+           }
+
+         ]
+        }
+
+       ]
+      },
+
+      {
+       "id": 6880208,
+       "name": "bottomdock",
+       "layout": "dockarea",
+       "orientation": "vertical",
+       "rect": {
+         "x": 0,
+        "y": 782,
+        "width": 1280,
+        "height": 18
+       },
+       "nodes": [
+
+         {
+          "id": 6931312,
+         "name": "#00aa00",
+         "percent": 1,
+         "rect": {
+            "x": 0,
+           "y": 782,
+           "width": 1280,
+           "height": 18
+         }
+        }
+
+       ]
+      }
+    ]
+   }
+ ]
+}
+
+
+=== GET_MARKS reply
+
+The reply consists of a single array of strings for each container that has a
+mark. The order of that array is undefined. If more than one container has the
+same mark, it will be represented multiple times in the reply (the array
+contents are not unique).
+
+If no window has a mark the response will be the empty array [].
+------------------------
+
+
 == Events
 
 [[events]]
@@ -180,15 +442,16 @@ default) or whether a JSON parse error occurred.
 To get informed when certain things happen in i3, clients can subscribe to
 events. Events consist of a name (like "workspace") and an event reply type
 (like I3_IPC_EVENT_WORKSPACE). The events sent by i3 are in the same format
-as replies to specific commands.
+as replies to specific commands. However, the highest bit of the message type
+is set to 1 to indicate that this is an event reply instead of a normal reply.
 
 Caveat: As soon as you subscribe to an event, it is not guaranteed any longer
 that the requests to i3 are processed in order. This means, the following
 situation can happen: You send a GET_WORKSPACES request but you receive a
 "workspace" event before receiving the reply to GET_WORKSPACES. If your
 program does not want to cope which such kinds of race conditions (an
-event based library may not have a problem here), I advise to create a separate
-connection to receive events.
+event based library may not have a problem here), I suggest you create a
+separate connection to receive events.
 
 === Subscribing to events
 
@@ -201,31 +464,72 @@ type: SUBSCRIBE
 payload: [ "workspace", "focus" ]
 ---------------------------------
 
+
 === Available events
 
-workspace::
+The numbers in parenthesis is the event type (keep in mind that you need to
+strip the highest bit first).
+
+workspace (0)::
        Sent when the user switches to a different workspace, when a new
        workspace is initialized or when a workspace is removed (because the
        last client vanished).
+output (1)::
+       Sent when RandR issues a change notification (of either screens,
+       outputs, CRTCs or output properties).
+
+*Example:*
+--------------------------------------------------------------------
+# the appropriate 4 bytes read from the socket are stored in $input
+
+# unpack a 32-bit unsigned integer
+my $message_type = unpack("L", $input);
+
+# check if the highest bit is 1
+my $is_event = (($message_type >> 31) == 1);
+
+# use the other bits
+my $event_type = ($message_type & 0x7F);
+
+if ($is_event) {
+  say "Received event of type $event_type";
+}
+--------------------------------------------------------------------
 
 === workspace event
 
 This event consists of a single serialized map containing a property
 +change (string)+ which indicates the type of the change ("focus", "init",
-"empty").
+"empty", "urgent").
 
 *Example:*
 ---------------------
 { "change": "focus" }
 ---------------------
 
+=== output event
+
+This event consists of a single serialized map containing a property
++change (string)+ which indicates the type of the change (currently only
+"unspecified").
+
+*Example:*
+---------------------------
+{ "change": "unspecified" }
+---------------------------
+
 == See also
 
 For some languages, libraries are available (so you don’t have to implement
 all this on your own). This list names some (if you wrote one, please let me
 know):
 
+C::
+       i3 includes a headerfile +i3/ipc.h+ which provides you all constants.
+       However, there is no library yet.
 Ruby::
        http://github.com/badboy/i3-ipc
 Perl::
        http://search.cpan.org/search?query=AnyEvent::I3
+Python::
+       http://github.com/thepub/i3ipc