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"
- COMMANDS =
[ # 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. [0, :command, :required], # Gets the current workspaces. # The reply will be the list of workspaces # (see the reply section of i3 docu) [1, :get_workspaces, :none], # Gets the current outputs. # The reply will be a JSON-encoded list of outputs # (see the reply section of i3 docu). [3, :get_outputs, :none], # 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 of i3 docu) [4, :get_tree, :none], # 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 the reply section of i3 docu) [5, :get_marks, :none], # 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. [6, :get_bar_config, :optional], ]
- MESSAGE_TYPE_SUBSCRIBE =
Needed because subscribe is handled in submodule.
2
- EVENT_MASK =
(1 << 31)
- EVENT_WORKSPACE =
(EVENT_MASK | 0)
Class Method Summary collapse
-
.format(type, payload = nil) ⇒ Object
Format the message.
- .message_type_subscribe ⇒ Object
-
.parse_response(response) ⇒ Object
Parse a full ipc response.
-
.socket_path ⇒ Object
Get socket path via i3 itself.
-
.subscribe(list, socket_path = nil, &blk) ⇒ Object
shortcut.
Instance Method Summary collapse
-
#close ⇒ Object
Closes the socket connection.
-
#closed? ⇒ Boolean
Alias for @socket.closed? for easy access.
-
#connect ⇒ Object
Connects to the given socket.
- #format(type, payload = nil) ⇒ Object
-
#handle_response(type) ⇒ Object
Reads the reply from the socket and parses the returned json into a ruby object.
-
#initialize(socket = nil, 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.
Constructor Details
#initialize(socket = nil, force_connect = false) ⇒ IPC
connects to the given i3 ipc interface
91 92 93 94 |
# File 'lib/i3-ipc.rb', line 91 def initialize(socket=nil, force_connect=false) @@socket_path = socket if socket 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>
126 127 128 129 130 131 |
# File 'lib/i3-ipc.rb', line 126 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 |
.message_type_subscribe ⇒ Object
56 57 58 |
# File 'lib/i3-ipc.rb', line 56 def self. MESSAGE_TYPE_SUBSCRIBE 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
143 144 145 146 147 148 149 150 151 152 |
# File 'lib/i3-ipc.rb', line 143 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 |
.socket_path ⇒ Object
Get socket path via i3 itself.
84 85 86 |
# File 'lib/i3-ipc.rb', line 84 def self.socket_path @@socket_path ||= `i3 --get-socketpath`.chomp end |
.subscribe(list, socket_path = nil, &blk) ⇒ Object
shortcut
97 98 99 |
# File 'lib/i3-ipc.rb', line 97 def self.subscribe(list, socket_path=nil, &blk) Subscription.subscribe(list, socket_path || self.socket_path, &blk) end |
Instance Method Details
#close ⇒ Object
Closes the socket connection.
175 176 177 |
# File 'lib/i3-ipc.rb', line 175 def close @socket.close end |
#closed? ⇒ Boolean
Alias for @socket.closed? for easy access
180 181 182 |
# File 'lib/i3-ipc.rb', line 180 def closed? @socket.closed? end |
#connect ⇒ Object
Connects to the given socket.
170 171 172 |
# File 'lib/i3-ipc.rb', line 170 def connect @socket = UNIXSocket.new(self.class.socket_path) end |
#format(type, payload = nil) ⇒ Object
133 134 135 |
# File 'lib/i3-ipc.rb', line 133 def format(type, payload=nil) self.class.format(type, payload) end |
#handle_response(type) ⇒ Object
Reads the reply from the socket and parses 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
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/i3-ipc.rb', line 110 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
154 155 156 |
# File 'lib/i3-ipc.rb', line 154 def parse_response(response) self.class.parse_response(response) end |
#read(len) ⇒ Object
165 166 167 |
# File 'lib/i3-ipc.rb', line 165 def read(len) @socket.read(len) end |
#write(msg) ⇒ Object
Writes message to the socket. If socket is not connected, it connects first.
160 161 162 163 |
# File 'lib/i3-ipc.rb', line 160 def write(msg) connect if @socket.nil? || closed? @last_write_length = @socket.write msg end |