refactor(modules): Input handling

This commit is contained in:
Michael Carlberg 2016-12-23 20:43:52 +01:00
parent 99764b930e
commit b422d1d1a4
23 changed files with 55 additions and 93 deletions

View File

@ -26,6 +26,7 @@ class signal_emitter;
namespace modules { namespace modules {
struct module_interface; struct module_interface;
class input_handler;
} }
using module_t = unique_ptr<modules::module_interface>; using module_t = unique_ptr<modules::module_interface>;
@ -42,7 +43,7 @@ namespace sig_ui = signals::ui;
namespace sig_ipc = signals::ipc; namespace sig_ipc = signals::ipc;
class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, sig_ev::process_broadcast, sig_ev::process_update, class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, sig_ev::process_broadcast, sig_ev::process_update,
sig_ev::process_input, sig_ev::process_quit, sig_ev::process_check, sig_ipc::process_action, sig_ev::process_quit, sig_ev::process_check, sig_ipc::process_action,
sig_ipc::process_command, sig_ipc::process_hook, sig_ui::button_press> { sig_ipc::process_command, sig_ipc::process_hook, sig_ui::button_press> {
public: public:
using make_type = unique_ptr<controller>; using make_type = unique_ptr<controller>;
@ -55,7 +56,7 @@ class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, sig_ev::proc
bool run(bool writeback = false); bool run(bool writeback = false);
bool enqueue(event&& evt); bool enqueue(event&& evt);
bool enqueue(string&& input_data); bool enqueue(string&& input);
protected: protected:
void read_events(); void read_events();
@ -64,7 +65,6 @@ class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, sig_ev::proc
bool on(const sig_ev::process_broadcast& evt); bool on(const sig_ev::process_broadcast& evt);
bool on(const sig_ev::process_update& evt); bool on(const sig_ev::process_update& evt);
bool on(const sig_ev::process_input& evt);
bool on(const sig_ev::process_quit& evt); bool on(const sig_ev::process_quit& evt);
bool on(const sig_ev::process_check& evt); bool on(const sig_ev::process_check& evt);
bool on(const sig_ui::button_press& evt); bool on(const sig_ui::button_press& evt);
@ -106,7 +106,7 @@ class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, sig_ev::proc
/** /**
* @brief Module input handlers * @brief Module input handlers
*/ */
vector<signal_receiver_interface*> m_inputhandlers; vector<modules::input_handler*> m_inputhandlers;
/** /**
* @brief Maximum number of subsequent events to swallow * @brief Maximum number of subsequent events to swallow

View File

@ -94,9 +94,8 @@ namespace signals {
namespace eventqueue { namespace eventqueue {
DEFINE_VALUE_SIGNAL(1, process_quit, event); DEFINE_VALUE_SIGNAL(1, process_quit, event);
DEFINE_VALUE_SIGNAL(2, process_update, event); DEFINE_VALUE_SIGNAL(2, process_update, event);
DEFINE_VALUE_SIGNAL(3, process_input, string); DEFINE_SIGNAL(3, process_check);
DEFINE_SIGNAL(4, process_check); DEFINE_SIGNAL(4, process_broadcast);
DEFINE_SIGNAL(5, process_broadcast);
} }
namespace ipc { namespace ipc {

View File

@ -8,7 +8,6 @@ namespace signals {
namespace eventqueue { namespace eventqueue {
struct process_quit; struct process_quit;
struct process_update; struct process_update;
struct process_input;
struct process_check; struct process_check;
struct process_broadcast; struct process_broadcast;
} }

View File

@ -47,7 +47,7 @@ namespace modules {
bool build(builder* builder, const string& tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
bool on(const input_event_t& evt); bool input(string&& cmd);
private: private:
static constexpr auto DEFAULT_ICON = "ws-icon-default"; static constexpr auto DEFAULT_ICON = "ws-icon-default";

View File

@ -14,7 +14,7 @@ namespace modules {
bool build(builder* builder, const string& tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
bool on(const input_event_t& evt); bool input(string&& cmd);
private: private:
static constexpr auto TAG_LABEL = "<label>"; static constexpr auto TAG_LABEL = "<label>";

View File

@ -42,7 +42,7 @@ namespace modules {
bool build(builder* builder, const string& tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
bool on(const input_event_t& evt); bool input(string&& cmd);
private: private:
static constexpr const char* DEFAULT_TAGS{"<label-state> <label-mode>"}; static constexpr const char* DEFAULT_TAGS{"<label-state> <label-mode>"};

View File

@ -24,7 +24,7 @@ namespace modules {
void update() {} void update() {}
protected: protected:
bool on(const input_event_t& evt); bool input(string&& cmd);
private: private:
static constexpr auto TAG_LABEL_TOGGLE = "<label-toggle>"; static constexpr auto TAG_LABEL_TOGGLE = "<label-toggle>";

View File

@ -1,16 +1,14 @@
#pragma once #pragma once
#include "common.hpp" #include "common.hpp"
#include "events/signal.hpp"
#include "events/signal_receiver.hpp"
POLYBAR_NS POLYBAR_NS
namespace modules { namespace modules {
using input_event_t = signals::eventqueue::process_input; class input_handler {
class input_handler : public signal_receiver<0, input_event_t> {
public: public:
virtual ~input_handler() {} virtual ~input_handler() {}
virtual bool input(string&& cmd) = 0;
}; };
} }

View File

@ -27,7 +27,7 @@ namespace modules {
bool build(builder* builder, const string& tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
bool on(const input_event_t& evt); bool input(string&& cmd);
private: private:
static constexpr const char* FORMAT_ONLINE{"format-online"}; static constexpr const char* FORMAT_ONLINE{"format-online"};

View File

@ -31,7 +31,7 @@ namespace modules {
bool build(builder* builder, const string& tag) const; bool build(builder* builder, const string& tag) const;
protected: protected:
bool on(const input_event_t& evt); bool input(string&& cmd);
private: private:
static constexpr auto FORMAT_VOLUME = "format-volume"; static constexpr auto FORMAT_VOLUME = "format-volume";

View File

@ -37,7 +37,7 @@ namespace modules {
protected: protected:
void handle(const evt::randr_notify& evt); void handle(const evt::randr_notify& evt);
bool on(const input_event_t& evt); bool input(string&& cmd);
private: private:
static constexpr const char* TAG_LABEL{"<label>"}; static constexpr const char* TAG_LABEL{"<label>"};

View File

@ -36,7 +36,7 @@ namespace modules {
void handle(const evt::xkb_state_notify& evt); void handle(const evt::xkb_state_notify& evt);
void handle(const evt::xkb_indicator_state_notify& evt); void handle(const evt::xkb_indicator_state_notify& evt);
bool on(const input_event_t&); bool input(string&& cmd);
private: private:
static constexpr const char* TAG_LABEL_LAYOUT{"<label-layout>"}; static constexpr const char* TAG_LABEL_LAYOUT{"<label-layout>"};

View File

@ -63,7 +63,7 @@ namespace modules {
void handle(const evt::property_notify& evt); void handle(const evt::property_notify& evt);
void rebuild_desktops(); void rebuild_desktops();
void set_current_desktop(); void set_current_desktop();
bool on(const input_event_t&); bool input(string&& cmd);
private: private:
static constexpr const char* DEFAULT_ICON{"icon-default"}; static constexpr const char* DEFAULT_ICON{"icon-default"};

View File

@ -363,17 +363,31 @@ void controller::process_eventqueue() {
*/ */
void controller::process_inputdata() { void controller::process_inputdata() {
if (!m_inputdata.empty()) { if (!m_inputdata.empty()) {
auto evt = sig_ev::process_input{string{m_inputdata}}; string cmd = m_inputdata;
m_lastinput = chrono::time_point_cast<decltype(m_swallow_input)>(chrono::system_clock::now()); m_lastinput = chrono::time_point_cast<decltype(m_swallow_input)>(chrono::system_clock::now());
m_inputdata.clear(); m_inputdata.clear();
for (auto&& handler : m_inputhandlers) { for (auto&& handler : m_inputhandlers) {
if (handler->on(evt)) { if (handler->input(string{cmd})) {
return; return;
} }
} }
m_sig.emit(evt); try {
m_log.warn("Uncaught input event, forwarding to shell... (input: %s)", cmd);
if (m_command) {
m_log.warn("Terminating previous shell command");
m_command->terminate();
}
m_log.info("Executing shell command: %s", cmd);
m_command = command_util::make_command(move(cmd));
m_command->exec();
m_command.reset();
} catch (const application_error& err) {
m_log.err("controller: Error while forwarding input to shell -> %s", err.what());
}
} }
} }
@ -472,31 +486,6 @@ bool controller::on(const sig_ev::process_update& evt) {
return true; return true;
} }
/**
* Process eventqueue input event
*/
bool controller::on(const sig_ev::process_input& evt) {
try {
string input{*evt()};
m_log.warn("Uncaught input event, forwarding to shell... (input: %s)", input);
if (m_command) {
m_log.warn("Terminating previous shell command");
m_command->terminate();
}
m_log.info("Executing shell command: %s", input);
m_command = command_util::make_command(move(input));
m_command->exec();
m_command.reset();
} catch (const application_error& err) {
m_log.err("controller: Error while forwarding input to shell -> %s", err.what());
}
return true;
}
/** /**
* Process eventqueue quit event * Process eventqueue quit event
*/ */

View File

@ -417,9 +417,7 @@ namespace modules {
return false; return false;
} }
bool bspwm_module::on(const input_event_t& evt) { bool bspwm_module::input(string&& cmd) {
string cmd{*evt.data()};
if (cmd.find(EVENT_PREFIX) != 0) { if (cmd.find(EVENT_PREFIX) != 0) {
return false; return false;
} }

View File

@ -84,13 +84,10 @@ namespace modules {
return true; return true;
} }
bool date_module::on(const input_event_t& evt) { bool date_module::input(string&& cmd) {
string cmd{*evt.data()};
if (cmd != EVENT_TOGGLE) { if (cmd != EVENT_TOGGLE) {
return false; return false;
} }
m_toggled = !m_toggled; m_toggled = !m_toggled;
wakeup(); wakeup();
return true; return true;

View File

@ -191,9 +191,7 @@ namespace modules {
return true; return true;
} }
bool i3_module::on(const input_event_t& evt) { bool i3_module::input(string&& cmd) {
string cmd{*evt.data()};
if (cmd.find(EVENT_PREFIX) != 0) { if (cmd.find(EVENT_PREFIX) != 0) {
return false; return false;
} }
@ -205,11 +203,10 @@ namespace modules {
const connection_t conn{}; const connection_t conn{};
if (cmd.compare(0, strlen(EVENT_CLICK), EVENT_CLICK) == 0) { if (cmd.compare(0, strlen(EVENT_CLICK), EVENT_CLICK) == 0) {
const string workspace_num{cmd.substr(strlen(EVENT_CLICK))}; cmd.erase(0, strlen(EVENT_CLICK));
if (focused_workspace(conn)->num != atoi(cmd.c_str())) {
if (focused_workspace(conn)->num != atoi(workspace_num.c_str())) {
m_log.info("%s: Sending workspace focus command to ipc handler", name()); m_log.info("%s: Sending workspace focus command to ipc handler", name());
conn.send_command("workspace number " + workspace_num); conn.send_command("workspace number " + cmd);
} }
} else if (cmd.compare(0, strlen(EVENT_SCROLL_UP), EVENT_SCROLL_UP) == 0) { } else if (cmd.compare(0, strlen(EVENT_SCROLL_UP), EVENT_SCROLL_UP) == 0) {
scrolldir = m_revscroll ? "prev" : "next"; scrolldir = m_revscroll ? "prev" : "next";

View File

@ -80,9 +80,7 @@ namespace modules {
return true; return true;
} }
bool menu_module::on(const input_event_t& evt) { bool menu_module::input(string&& cmd) {
string cmd{*evt.data()};
if (cmd.compare(0, 4, "menu") != 0) { if (cmd.compare(0, 4, "menu") != 0) {
return false; return false;
} }

View File

@ -316,9 +316,7 @@ namespace modules {
return true; return true;
} }
bool mpd_module::on(const input_event_t& evt) { bool mpd_module::input(string&& cmd) {
string cmd{*evt.data()};
if (cmd.compare(0, 3, "mpd") != 0) { if (cmd.compare(0, 3, "mpd") != 0) {
return false; return false;
} }

View File

@ -209,9 +209,7 @@ namespace modules {
return true; return true;
} }
bool volume_module::on(const input_event_t& evt) { bool volume_module::input(string&& cmd) {
string cmd{*evt.data()};
if (cmd.compare(0, 3, EVENT_PREFIX) != 0) { if (cmd.compare(0, 3, EVENT_PREFIX) != 0) {
return false; return false;
} }

View File

@ -150,9 +150,7 @@ namespace modules {
/** /**
* Process scroll events by changing backlight value * Process scroll events by changing backlight value
*/ */
bool xbacklight_module::on(const input_event_t& evt) { bool xbacklight_module::input(string&& cmd) {
string cmd{*evt.data()};
int value_mod = 0; int value_mod = 0;
if (cmd == EVENT_SCROLLUP) { if (cmd == EVENT_SCROLLUP) {

View File

@ -104,9 +104,7 @@ namespace modules {
/** /**
* Handle input command * Handle input command
*/ */
bool xkeyboard_module::on(const input_event_t& evt) { bool xkeyboard_module::input(string&& cmd) {
string cmd{*evt.data()};
if (cmd.compare(0, strlen(EVENT_SWITCH), EVENT_SWITCH) != 0) { if (cmd.compare(0, strlen(EVENT_SWITCH), EVENT_SWITCH) != 0) {
return false; return false;
} }

View File

@ -208,13 +208,12 @@ namespace modules {
return false; return false;
} }
bool xworkspaces_module::on(const input_event_t& evt) { bool xworkspaces_module::input(string&& cmd) {
string cmd{*evt.data()}; size_t len{strlen(EVENT_PREFIX)};
if (cmd.find(EVENT_PREFIX) != 0) { if (cmd.compare(0, len, EVENT_PREFIX) != 0) {
return false; return false;
} }
cmd.erase(0, len);
cmd.erase(0, strlen(EVENT_PREFIX));
uint32_t new_desktop{0}; uint32_t new_desktop{0};
uint32_t min_desktop{0}; uint32_t min_desktop{0};
@ -233,26 +232,22 @@ namespace modules {
} }
} }
if (cmd.compare(0, strlen(EVENT_CLICK), EVENT_CLICK) == 0) { if ((len = strlen(EVENT_CLICK)) && cmd.compare(0, len, EVENT_CLICK) == 0) {
new_desktop = atoi(cmd.substr(strlen(EVENT_CLICK)).c_str()); new_desktop = std::strtoul(cmd.substr(len).c_str(), nullptr, 10);
} else if ((len = strlen(EVENT_SCROLL_UP)) && cmd.compare(0, len, EVENT_SCROLL_UP) == 0) {
} else if (cmd.compare(0, strlen(EVENT_SCROLL_UP), EVENT_SCROLL_UP) == 0) {
new_desktop = math_util::min<uint32_t>(max_desktop, current_desktop + 1); new_desktop = math_util::min<uint32_t>(max_desktop, current_desktop + 1);
if (new_desktop == current_desktop) { if (new_desktop == current_desktop) {
new_desktop = min_desktop; new_desktop = min_desktop;
} }
} else if ((len = strlen(EVENT_SCROLL_DOWN)) && cmd.compare(0, len, EVENT_SCROLL_DOWN) == 0) {
} else if (cmd.compare(0, strlen(EVENT_SCROLL_DOWN), EVENT_SCROLL_DOWN) == 0) { new_desktop = math_util::max<uint32_t>(min_desktop, std::max(0U, current_desktop - 1));
new_desktop = math_util::max<uint32_t>(min_desktop, current_desktop - 1);
if (new_desktop == current_desktop) { if (new_desktop == current_desktop) {
new_desktop = max_desktop; new_desktop = max_desktop;
} }
} }
if (new_desktop != current_desktop) { if (new_desktop != current_desktop) {
m_log.info("%s: Requesting change to desktop #%lu", name(), new_desktop); m_log.info("%s: Requesting change to desktop #%u", name(), new_desktop);
ewmh_util::change_current_desktop(m_ewmh.get(), new_desktop); ewmh_util::change_current_desktop(m_ewmh.get(), new_desktop);
m_connection.flush(); m_connection.flush();
} else { } else {