actions: Integrate input_handler into module
Only modules can now be action handlers. This also slightly simplifies the controller because we don't need to keep track of input handlers, we can just use the module list.
This commit is contained in:
parent
0a1b58a2ed
commit
191fb2972c
@ -4,14 +4,15 @@
|
||||
|
||||
#include "common.hpp"
|
||||
#include "components/types.hpp"
|
||||
#include "modules/meta/input_handler.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
using std::map;
|
||||
|
||||
// fwd decl
|
||||
using namespace drawtypes;
|
||||
namespace modules {
|
||||
struct module_interface;
|
||||
}
|
||||
|
||||
class builder {
|
||||
public:
|
||||
@ -49,9 +50,9 @@ class builder {
|
||||
void underline_close();
|
||||
void control(controltag tag);
|
||||
void action(mousebtn index, string action);
|
||||
void action(mousebtn btn, const modules::input_handler& handler, string action, string data);
|
||||
void action(mousebtn btn, const modules::module_interface& module, string action, string data);
|
||||
void action(mousebtn index, string action, const label_t& label);
|
||||
void action(mousebtn btn, const modules::input_handler& handler, string action, string data, const label_t& label);
|
||||
void action(mousebtn btn, const modules::module_interface& module, string action, string data, const label_t& label);
|
||||
void action_close();
|
||||
|
||||
protected:
|
||||
|
@ -29,7 +29,6 @@ class logger;
|
||||
class signal_emitter;
|
||||
namespace modules {
|
||||
struct module_interface;
|
||||
class input_handler;
|
||||
} // namespace modules
|
||||
using module_t = shared_ptr<modules::module_interface>;
|
||||
using modulemap_t = std::map<alignment, vector<module_t>>;
|
||||
@ -117,14 +116,6 @@ class controller
|
||||
*/
|
||||
modulemap_t m_blocks;
|
||||
|
||||
/**
|
||||
* \brief Input handlers modules
|
||||
*
|
||||
* Maps the name of the input handler (module name) to the corresponding input
|
||||
* handler
|
||||
*/
|
||||
std::vector<shared_ptr<modules::input_handler>> m_inputhandlers;
|
||||
|
||||
/**
|
||||
* \brief Maximum number of subsequent events to swallow
|
||||
*/
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "common.hpp"
|
||||
#include "components/types.hpp"
|
||||
#include "errors.hpp"
|
||||
#include "modules/meta/input_handler.hpp"
|
||||
#include "utils/concurrency.hpp"
|
||||
#include "utils/functional.hpp"
|
||||
#include "utils/inotify.hpp"
|
||||
@ -112,6 +111,16 @@ namespace modules {
|
||||
virtual string name() const = 0;
|
||||
virtual bool running() const = 0;
|
||||
|
||||
/**
|
||||
* Handle action, possibly with data attached
|
||||
*
|
||||
* Any implementation is free to ignore the data, if the action does not
|
||||
* require additional data.
|
||||
*
|
||||
* \returns true if the action is supported and false otherwise
|
||||
*/
|
||||
virtual bool input(const string& action, const string& data) = 0;
|
||||
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void halt(string error_message) = 0;
|
||||
@ -122,7 +131,7 @@ namespace modules {
|
||||
// class definition : module {{{
|
||||
|
||||
template <class Impl>
|
||||
class module : public module_interface, public input_handler {
|
||||
class module : public module_interface {
|
||||
public:
|
||||
module(const bar_settings bar, string name);
|
||||
~module() noexcept;
|
||||
@ -138,7 +147,6 @@ namespace modules {
|
||||
string contents();
|
||||
|
||||
bool input(const string& action, const string& data);
|
||||
string input_handler_name() const;
|
||||
|
||||
static constexpr auto TYPE = "";
|
||||
|
||||
|
@ -109,11 +109,6 @@ namespace modules {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
string module<Impl>::input_handler_name() const {
|
||||
return m_name_raw;
|
||||
}
|
||||
|
||||
// }}}
|
||||
// module<Impl> protected {{{
|
||||
|
||||
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace modules {
|
||||
class input_handler {
|
||||
public:
|
||||
virtual ~input_handler() {}
|
||||
/**
|
||||
* Handle action, possibly with data attached
|
||||
*
|
||||
* Any implementation is free to ignore the data, if the action does not
|
||||
* require additional data.
|
||||
*
|
||||
* \returns true if the action is supported and false otherwise
|
||||
*/
|
||||
virtual bool input(const string& action, const string& data) = 0;
|
||||
|
||||
/**
|
||||
* The name of this input handler
|
||||
*/
|
||||
virtual string input_handler_name() const = 0;
|
||||
};
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
@ -9,7 +9,7 @@ namespace modules {
|
||||
struct module_interface;
|
||||
|
||||
#define DEFINE_UNSUPPORTED_MODULE(MODULE_NAME, MODULE_TYPE) \
|
||||
class MODULE_NAME : public module_interface, public input_handler { \
|
||||
class MODULE_NAME : public module_interface { \
|
||||
public: \
|
||||
MODULE_NAME(const bar_settings, string) { \
|
||||
throw application_error("No built-in support for '" + string{MODULE_TYPE} + "'"); \
|
||||
@ -33,9 +33,6 @@ namespace modules {
|
||||
string contents() { \
|
||||
return ""; \
|
||||
} \
|
||||
string input_handler_name() const { \
|
||||
return ""; \
|
||||
} \
|
||||
bool input(const string&, const string&) { \
|
||||
return false; \
|
||||
} \
|
||||
|
@ -1,12 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
#include "modules/meta/input_handler.hpp"
|
||||
|
||||
namespace modules {
|
||||
struct module_interface;
|
||||
} // namespace modules
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace actions_util {
|
||||
string get_action_string(const modules::input_handler& handler, string action, string data);
|
||||
string get_action_string(const modules::module_interface& module, string action, string data);
|
||||
|
||||
/**
|
||||
* Parses an action string of the form "#name.action[.data]".
|
||||
|
@ -3,10 +3,10 @@
|
||||
#include <utility>
|
||||
|
||||
#include "drawtypes/label.hpp"
|
||||
#include "utils/actions.hpp"
|
||||
#include "utils/color.hpp"
|
||||
#include "utils/string.hpp"
|
||||
#include "utils/time.hpp"
|
||||
#include "utils/actions.hpp"
|
||||
POLYBAR_NS
|
||||
|
||||
builder::builder(const bar_settings& bar) : m_bar(bar) {
|
||||
@ -440,10 +440,10 @@ void builder::action(mousebtn index, string action) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Open action tag for the action of the given input_handler
|
||||
* Open action tag for the action of the given module
|
||||
*/
|
||||
void builder::action(mousebtn btn, const modules::input_handler& handler, string action_name, string data) {
|
||||
action(btn, actions_util::get_action_string(handler, action_name, data));
|
||||
void builder::action(mousebtn btn, const modules::module_interface& module, string action_name, string data) {
|
||||
action(btn, actions_util::get_action_string(module, action_name, data));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -457,12 +457,12 @@ void builder::action(mousebtn index, string action_name, const label_t& label) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrap label in module action tag
|
||||
*/
|
||||
void builder::action(mousebtn btn, const modules::input_handler& handler, string action_name, string data, const label_t& label) {
|
||||
action(btn, actions_util::get_action_string(handler, action_name, data), label);
|
||||
void builder::action(
|
||||
mousebtn btn, const modules::module_interface& module, string action_name, string data, const label_t& label) {
|
||||
action(btn, actions_util::get_action_string(module, action_name, data), label);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "components/types.hpp"
|
||||
#include "events/signal.hpp"
|
||||
#include "events/signal_emitter.hpp"
|
||||
#include "modules/meta/base.hpp"
|
||||
#include "modules/meta/event_handler.hpp"
|
||||
#include "modules/meta/factory.hpp"
|
||||
#include "utils/actions.hpp"
|
||||
@ -146,14 +147,8 @@ bool controller::run(bool writeback, string snapshot_dst) {
|
||||
|
||||
size_t started_modules{0};
|
||||
for (const auto& module : m_modules) {
|
||||
auto inp_handler = std::dynamic_pointer_cast<input_handler>(module);
|
||||
auto evt_handler = dynamic_cast<event_handler_interface*>(&*module);
|
||||
|
||||
if (inp_handler) {
|
||||
m_log.trace("Registering module %s as input handler", module->name_raw());
|
||||
m_inputhandlers.push_back(inp_handler);
|
||||
}
|
||||
|
||||
if (evt_handler != nullptr) {
|
||||
evt_handler->connect(m_connection);
|
||||
}
|
||||
@ -474,20 +469,19 @@ bool controller::try_forward_legacy_action(const string& cmd) {
|
||||
string action = entry.second.second;
|
||||
|
||||
// Search for the first module that matches the type for this legacy action
|
||||
for (auto&& mod : m_modules) {
|
||||
if (mod->type() == type) {
|
||||
auto handler_ptr = std::dynamic_pointer_cast<input_handler>(mod);
|
||||
auto handler_name = handler_ptr->input_handler_name();
|
||||
for (auto&& module : m_modules) {
|
||||
if (module->type() == type) {
|
||||
auto module_name = module->name_raw();
|
||||
// TODO make this message more descriptive and maybe link to some documentation
|
||||
// TODO use route to string methods to print action name that should be used.
|
||||
if (data.empty()) {
|
||||
m_log.warn("The action '%s' is deprecated, use '#%s.%s' instead!", cmd, handler_name, action);
|
||||
m_log.warn("The action '%s' is deprecated, use '#%s.%s' instead!", cmd, module_name, action);
|
||||
} else {
|
||||
m_log.warn("The action '%s' is deprecated, use '#%s.%s.%s' instead!", cmd, handler_name, action, data);
|
||||
m_log.warn("The action '%s' is deprecated, use '#%s.%s.%s' instead!", cmd, module_name, action, data);
|
||||
}
|
||||
m_log.info(
|
||||
"Forwarding legacy action '%s' to module '%s' as '%s' with data '%s'", cmd, handler_name, action, data);
|
||||
if (!handler_ptr->input(action, data)) {
|
||||
"Forwarding legacy action '%s' to module '%s' as '%s' with data '%s'", cmd, module_name, action, data);
|
||||
if (!module->input(action, data)) {
|
||||
m_log.err("Failed to forward deprecated action to %s module", type);
|
||||
// Forward to shell if the module cannot accept the action to not break existing behavior.
|
||||
return false;
|
||||
@ -521,14 +515,14 @@ void controller::process_inputdata() {
|
||||
|
||||
// Every command that starts with '#' is considered an action string.
|
||||
if (cmd.front() == '#') {
|
||||
string handler_name;
|
||||
string module_name;
|
||||
string action;
|
||||
string data;
|
||||
|
||||
try {
|
||||
auto res = actions_util::parse_action_string(cmd);
|
||||
|
||||
handler_name = std::get<0>(res);
|
||||
module_name = std::get<0>(res);
|
||||
action = std::get<1>(res);
|
||||
data = std::get<2>(res);
|
||||
} catch (runtime_error& e) {
|
||||
@ -536,15 +530,15 @@ void controller::process_inputdata() {
|
||||
return;
|
||||
}
|
||||
|
||||
m_log.info("Forwarding data to input handlers (name: '%s', action: '%s', data: '%s') ", handler_name, action, data);
|
||||
m_log.info("Forwarding action to modules (name: '%s', action: '%s', data: '%s') ", module_name, action, data);
|
||||
|
||||
int num_delivered = 0;
|
||||
|
||||
// Forwards the action to all input handlers that match the name
|
||||
for (auto&& handler : m_inputhandlers) {
|
||||
if (handler->input_handler_name() == handler_name) {
|
||||
if (!handler->input(action, data)) {
|
||||
m_log.err("The '%s' module does not support the '%s' action.", handler_name, action);
|
||||
// Forwards the action to all modules that match the name
|
||||
for (auto&& module : m_modules) {
|
||||
if (module->name_raw() == module_name) {
|
||||
if (!module->input(action, data)) {
|
||||
m_log.err("The '%s' module does not support the '%s' action.", module_name, action);
|
||||
}
|
||||
|
||||
num_delivered++;
|
||||
@ -552,9 +546,9 @@ void controller::process_inputdata() {
|
||||
}
|
||||
|
||||
if (num_delivered == 0) {
|
||||
m_log.err("There exists no input handler with name '%s' (input: %s)", handler_name, cmd);
|
||||
m_log.err("There exists no module with name '%s' (input: %s)", module_name, cmd);
|
||||
} else {
|
||||
m_log.info("Delivered input to %d input handler%s", num_delivered, num_delivered > 1 ? "s" : "");
|
||||
m_log.info("Delivered action to %d module%s", num_delivered, num_delivered > 1 ? "s" : "");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -4,12 +4,13 @@
|
||||
#include <stdexcept>
|
||||
|
||||
#include "common.hpp"
|
||||
#include "modules/meta/base.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace actions_util {
|
||||
string get_action_string(const modules::input_handler& handler, string action, string data) {
|
||||
string str = "#" + handler.input_handler_name() + "." + action;
|
||||
string get_action_string(const modules::module_interface& module, string action, string data) {
|
||||
string str = "#" + module.name_raw() + "." + action;
|
||||
if (!data.empty()) {
|
||||
str += "." + data;
|
||||
}
|
||||
@ -28,10 +29,10 @@ namespace actions_util {
|
||||
throw std::runtime_error("Missing separator between name and action");
|
||||
}
|
||||
|
||||
auto handler_name = action_str.substr(0, action_sep);
|
||||
auto module_name = action_str.substr(0, action_sep);
|
||||
|
||||
if (handler_name.empty()) {
|
||||
throw std::runtime_error("The handler name must not be empty");
|
||||
if (module_name.empty()) {
|
||||
throw std::runtime_error("The module name must not be empty");
|
||||
}
|
||||
|
||||
auto action = action_str.substr(action_sep + 1);
|
||||
@ -47,7 +48,7 @@ namespace actions_util {
|
||||
throw std::runtime_error("The action name must not be empty");
|
||||
}
|
||||
|
||||
return std::tuple<string, string, string>{handler_name, action, data};
|
||||
return std::tuple<string, string, string>{module_name, action, data};
|
||||
}
|
||||
} // namespace actions_util
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user