resolve #8 Implement support of binding_event

This commit is contained in:
Sergey Naumov
2016-09-04 17:46:37 +03:00
parent c77c5af006
commit 42e4d05b75
3 changed files with 94 additions and 1 deletions

View File

@@ -5,7 +5,7 @@
int main() {
i3ipc::connection conn;
conn.subscribe(i3ipc::ET_WORKSPACE | i3ipc::ET_WINDOW);
conn.subscribe(i3ipc::ET_WORKSPACE | i3ipc::ET_WINDOW | i3ipc::ET_BINDING);
conn.signal_workspace_event.connect([](const i3ipc::workspace_event_t& ev) {
std::cout << "workspace_event: " << (char)ev.type << std::endl;
@@ -13,6 +13,17 @@ int main() {
conn.signal_window_event.connect([](const i3ipc::window_event_t& ev) {
std::cout << "window_event: " << (char)ev.type << std::endl;
});
conn.signal_binding_event.connect([](const i3ipc::binding_t& b) {
std::cout << "binding_event:" << std::endl
<< "\tcommand = \"" << b.command << '"' << std::endl
<< "\tinput_code = " << b.input_code << std::endl
<< "\tsymbol = " << b.symbol << std::endl
<< "\tinput_type = " << static_cast<char>(b.input_type) << std::endl
<< "\tevent_state_mask =" << std::endl;
for (const std::string& s : b.event_state_mask) {
std::cout << "\t\t\"" << s << '"' << std::endl;
}
});
// Don't forget this:
conn.prepare_to_event_handling();

View File

@@ -77,6 +77,7 @@ enum EventType {
ET_MODE = (1 << 2), ///< Output mode event
ET_WINDOW = (1 << 3), ///< Window event
ET_BARCONFIG_UPDATE = (1 << 4), ///< Bar config update event @attention Yet is not implemented as signal in connection
ET_BINDING = (1 << 5), ///< Binding event
};
/**
@@ -130,6 +131,16 @@ enum class ContainerLayout : char {
};
/**
* A type of the input of bindings
*/
enum class InputType : char {
UNKNOWN = '?', //< If got an unknown input_type in binding_event
KEYBOARD = 'k',
MOUSE = 'm',
};
/**
* A node of tree of windows
*/
@@ -174,6 +185,18 @@ struct window_event_t {
};
/**
* A binding
*/
struct binding_t {
std::string command; ///< The i3 command that is configured to run for this binding
std::vector<std::string> event_state_mask; ///< The group and modifier keys that were configured with this binding
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
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
InputType input_type;
};
struct buf_t;
/**
* Connection to the i3
@@ -258,6 +281,7 @@ public:
sigc::signal<void> signal_mode_event; ///< Output mode event signal
sigc::signal<void, const window_event_t&> signal_window_event; ///< Window event signal
sigc::signal<void> signal_barconfig_update_event; ///< Barconfig update event signal
sigc::signal<void, const binding_t&> signal_binding_event; ///< Binding event signal
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
private:
const int32_t m_main_socket;

View File

@@ -155,6 +155,39 @@ static std::shared_ptr<output_t> parse_output_from_json(const Json::Value& val
return p;
}
static std::shared_ptr<binding_t> parse_binding_from_json(const Json::Value& value) {
#define i3IPC_TYPE_STR "PARSE BINDING FROM JSON"
if (value.isNull())
return std::shared_ptr<binding_t>();
IPC_JSON_ASSERT_TYPE_OBJECT(value, "binding")
std::shared_ptr<binding_t> b (new binding_t());
b->command = value["command"].asString();
b->symbol = value["symbol"].asString();
b->input_code = value["input_code"].asInt();
Json::Value input_type = value["input_type"].asString();
if (input_type == "keyboard") {
b->input_type = InputType::KEYBOARD;
} else if (input_type == "mouse") {
b->input_type = InputType::MOUSE;
} else {
b->input_type = InputType::UNKNOWN;
}
Json::Value esm_arr = value["event_state_mask"];
IPC_JSON_ASSERT_TYPE_ARRAY(esm_arr, "event_state_mask")
b->event_state_mask.resize(esm_arr.size());
for (Json::ArrayIndex i = 0; i < esm_arr.size(); i++) {
b->event_state_mask[i] = esm_arr[i].asString();
}
return b;
#undef i3IPC_TYPE_STR
}
std::string get_socketpath() {
std::string str;
@@ -259,6 +292,28 @@ connection::connection(const std::string& socket_path) : m_main_socket(i3_conne
I3IPC_DEBUG("BARCONFIG_UPDATE")
signal_barconfig_update_event.emit();
break;
case ET_BINDING: {
Json::Value root;
IPC_JSON_READ(root);
std::string change = root["change"].asString();
if (change != "run") {
I3IPC_WARN("Got \"" << change << "\" in field \"change\" of binding_event. Expected \"run\"")
}
Json::Value binding_json = root["binding"];
std::shared_ptr<binding_t> bptr;
if (!binding_json.isNull()) {
bptr = parse_binding_from_json(binding_json);
}
if (!bptr) {
I3IPC_ERR("Failed to parse field \"binding\" from binding_event")
} else {
I3IPC_DEBUG("BINDING " << bptr->symbol);
signal_binding_event.emit(*bptr);
}
break;
}
};
});
#undef i3IPC_TYPE_STR
@@ -308,6 +363,9 @@ bool connection::subscribe(const int32_t events) {
if (events & static_cast<int32_t>(ET_BARCONFIG_UPDATE)) {
payload_auss << "\"barconfig_update\",";
}
if (events & static_cast<int32_t>(ET_BINDING)) {
payload_auss << "\"binding\",";
}
payload = payload_auss;
if (payload.empty()) {
return true;