Class: I3::IPC
- Inherits:
-
Object
- Object
- I3::IPC
- Defined in:
- lib/i3-ipc.rb
Defined Under Namespace
Classes: WrongMagicCode, WrongType
Constant Summary collapse
- MAGIC_STRING =
"i3-ipc"
- SOCKET_PATH =
"/tmp/i3-ipc.sock"
- MESSAGE_TYPE_COMMAND =
0
- MESSAGE_TYPE_GET_WORKSPACES =
1
- MESSAGE_TYPE_SUBSCRIBE =
2
- MESSAGE_REPLY_COMMAND =
0
- MESSAGE_REPLY_GET_WORKSPACES =
1
- MESSAGE_REPLY_SUBSCRIBE =
2
- EVENT_MASK =
(1 << 31)
- EVENT_WORKSPACE =
(EVENT_MASK | 0)
Class Method Summary collapse
-
.format(type, payload = nil) ⇒ Object
format the message a typical message looks like “i3-ipc” <message length> <message type> <payload>.
-
.parse_response(response) ⇒ Object
parse a full ipc response similar to handle_response, but parses full reply as received by EventMachine.
-
.subscribe(list, socket_path = SOCKET_PATH, &blk) ⇒ Object
shortcut.
Instance Method Summary collapse
-
#close ⇒ Object
closes the socket connection.
-
#closed? ⇒ Boolean
alias for @socket.closed? for easy access.
-
#command(payload) ⇒ Object
send a command to i3.
-
#connect ⇒ Object
connects to the given socket.
- #format(type, payload = nil) ⇒ Object
-
#get_workspaces ⇒ Object
gets the current workspaces.
-
#handle_response(type) ⇒ Object
reads the reply from the socket and parse the returned json into a ruby object.
-
#initialize(socket_path = SOCKET_PATH, force_connect = false) ⇒ IPC
constructor
connects to the given i3 ipc interface.
- #parse_response(response) ⇒ Object
- #read(len) ⇒ Object
-
#write(msg) ⇒ Object
writes message to the socket if socket is not connected, it connects first.
Constructor Details
#initialize(socket_path = SOCKET_PATH, force_connect = false) ⇒ IPC
connects to the given i3 ipc interface
30 31 32 33 |
# File 'lib/i3-ipc.rb', line 30 def initialize(socket_path=SOCKET_PATH, force_connect=false) @socket_path = socket_path connect if connect end |
Class Method Details
.format(type, payload = nil) ⇒ Object
format the message a typical message looks like
"i3-ipc" <message length> <message type> <payload>
86 87 88 89 90 91 |
# File 'lib/i3-ipc.rb', line 86 def self.format(type, payload=nil) size = payload ? payload.to_s.bytes.count : 0 msg = MAGIC_STRING + [size, type].pack("LL") msg << payload.to_s if payload msg end |
.parse_response(response) ⇒ Object
parse a full ipc response similar to handle_response, but parses full reply as received by EventMachine
returns an Array containing the reply type and the parsed data
103 104 105 106 107 108 109 110 111 112 |
# File 'lib/i3-ipc.rb', line 103 def self.parse_response(response) if response[0, (MAGIC_STRING.length)] != MAGIC_STRING raise WrongMagicCode end len, recv_type = response[6, 8].unpack("LL") answer = response[14, len] [recv_type, ::JSON.parse(answer)] end |
.subscribe(list, socket_path = SOCKET_PATH, &blk) ⇒ Object
shortcut
36 37 38 |
# File 'lib/i3-ipc.rb', line 36 def self.subscribe(list, socket_path=SOCKET_PATH, &blk) Subscription.subscribe(list, socket_path, &blk) end |
Instance Method Details
#close ⇒ Object
closes the socket connection
135 136 137 |
# File 'lib/i3-ipc.rb', line 135 def close @socket.close end |
#closed? ⇒ Boolean
alias for @socket.closed? for easy access
140 141 142 |
# File 'lib/i3-ipc.rb', line 140 def closed? @socket.closed? end |
#command(payload) ⇒ Object
send a command to i3
the payload 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.
returns { “success” => true } for now. i3 does send this reply without checks
48 49 50 51 |
# File 'lib/i3-ipc.rb', line 48 def command(payload) write format(MESSAGE_TYPE_COMMAND, payload) handle_response MESSAGE_TYPE_COMMAND end |
#connect ⇒ Object
connects to the given socket
130 131 132 |
# File 'lib/i3-ipc.rb', line 130 def connect @socket = UNIXSocket.new(@socket_path) end |
#format(type, payload = nil) ⇒ Object
93 94 95 |
# File 'lib/i3-ipc.rb', line 93 def format(type, payload=nil) self.class.format(type, payload) end |
#get_workspaces ⇒ Object
gets the current workspaces. the reply will be the list of workspaces (see the reply section of i3 docu)
56 57 58 59 |
# File 'lib/i3-ipc.rb', line 56 def get_workspaces write format(MESSAGE_TYPE_GET_WORKSPACES) handle_response MESSAGE_TYPE_GET_WORKSPACES end |
#handle_response(type) ⇒ Object
reads the reply from the socket and parse the returned json into a ruby object
throws WrongMagicCode when magic word is wrong throws WrongType if returned type does not match expected
this is a bit duplicated code but I don’t know a way to read the full send reply without knowing its length
70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/i3-ipc.rb', line 70 def handle_response(type) # reads 14 bytes # length of "i3-ipc" + 4 bytes length + 4 bytes type buffer = read 14 raise WrongMagicCode unless buffer[0, (MAGIC_STRING.length)] == MAGIC_STRING len, recv_type = buffer[6..-1].unpack("LL") raise WrongType unless recv_type == type answer = read len ::JSON.parse(answer) end |
#parse_response(response) ⇒ Object
114 115 116 |
# File 'lib/i3-ipc.rb', line 114 def parse_response(response) self.class.parse_response(response) end |
#read(len) ⇒ Object
125 126 127 |
# File 'lib/i3-ipc.rb', line 125 def read(len) @socket.read(len) end |
#write(msg) ⇒ Object
writes message to the socket if socket is not connected, it connects first
120 121 122 123 |
# File 'lib/i3-ipc.rb', line 120 def write(msg) connect if @socket.nil? || closed? @last_write_length = @socket.write msg end |