# I3ipc [![Gem Version](https://badge.fury.io/rb/i3ipc.svg)](https://rubygems.org/gems/i3ipc) [![Build Status](https://api.travis-ci.org/veelenga/i3ipc-ruby.svg?branch=master)](https://travis-ci.org/veelenga/i3ipc-ruby) - [Installation](#installation) - [Usage](#usage) - [Command](#command) - [Workspaces](#workspaces) - [Subscribe](#subscribe) - [Outputs](#outputs) - [Tree](#tree) - [Marks](#marks) - [Bar config](#bar-config) - [Version](#version) - [Contributing](#contributing) An improved Ruby library to control [i3wm](http://i3wm.org/). i3's interprocess communication (or [ipc](http://i3wm.org/docs/ipc.html)) is the interface i3 wm uses to receive commands from the clients. It also features a publish/subscribe mechanism for notifying interested parties of window manager events. This gem will be useful for example for controlling i3 windows manager or to get various information like the current workspaces or to implement external workspace bar in `Ruby` language. Inspired by [i3ipc-python](https://github.com/acrisci/i3ipc-python), [i3ipc-gjs](https://github.com/acrisci/i3ipc-gjs), [i3ipc-lua](https://github.com/acrisci/i3ipc-lua) and reworked mainly from [i3-ipc](https://github.com/badboy/i3-ipc) (thanks to [@badboy](https://github.com/badboy) for this gem). ## Installation Nothing special here: ```sh $ gem install i3ipc ``` ## Usage Usage is very simple and straightforward: ```ruby require 'i3ipc' i3 = I3Ipc::Connection.new # communicate with i3 server... # ... i3.close ``` Below you can find examples of usage some replies from local i3 wm. Output depend on my config and will be different in other env. A list of messages to send and replies you can find in [Receiving replies from i3](https://i3wm.org/docs/ipc.html#_receiving_replies_from_i3). Each reply from i3 wm will be parsed and packed in a special object. That object responds to any method with a name of an original name of i3 wm attribute in the reply. So you can access attributes in a very useful way. Find examples below. ### Command Executes one or more command at a time. Reply contains the property `success (bool)` for each command: ```ruby >> command = i3.command('workspace 0; focus left') >> puts command[0] { "success": true } >> puts command[0].success true ``` or a human readable error message in the property `error (string)` ```ruby >> command = i3.command('this a bad command') >> puts command[0].success false >> puts command[0].error Expected one of these tokens: , '[', 'move', 'exec', 'exit', 'restart', 'reload', 'shmlog', 'debuglog', 'border', 'layout', 'append_layout', 'workspace', 'focus', 'kill', 'open', 'fullscreen', 'split', 'floating', 'mark', 'unmark', 'resize', 'rename', 'nop', 'scratchpad', 'mode', 'bar' ``` ### Workspaces Reply consists of a list of workspaces. Each workspace has some properties: ```ruby >> workspaces = i3.workspaces >> puts workspaces[0] { "num": 1, "name": "1 Browse", "visible": true, "focused": false, "rect": { "x": 1366, "y": 20, "width": 1920, "height": 1060 }, "output": "VGA1", "urgent": false } >> puts workspaces[0].name 1 Browse >> puts workspaces[0].rect.width 1920 ``` ### Subscribe Takes an [event](http://i3wm.org/docs/ipc.html#_available_events) and a Proc object. The Proc object will be called with i3's response whenever i3 generates the specified event. `subscribe` returns a Thread; the block will execute in this thread until the thread is killed. ```ruby block = Proc.new do |reply| if reply.change == 'title' puts "title changed for window #{reply.container.name}" end end pid = i3.subscribe('window', block) pid.join ``` It is recommended to use separate `Connection`s for each subscription, since replies to subscription events may be sent by i3 at any time. ### Outputs Reply consists of a list of outputs: ```ruby >> outputs = i3.outputs >> puts oututs[0].name LVDS1 ``` ### Tree The reply consists information about i3 tree. Each node in the tree (representing one container) has some properties: ```ruby >> tree = i3.tree >> puts tree.id 8214416 >> puts tree.nodes[0].name VGA1 ``` ### Marks Reply consists of a single array of string for each container that has a mark. First we need to create some marks: ```ruby >> i3.command('mark terminal; focus right; mark vim') ``` Then can get a list of available marks: ```ruby >> puts i3.marks terminal vim ``` And use those marks: ```ruby >> i3.command("focus right; [con_mark=\"terminal\"] focus") ``` ### Bar config ```ruby >> puts i3.bar_config bar-0 ``` ### Version Reply describes a current version of i3 windows manager: ```ruby >> puts i3.version { "major": 4, "minor": 10, "patch": 2, "human_readable": "4.10.2 (2015-04-16, branch \"4.10.2\")" } ``` ## Contributing 1. Fork it 1. Create your feature branch (`git checkout -b my-new-feature`) 1. Commit your changes (`git commit -am 'Add some feature'`) 1. Run tests (`bundle exec rspec`) 1. Push to the branch (`git push origin my-new-feature`) 1. Create a new Pull Request