refactor(modules): Input handling
This commit is contained in:
parent
99764b930e
commit
b422d1d1a4
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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";
|
||||||
|
@ -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>";
|
||||||
|
@ -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>"};
|
||||||
|
@ -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>";
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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"};
|
||||||
|
@ -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";
|
||||||
|
@ -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>"};
|
||||||
|
@ -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>"};
|
||||||
|
@ -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"};
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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";
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user