]> git.sur5r.net Git - i3/i3.github.io/blobdiff - _docs/ipc
update docs/debugging from git
[i3/i3.github.io] / _docs / ipc
index 5db6f00e55653f597ed4d8cd8c1f565b408e52c3..85e5e77e3e7966122f2835c716ac31d07ee35aef 100644 (file)
--- a/_docs/ipc
+++ b/_docs/ipc
@@ -1,7 +1,7 @@
 IPC interface (interprocess communication)
 ==========================================
-Michael Stapelberg <michael+i3@stapelberg.de>
-March 2010
+Michael Stapelberg <michael@i3wm.org>
+October 2012
 
 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
@@ -10,9 +10,21 @@ 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 +~/.i3/ipc.sock+.
+most languages. In the default configuration file, the ipc-socket gets created
+in +/tmp/i3-%u.XXXXXX/ipc-socket.%p+ where +%u+ is your UNIX username, +%p+ is
+the PID of i3 and XXXXXX is a string of random characters from the portable
+filename character set (see mkdtemp(3)). You can get the socketpath from i3 by
+calling +i3 --get-socketpath+.
+
+All i3 utilities, like +i3-msg+ and +i3-input+ will read the +I3_SOCKET_PATH+
+X11 property, stored on the X11 root window.
+
+[WARNING]
+.Use an existing library!
+There are existing libraries for many languages. You can have a look at
+<<libraries>> or search the web if your language of choice is not mentioned.
+Usually, it is not necessary to implement low-level communication with i3
+directly.
 
 == Establishing a connection
 
@@ -21,7 +33,8 @@ snippet illustrates this in Perl:
 
 -------------------------------------------------------------
 use IO::Socket::UNIX;
-my $sock = IO::Socket::UNIX->new(Peer => '~/.i3/ipc.sock');
+chomp(my $path = qx(i3 --get-socketpath));
+my $sock = IO::Socket::UNIX->new(Peer => $path);
 -------------------------------------------------------------
 
 == Sending messages to i3
@@ -42,7 +55,7 @@ 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. There is no reply to this message.
+       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).
@@ -52,6 +65,21 @@ SUBSCRIBE (2)::
 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.
 
 So, a typical message could look like this:
 --------------------------------------------------
@@ -61,7 +89,7 @@ So, a typical message could look like this:
 Or, as a hexdump:
 ------------------------------------------------------------------------------
 00000000  69 33 2d 69 70 63 04 00  00 00 00 00 00 00 65 78  |i3-ipc........ex|
-00000010  69 74 0a                                          |it.|
+00000010  69 74                                             |it|
 ------------------------------------------------------------------------------
 
 To generate and send such a message, you could use the following code in Perl:
@@ -95,12 +123,20 @@ The following reply types are implemented:
 
 COMMAND (0)::
        Confirmation/Error code for the COMMAND message.
-GET_WORKSPACES (1)::
+WORKSPACES (1)::
        Reply to the GET_WORKSPACES message.
 SUBSCRIBE (2)::
        Confirmation/Error code for the SUBSCRIBE message.
-GET_OUTPUTS (3)::
+OUTPUTS (3)::
        Reply to the GET_OUTPUTS message.
+TREE (4)::
+       Reply to the GET_TREE message.
+MARKS (5)::
+       Reply to the GET_MARKS message.
+BAR_CONFIG (6)::
+       Reply to the GET_BAR_CONFIG message.
+VERSION (7)::
+       Reply to the GET_VERSION message.
 
 === COMMAND reply
 
@@ -112,7 +148,7 @@ property is +success (bool)+, but this will be expanded in future versions.
 { "success": true }
 -------------------
 
-=== GET_WORKSPACES reply
+=== WORKSPACES reply
 
 The reply consists of a serialized list of workspaces. Each workspace has the
 following properties:
@@ -182,7 +218,7 @@ default) or whether a JSON parse error occurred.
 { "success": true }
 -------------------
 
-=== GET_OUTPUTS reply
+=== OUTPUTS reply
 
 The reply consists of a serialized list of outputs. Each output has the
 following properties:
@@ -226,6 +262,325 @@ rect (map)::
 ]
 -------------------
 
+=== 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.
+current_border_width (integer)::
+       Number of pixels of the border width.
+layout (string)::
+       Can be either "splith", "splitv", "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".
+       THIS FIELD IS OBSOLETE. It is still present, but your code should not
+       use it. Instead, rely on the layout field.
+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.
+window (integer)::
+       The X11 window ID of the *actual client window* inside this container.
+       This field is set to null for split containers or otherwise empty
+       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.
+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
+         }
+        }
+
+       ]
+      }
+    ]
+   }
+ ]
+}
+------------------------
+
+=== MARKS reply
+
+The reply consists of a single array of strings for each container that has a
+mark. A mark can only be set on one container, so the array is unique.
+The order of that array is undefined.
+
+If no window has a mark the response will be the empty array [].
+
+=== BAR_CONFIG reply
+
+This can be used by third-party workspace bars (especially i3bar, but others
+are free to implement compatible alternatives) to get the +bar+ block
+configuration from i3.
+
+Depending on the input, the reply is either:
+
+empty input::
+       An array of configured bar IDs
+Bar ID::
+       A JSON map containing the configuration for the specified bar.
+
+Each bar configuration has the following properties:
+
+id (string)::
+       The ID for this bar. Included in case you request multiple
+       configurations and want to differentiate the different replies.
+mode (string)::
+       Either +dock+ (the bar sets the dock window type) or +hide+ (the bar
+       does not show unless a specific key is pressed).
+position (string)::
+       Either +bottom+ or +top+ at the moment.
+status_command (string)::
+       Command which will be run to generate a statusline. Each line on stdout
+       of this command will be displayed in the bar. At the moment, no
+       formatting is supported.
+font (string)::
+       The font to use for text on the bar.
+workspace_buttons (boolean)::
+       Display workspace buttons or not? Defaults to true.
+binding_mode_indicator (boolean)::
+       Display the mode indicator or not? Defaults to true.
+verbose (boolean)::
+       Should the bar enable verbose output for debugging? Defaults to false.
+colors (map)::
+       Contains key/value pairs of colors. Each value is a color code in hex,
+       formatted #rrggbb (like in HTML).
+
+The following colors can be configured at the moment:
+
+background::
+       Background color of the bar.
+statusline::
+       Text color to be used for the statusline.
+separator::
+       Text color to be used for the separator.
+focused_workspace_text/focused_workspace_bg::
+       Text color/background color for a workspace button when the workspace
+       has focus.
+active_workspace_text/active_workspace_bg::
+       Text color/background color for a workspace button when the workspace
+       is active (visible) on some output, but the focus is on another one.
+       You can only tell this apart from the focused workspace when you are
+       using multiple monitors.
+inactive_workspace_text/inactive_workspace_bg::
+       Text color/background color for a workspace button when the workspace
+       does not have focus and is not active (visible) on any output. This
+       will be the case for most workspaces.
+urgent_workspace_text/urgent_workspace_bar::
+       Text color/background color for workspaces which contain at least one
+       window with the urgency hint set.
+
+
+*Example of configured bars:*
+--------------
+["bar-bxuqzf"]
+--------------
+
+*Example of bar configuration:*
+--------------
+{
+ "id": "bar-bxuqzf",
+ "mode": "dock",
+ "position": "bottom",
+ "status_command": "i3status",
+ "font": "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1",
+ "workspace_buttons": true,
+ "binding_mode_indicator": true,
+ "verbose": false,
+ "colors": {
+   "background": "#c0c0c0",
+   "statusline": "#00ff00",
+   "focused_workspace_text": "#ffffff",
+   "focused_workspace_bg": "#000000"
+ }
+}
+--------------
+
+=== VERSION reply
+
+The reply consists of a single JSON dictionary with the following keys:
+
+major (integer)::
+       The major version of i3, such as +4+.
+minor (integer)::
+       The minor version of i3, such as +2+. Changes in the IPC interface (new
+       features) will only occur with new minor (or major) releases. However,
+       bugfixes might be introduced in patch releases, too.
+patch (integer)::
+       The patch version of i3, such as +1+ (when the complete version is
+       +4.2.1+). For versions such as +4.2+, patch will be set to +0+.
+human_readable (string)::
+       A human-readable version of i3 containing the precise git version,
+       build date and branch name. When you need to display the i3 version to
+       your users, use the human-readable version whenever possible (since
+       this is what +i3 --version+ displays, too).
+
+*Example:*
+-------------------
+{
+   "human_readable" : "4.2-169-gf80b877 (2012-08-05, branch \"next\")",
+   "minor" : 2,
+   "patch" : 0,
+   "major" : 4
+}
+-------------------
+
 == Events
 
 [[events]]
@@ -268,6 +623,14 @@ workspace (0)::
 output (1)::
        Sent when RandR issues a change notification (of either screens,
        outputs, CRTCs or output properties).
+mode (2)::
+       Sent whenever i3 changes its binding mode.
+window (3)::
+       Sent when a client's window is successfully reparented (that is when i3
+       has finished fitting it into a container).
+barconfig_update (4)::
+    Sent when the hidden_state or mode field in the barconfig of any bar
+    instance was updated.
 
 *Example:*
 --------------------------------------------------------------------
@@ -293,9 +656,29 @@ This event consists of a single serialized map containing a property
 +change (string)+ which indicates the type of the change ("focus", "init",
 "empty", "urgent").
 
+Moreover, when the change is "focus", an +old (object)+ and a +current
+(object)+ properties will be present with the previous and current
+workspace respectively.  When the first switch occurs (when i3 focuses
+the workspace visible at the beginning) there is no previous
+workspace, and the +old+ property will be set to +null+.  Also note
+that if the previous is empty it will get destroyed when switching,
+but will still be present in the "old" property.
+
 *Example:*
 ---------------------
-{ "change": "focus" }
+{
+ "change": "focus",
+ "current": {
+  "id": 28489712,
+  "type":4,
+  ...
+ }
+ "old": {
+  "id": 28489715,
+  "type": 4,
+  ...
+ }
+}
 ---------------------
 
 === output event
@@ -309,7 +692,63 @@ This event consists of a single serialized map containing a property
 { "change": "unspecified" }
 ---------------------------
 
-== See also
+=== mode event
+
+This event consists of a single serialized map containing a property
++change (string)+ which holds the name of current mode in use. The name
+is the same as specified in config when creating a mode. The default
+mode is simply named default.
+
+*Example:*
+---------------------------
+{ "change": "default" }
+---------------------------
+
+=== window event
+
+This event consists of a single serialized map containing a property
++change (string)+ which currently can indicate only that a new window
+has been successfully reparented (the value will be "new").
+
+Additionally a +container (object)+ field will be present, which consists
+of the window's parent container. Be aware that the container will hold
+the initial name of the newly reparented window (e.g. if you run urxvt
+with a shell that changes the title, you will still at this point get the
+window title as "urxvt").
+
+*Example:*
+---------------------------
+{
+ "change": "new",
+ "container": {
+  "id": 35569536,
+  "type": 2,
+  ...
+ }
+}
+---------------------------
+
+=== barconfig_update event
+
+This event consists of a single serialized map reporting on options from the
+barconfig of the specified bar_id that were updated in i3. The map always
+consists of a property +id (string)+, which specifies to which bar instance the
+sent config update belongs, a property +hidden_state (string)+, which indicates
+the hidden_state of an i3bar instance, and a property +mode (string)+, which
+corresponds to the current mode.
+
+*Example:*
+---------------------------
+{
+    "id": "bar-0",
+    "hidden_state": "hide"
+    "mode": "hide"
+}
+---------------------------
+
+== See also (existing libraries)
+
+[[libraries]]
 
 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
@@ -321,6 +760,9 @@ C::
 Ruby::
        http://github.com/badboy/i3-ipc
 Perl::
-       http://search.cpan.org/search?query=AnyEvent::I3
+       https://metacpan.org/module/AnyEvent::I3
 Python::
-       http://github.com/thepub/i3ipc
+       * https://github.com/whitelynx/i3ipc
+       * https://github.com/ziberna/i3-py (includes higher-level features)
+Go::
+       * https://github.com/proxypoke/i3ipc