Skip to content

Commit 42e4d05

Browse files
committed
resolve #8 Implement support of binding_event
1 parent c77c5af commit 42e4d05

File tree

3 files changed

+94
-1
lines changed

3 files changed

+94
-1
lines changed

examples/events.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,25 @@
55

66
int main() {
77
i3ipc::connection conn;
8-
conn.subscribe(i3ipc::ET_WORKSPACE | i3ipc::ET_WINDOW);
8+
conn.subscribe(i3ipc::ET_WORKSPACE | i3ipc::ET_WINDOW | i3ipc::ET_BINDING);
99

1010
conn.signal_workspace_event.connect([](const i3ipc::workspace_event_t& ev) {
1111
std::cout << "workspace_event: " << (char)ev.type << std::endl;
1212
});
1313
conn.signal_window_event.connect([](const i3ipc::window_event_t& ev) {
1414
std::cout << "window_event: " << (char)ev.type << std::endl;
1515
});
16+
conn.signal_binding_event.connect([](const i3ipc::binding_t& b) {
17+
std::cout << "binding_event:" << std::endl
18+
<< "\tcommand = \"" << b.command << '"' << std::endl
19+
<< "\tinput_code = " << b.input_code << std::endl
20+
<< "\tsymbol = " << b.symbol << std::endl
21+
<< "\tinput_type = " << static_cast<char>(b.input_type) << std::endl
22+
<< "\tevent_state_mask =" << std::endl;
23+
for (const std::string& s : b.event_state_mask) {
24+
std::cout << "\t\t\"" << s << '"' << std::endl;
25+
}
26+
});
1627

1728
// Don't forget this:
1829
conn.prepare_to_event_handling();

include/i3ipc++/ipc.hpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ enum EventType {
7777
ET_MODE = (1 << 2), ///< Output mode event
7878
ET_WINDOW = (1 << 3), ///< Window event
7979
ET_BARCONFIG_UPDATE = (1 << 4), ///< Bar config update event @attention Yet is not implemented as signal in connection
80+
ET_BINDING = (1 << 5), ///< Binding event
8081
};
8182

8283
/**
@@ -130,6 +131,16 @@ enum class ContainerLayout : char {
130131
};
131132

132133

134+
/**
135+
* A type of the input of bindings
136+
*/
137+
enum class InputType : char {
138+
UNKNOWN = '?', //< If got an unknown input_type in binding_event
139+
KEYBOARD = 'k',
140+
MOUSE = 'm',
141+
};
142+
143+
133144
/**
134145
* A node of tree of windows
135146
*/
@@ -174,6 +185,18 @@ struct window_event_t {
174185
};
175186

176187

188+
/**
189+
* A binding
190+
*/
191+
struct binding_t {
192+
std::string command; ///< The i3 command that is configured to run for this binding
193+
std::vector<std::string> event_state_mask; ///< The group and modifier keys that were configured with this binding
194+
int32_t input_code; ///< If the binding was configured with bindcode, this will be the key code that was given for the binding. If the binding is a mouse binding, it will be the number of the mouse button that was pressed. Otherwise it will be 0
195+
std::string symbol; ///< If this is a keyboard binding that was configured with bindsym, this field will contain the given symbol. Otherwise it will be null
196+
InputType input_type;
197+
};
198+
199+
177200
struct buf_t;
178201
/**
179202
* Connection to the i3
@@ -258,6 +281,7 @@ class connection {
258281
sigc::signal<void> signal_mode_event; ///< Output mode event signal
259282
sigc::signal<void, const window_event_t&> signal_window_event; ///< Window event signal
260283
sigc::signal<void> signal_barconfig_update_event; ///< Barconfig update event signal
284+
sigc::signal<void, const binding_t&> signal_binding_event; ///< Binding event signal
261285
sigc::signal<void, EventType, const std::shared_ptr<const buf_t>&> signal_event; ///< i3 event signal @note Default handler routes event to signal according to type
262286
private:
263287
const int32_t m_main_socket;

src/ipc.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,39 @@ static std::shared_ptr<output_t> parse_output_from_json(const Json::Value& val
155155
return p;
156156
}
157157

158+
static std::shared_ptr<binding_t> parse_binding_from_json(const Json::Value& value) {
159+
#define i3IPC_TYPE_STR "PARSE BINDING FROM JSON"
160+
if (value.isNull())
161+
return std::shared_ptr<binding_t>();
162+
IPC_JSON_ASSERT_TYPE_OBJECT(value, "binding")
163+
std::shared_ptr<binding_t> b (new binding_t());
164+
165+
b->command = value["command"].asString();
166+
b->symbol = value["symbol"].asString();
167+
b->input_code = value["input_code"].asInt();
168+
169+
Json::Value input_type = value["input_type"].asString();
170+
if (input_type == "keyboard") {
171+
b->input_type = InputType::KEYBOARD;
172+
} else if (input_type == "mouse") {
173+
b->input_type = InputType::MOUSE;
174+
} else {
175+
b->input_type = InputType::UNKNOWN;
176+
}
177+
178+
Json::Value esm_arr = value["event_state_mask"];
179+
IPC_JSON_ASSERT_TYPE_ARRAY(esm_arr, "event_state_mask")
180+
181+
b->event_state_mask.resize(esm_arr.size());
182+
183+
for (Json::ArrayIndex i = 0; i < esm_arr.size(); i++) {
184+
b->event_state_mask[i] = esm_arr[i].asString();
185+
}
186+
187+
return b;
188+
#undef i3IPC_TYPE_STR
189+
}
190+
158191

159192
std::string get_socketpath() {
160193
std::string str;
@@ -259,6 +292,28 @@ connection::connection(const std::string& socket_path) : m_main_socket(i3_conne
259292
I3IPC_DEBUG("BARCONFIG_UPDATE")
260293
signal_barconfig_update_event.emit();
261294
break;
295+
case ET_BINDING: {
296+
Json::Value root;
297+
IPC_JSON_READ(root);
298+
std::string change = root["change"].asString();
299+
if (change != "run") {
300+
I3IPC_WARN("Got \"" << change << "\" in field \"change\" of binding_event. Expected \"run\"")
301+
}
302+
303+
Json::Value binding_json = root["binding"];
304+
std::shared_ptr<binding_t> bptr;
305+
if (!binding_json.isNull()) {
306+
bptr = parse_binding_from_json(binding_json);
307+
}
308+
309+
if (!bptr) {
310+
I3IPC_ERR("Failed to parse field \"binding\" from binding_event")
311+
} else {
312+
I3IPC_DEBUG("BINDING " << bptr->symbol);
313+
signal_binding_event.emit(*bptr);
314+
}
315+
break;
316+
}
262317
};
263318
});
264319
#undef i3IPC_TYPE_STR
@@ -308,6 +363,9 @@ bool connection::subscribe(const int32_t events) {
308363
if (events & static_cast<int32_t>(ET_BARCONFIG_UPDATE)) {
309364
payload_auss << "\"barconfig_update\",";
310365
}
366+
if (events & static_cast<int32_t>(ET_BINDING)) {
367+
payload_auss << "\"binding\",";
368+
}
311369
payload = payload_auss;
312370
if (payload.empty()) {
313371
return true;

0 commit comments

Comments
 (0)