refactor(modules): Input handling
This commit is contained in:
parent
99764b930e
commit
b422d1d1a4
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -8,7 +8,6 @@ namespace signals {
|
||||
namespace eventqueue {
|
||||
struct process_quit;
|
||||
struct process_update;
|
||||
struct process_input;
|
||||
struct process_check;
|
||||
struct process_broadcast;
|
||||
}
|
||||
|
@ -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";
|
||||
|
@ -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>";
|
||||
|
@ -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>"};
|
||||
|
@ -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>";
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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"};
|
||||
|
@ -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";
|
||||
|
@ -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>"};
|
||||
|
@ -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>"};
|
||||
|
@ -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"};
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Loading…
Reference in New Issue
Block a user