🛫 An improved Ruby library to control i3wm
Ruby
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
lib
spec
.gitignore
.rspec
.travis.yml
.yardopts
Gemfile
Guardfile
LICENSE.txt
README.md
Rakefile
i3ipc.gemspec

README.md

I3ipc Gem Version Build Status

An improved Ruby library to control i3wm.

i3's interprocess communication (or ipc) 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, i3ipc-gjs, i3ipc-lua and reworked mainly from i3-ipc (thanks to @badboy for this gem).

Installation

Nothing special here:

$ gem install i3ipc

Usage

Usage is very simple and straightforward:

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.

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:

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

>> command = i3.command('this a bad command')
>> puts command[0].success
false
>> puts command[0].error
Expected one of these tokens: <end>, '[', '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:

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

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 Connections for each subscription, since replies to subscription events may be sent by i3 at any time.

Outputs

Reply consists of a list of outputs:

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

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

>> i3.command('mark terminal; focus right; mark vim')

Then can get a list of available marks:

>> puts i3.marks
terminal
vim

And use those marks:

>> i3.command("focus right; [con_mark=\"terminal\"] focus")

Bar config

>> puts i3.bar_config
bar-0

Version

Reply describes a current version of i3 windows manager:

>> 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
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Run tests (bundle exec rspec)
  5. Push to the branch (git push origin my-new-feature)
  6. Create a new Pull Request