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 {
struct module_interface;
class input_handler;
}
using module_t = unique_ptr<modules::module_interface>;
@ -42,7 +43,7 @@ namespace sig_ui = signals::ui;
namespace sig_ipc = signals::ipc;
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> {
public:
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 enqueue(event&& evt);
bool enqueue(string&& input_data);
bool enqueue(string&& input);
protected:
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_update& evt);
bool on(const sig_ev::process_input& evt);
bool on(const sig_ev::process_quit& evt);
bool on(const sig_ev::process_check& 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
*/
vector<signal_receiver_interface*> m_inputhandlers;
vector<modules::input_handler*> m_inputhandlers;
/**
* @brief Maximum number of subsequent events to swallow

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,16 +1,14 @@
#pragma once
#include "common.hpp"
#include "events/signal.hpp"
#include "events/signal_receiver.hpp"
POLYBAR_NS
namespace modules {
using input_event_t = signals::eventqueue::process_input;
class input_handler : public signal_receiver<0, input_event_t> {
class input_handler {
public:
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;
protected:
bool on(const input_event_t& evt);
bool input(string&& cmd);
private:
static constexpr const char* FORMAT_ONLINE{"format-online"};

View File

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

View File

@ -37,7 +37,7 @@ namespace modules {
protected:
void handle(const evt::randr_notify& evt);
bool on(const input_event_t& evt);
bool input(string&& cmd);
private:
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_indicator_state_notify& evt);
bool on(const input_event_t&);
bool input(string&& cmd);
private:
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 rebuild_desktops();
void set_current_desktop();
bool on(const input_event_t&);
bool input(string&& cmd);
private:
static constexpr const char* DEFAULT_ICON{"icon-default"};

View File

@ -363,17 +363,31 @@ void controller::process_eventqueue() {
*/
void controller::process_inputdata() {
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_inputdata.clear();
for (auto&& handler : m_inputhandlers) {
if (handler->on(evt)) {
if (handler->input(string{cmd})) {
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;
}
/**
* 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
*/

View File

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

View File

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

View File

@ -191,9 +191,7 @@ namespace modules {
return true;
}
bool i3_module::on(const input_event_t& evt) {
string cmd{*evt.data()};
bool i3_module::input(string&& cmd) {
if (cmd.find(EVENT_PREFIX) != 0) {
return false;
}
@ -205,11 +203,10 @@ namespace modules {
const connection_t conn{};
if (cmd.compare(0, strlen(EVENT_CLICK), EVENT_CLICK) == 0) {
const string workspace_num{cmd.substr(strlen(EVENT_CLICK))};
if (focused_workspace(conn)->num != atoi(workspace_num.c_str())) {
cmd.erase(0, strlen(EVENT_CLICK));
if (focused_workspace(conn)->num != atoi(cmd.c_str())) {
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) {
scrolldir = m_revscroll ? "prev" : "next";

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -208,13 +208,12 @@ namespace modules {
return false;
}
bool xworkspaces_module::on(const input_event_t& evt) {
string cmd{*evt.data()};
if (cmd.find(EVENT_PREFIX) != 0) {
bool xworkspaces_module::input(string&& cmd) {
size_t len{strlen(EVENT_PREFIX)};
if (cmd.compare(0, len, EVENT_PREFIX) != 0) {
return false;
}
cmd.erase(0, strlen(EVENT_PREFIX));
cmd.erase(0, len);
uint32_t new_desktop{0};
uint32_t min_desktop{0};
@ -233,26 +232,22 @@ namespace modules {
}
}
if (cmd.compare(0, strlen(EVENT_CLICK), EVENT_CLICK) == 0) {
new_desktop = atoi(cmd.substr(strlen(EVENT_CLICK)).c_str());
} else if (cmd.compare(0, strlen(EVENT_SCROLL_UP), EVENT_SCROLL_UP) == 0) {
if ((len = strlen(EVENT_CLICK)) && cmd.compare(0, len, EVENT_CLICK) == 0) {
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) {
new_desktop = math_util::min<uint32_t>(max_desktop, current_desktop + 1);
if (new_desktop == current_desktop) {
new_desktop = min_desktop;
}
} else if (cmd.compare(0, strlen(EVENT_SCROLL_DOWN), EVENT_SCROLL_DOWN) == 0) {
new_desktop = math_util::max<uint32_t>(min_desktop, current_desktop - 1);
} else if ((len = strlen(EVENT_SCROLL_DOWN)) && cmd.compare(0, len, EVENT_SCROLL_DOWN) == 0) {
new_desktop = math_util::max<uint32_t>(min_desktop, std::max(0U, current_desktop - 1));
if (new_desktop == current_desktop) {
new_desktop = max_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);
m_connection.flush();
} else {