fix: Handle single input events
This commit is contained in:
parent
c2caf4d7a6
commit
eca870774f
@ -48,7 +48,7 @@ class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, sig_ev::proc
|
|||||||
static make_type make(string&& path_confwatch, bool enable_ipc = false, bool writeback = false);
|
static make_type make(string&& path_confwatch, bool enable_ipc = false, bool writeback = false);
|
||||||
|
|
||||||
explicit controller(connection& conn, signal_emitter& emitter, const logger& logger, const config& config,
|
explicit controller(connection& conn, signal_emitter& emitter, const logger& logger, const config& config,
|
||||||
unique_ptr<eventloop> eventloop, unique_ptr<bar> bar, unique_ptr<ipc> ipc, watch_t confwatch, bool writeback);
|
unique_ptr<eventloop>&& eventloop, unique_ptr<bar>&& bar, unique_ptr<ipc>&& ipc, watch_t&& confwatch, bool writeback);
|
||||||
~controller();
|
~controller();
|
||||||
|
|
||||||
void setup();
|
void setup();
|
||||||
|
@ -27,6 +27,7 @@ using namespace signals::eventloop;
|
|||||||
using module_t = unique_ptr<modules::module_interface>;
|
using module_t = unique_ptr<modules::module_interface>;
|
||||||
using modulemap_t = std::map<alignment, vector<module_t>>;
|
using modulemap_t = std::map<alignment, vector<module_t>>;
|
||||||
|
|
||||||
|
namespace chrono = std::chrono;
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit, process_input, process_check,
|
class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit, process_input, process_check,
|
||||||
@ -45,13 +46,8 @@ class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit,
|
|||||||
bool flag{false};
|
bool flag{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct input_data {
|
|
||||||
char data[EVENT_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename EventType>
|
template <typename EventType>
|
||||||
using queue_t = moodycamel::BlockingConcurrentQueue<EventType>;
|
using queue_t = moodycamel::BlockingConcurrentQueue<EventType>;
|
||||||
using duration_t = std::chrono::duration<double, std::milli>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using make_type = unique_ptr<eventloop>;
|
using make_type = unique_ptr<eventloop>;
|
||||||
@ -64,7 +60,7 @@ class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit,
|
|||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
bool enqueue(event&& evt);
|
bool enqueue(event&& evt);
|
||||||
bool enqueue(input_data&& evt);
|
bool enqueue(string&& evt);
|
||||||
|
|
||||||
void add_module(const alignment pos, module_t&& module);
|
void add_module(const alignment pos, module_t&& module);
|
||||||
const modulemap_t& modules() const;
|
const modulemap_t& modules() const;
|
||||||
@ -74,16 +70,11 @@ class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit,
|
|||||||
static event make_update_evt(bool force = false);
|
static event make_update_evt(bool force = false);
|
||||||
static event make_input_evt();
|
static event make_input_evt();
|
||||||
static event make_check_evt();
|
static event make_check_evt();
|
||||||
static input_data make_input_data(string&& data);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void process_inputqueue();
|
|
||||||
void dispatch_modules();
|
void dispatch_modules();
|
||||||
|
|
||||||
inline bool compare_events(event evt, event evt2);
|
void handle_inputdata();
|
||||||
inline bool compare_events(input_data data, input_data data1);
|
|
||||||
|
|
||||||
void forward_event(event evt);
|
|
||||||
|
|
||||||
bool on(const process_input& evt);
|
bool on(const process_input& evt);
|
||||||
bool on(const process_check& evt);
|
bool on(const process_check& evt);
|
||||||
@ -105,11 +96,6 @@ class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit,
|
|||||||
*/
|
*/
|
||||||
queue_t<event> m_queue;
|
queue_t<event> m_queue;
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Event queue
|
|
||||||
*/
|
|
||||||
queue_t<input_data> m_inputqueue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Loaded modules
|
* @brief Loaded modules
|
||||||
*/
|
*/
|
||||||
@ -123,12 +109,32 @@ class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit,
|
|||||||
/**
|
/**
|
||||||
* @brief Time to wait for subsequent events
|
* @brief Time to wait for subsequent events
|
||||||
*/
|
*/
|
||||||
duration_t m_swallow_time{0ms};
|
chrono::milliseconds m_swallow_update{10ms};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Maximum amount of subsequent events to swallow within timeframe
|
* @brief Maximum amount of subsequent events to swallow within timeframe
|
||||||
*/
|
*/
|
||||||
size_t m_swallow_limit{0};
|
size_t m_swallow_limit{5U};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Time to throttle input events
|
||||||
|
*/
|
||||||
|
chrono::milliseconds m_swallow_input{0};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Mutex used to guard input data
|
||||||
|
*/
|
||||||
|
std::mutex m_inputlock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Time of last handled input event
|
||||||
|
*/
|
||||||
|
chrono::time_point<chrono::system_clock, decltype(m_swallow_input)> m_lastinput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Input data
|
||||||
|
*/
|
||||||
|
string m_inputdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -92,13 +92,13 @@ namespace signals {
|
|||||||
|
|
||||||
DEFINE_VALUE_SIGNAL(1, process_quit, eventloop_t::event);
|
DEFINE_VALUE_SIGNAL(1, process_quit, eventloop_t::event);
|
||||||
DEFINE_VALUE_SIGNAL(2, process_update, eventloop_t::event);
|
DEFINE_VALUE_SIGNAL(2, process_update, eventloop_t::event);
|
||||||
DEFINE_VALUE_SIGNAL(3, process_input, eventloop_t::input_data);
|
DEFINE_VALUE_SIGNAL(3, process_input, string);
|
||||||
DEFINE_VALUE_SIGNAL(4, process_check, eventloop_t::event);
|
DEFINE_VALUE_SIGNAL(4, process_check, eventloop_t::event);
|
||||||
|
|
||||||
DEFINE_VALUE_SIGNAL(5, enqueue_event, eventloop_t::event);
|
DEFINE_VALUE_SIGNAL(5, enqueue_event, eventloop_t::event);
|
||||||
DEFINE_VALUE_SIGNAL(6, enqueue_quit, eventloop_t::event);
|
DEFINE_VALUE_SIGNAL(6, enqueue_quit, eventloop_t::event);
|
||||||
DEFINE_VALUE_SIGNAL(7, enqueue_update, eventloop_t::event);
|
DEFINE_VALUE_SIGNAL(7, enqueue_update, eventloop_t::event);
|
||||||
DEFINE_VALUE_SIGNAL(8, enqueue_input, eventloop_t::input_data);
|
DEFINE_VALUE_SIGNAL(8, enqueue_input, string);
|
||||||
DEFINE_VALUE_SIGNAL(9, enqueue_check, eventloop_t::event);
|
DEFINE_VALUE_SIGNAL(9, enqueue_check, eventloop_t::event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ controller::make_type controller::make(string&& path_confwatch, bool enable_ipc,
|
|||||||
eventloop::make(),
|
eventloop::make(),
|
||||||
bar::make(),
|
bar::make(),
|
||||||
enable_ipc ? ipc::make() : ipc::make_type{},
|
enable_ipc ? ipc::make() : ipc::make_type{},
|
||||||
!path_confwatch.empty() ? inotify_util::make_watch(forward<decltype(path_confwatch)>(path_confwatch)) : watch_t{},
|
!path_confwatch.empty() ? inotify_util::make_watch(forward<decltype(path_confwatch)>(move(path_confwatch))) : watch_t{},
|
||||||
writeback);
|
writeback);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
@ -41,37 +41,25 @@ controller::make_type controller::make(string&& path_confwatch, bool enable_ipc,
|
|||||||
* Construct controller object
|
* Construct controller object
|
||||||
*/
|
*/
|
||||||
controller::controller(connection& conn, signal_emitter& emitter, const logger& logger, const config& config,
|
controller::controller(connection& conn, signal_emitter& emitter, const logger& logger, const config& config,
|
||||||
unique_ptr<eventloop> eventloop, unique_ptr<bar> bar, unique_ptr<ipc> ipc, watch_t confwatch, bool writeback)
|
unique_ptr<eventloop>&& eventloop, unique_ptr<bar>&& bar, unique_ptr<ipc>&& ipc, watch_t&& confwatch, bool writeback)
|
||||||
: m_connection(conn)
|
: m_connection(conn)
|
||||||
, m_sig(emitter)
|
, m_sig(emitter)
|
||||||
, m_log(logger)
|
, m_log(logger)
|
||||||
, m_conf(config)
|
, m_conf(config)
|
||||||
, m_eventloop(move(eventloop))
|
, m_eventloop(forward<decltype(eventloop)>(eventloop))
|
||||||
, m_bar(move(bar))
|
, m_bar(forward<decltype(bar)>(bar))
|
||||||
, m_ipc(move(ipc))
|
, m_ipc(forward<decltype(ipc)>(ipc))
|
||||||
, m_confwatch(move(confwatch))
|
, m_confwatch(forward<decltype(confwatch)>(confwatch))
|
||||||
, m_writeback(writeback) {}
|
, m_writeback(writeback) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deconstruct controller object
|
* Deconstruct controller object
|
||||||
*/
|
*/
|
||||||
controller::~controller() {
|
controller::~controller() {
|
||||||
if (m_eventloop) {
|
|
||||||
m_log.info("Deconstructing eventloop");
|
|
||||||
m_eventloop.reset();
|
|
||||||
}
|
|
||||||
if (m_command) {
|
if (m_command) {
|
||||||
m_log.info("Terminating running shell command");
|
m_log.info("Terminating running shell command");
|
||||||
m_command.reset();
|
m_command.reset();
|
||||||
}
|
}
|
||||||
if (m_bar) {
|
|
||||||
m_log.info("Deconstructing bar");
|
|
||||||
m_bar.reset();
|
|
||||||
}
|
|
||||||
if (m_ipc) {
|
|
||||||
m_log.info("Deconstructing ipc");
|
|
||||||
m_ipc.reset();
|
|
||||||
}
|
|
||||||
if (!m_writeback) {
|
if (!m_writeback) {
|
||||||
m_log.info("Interrupting X event loop");
|
m_log.info("Interrupting X event loop");
|
||||||
m_connection.send_dummy_event(m_connection.root());
|
m_connection.send_dummy_event(m_connection.root());
|
||||||
@ -89,12 +77,13 @@ controller::~controller() {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sig.detach(this);
|
|
||||||
m_connection.flush();
|
m_connection.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
void controller::setup() {
|
void controller::setup() {
|
||||||
string bs{m_conf.bar_section()};
|
if (!m_writeback) {
|
||||||
|
m_connection.ensure_event_mask(m_connection.root(), XCB_EVENT_MASK_STRUCTURE_NOTIFY);
|
||||||
|
}
|
||||||
|
|
||||||
string bs{m_conf.section()};
|
string bs{m_conf.section()};
|
||||||
m_log.trace("controller: Setup user-defined modules");
|
m_log.trace("controller: Setup user-defined modules");
|
||||||
@ -150,11 +139,12 @@ void controller::setup() {
|
|||||||
|
|
||||||
bool controller::run() {
|
bool controller::run() {
|
||||||
assert(!m_connection.connection_has_error());
|
assert(!m_connection.connection_has_error());
|
||||||
m_sig.attach(this);
|
|
||||||
|
|
||||||
m_log.info("Starting application");
|
m_log.info("Starting application");
|
||||||
m_running = true;
|
m_running = true;
|
||||||
|
|
||||||
|
m_sig.attach(this);
|
||||||
|
|
||||||
if (m_confwatch && !m_writeback) {
|
if (m_confwatch && !m_writeback) {
|
||||||
m_threads.emplace_back(thread(&controller::wait_for_configwatch, this));
|
m_threads.emplace_back(thread(&controller::wait_for_configwatch, this));
|
||||||
}
|
}
|
||||||
@ -191,13 +181,20 @@ bool controller::run() {
|
|||||||
m_log.warn("Termination signal received, shutting down...");
|
m_log.warn("Termination signal received, shutting down...");
|
||||||
m_log.trace("controller: Caught signal %d", caught_signal);
|
m_log.trace("controller: Caught signal %d", caught_signal);
|
||||||
|
|
||||||
// Signal the eventloop, in case it's still running
|
m_sig.detach(this);
|
||||||
m_eventloop->enqueue(eventloop::make_quit_evt(false));
|
|
||||||
|
|
||||||
if (m_eventloop) {
|
if (m_eventloop) {
|
||||||
|
// Signal the eventloop, in case it's still running
|
||||||
|
m_eventloop->enqueue(eventloop::make_quit_evt(false));
|
||||||
|
|
||||||
m_log.trace("controller: Stopping event loop");
|
m_log.trace("controller: Stopping event loop");
|
||||||
m_eventloop->stop();
|
m_eventloop->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_ipc) {
|
||||||
|
m_ipc.reset();
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_writeback && m_confwatch) {
|
if (!m_writeback && m_confwatch) {
|
||||||
m_log.trace("controller: Removing config watch");
|
m_log.trace("controller: Removing config watch");
|
||||||
m_confwatch->remove(true);
|
m_confwatch->remove(true);
|
||||||
@ -351,7 +348,7 @@ bool controller::on(const sig_ev::process_update& evt) {
|
|||||||
|
|
||||||
bool controller::on(const sig_ev::process_input& evt) {
|
bool controller::on(const sig_ev::process_input& evt) {
|
||||||
try {
|
try {
|
||||||
string input{(*evt()).data};
|
string input{*evt()};
|
||||||
|
|
||||||
if (m_command) {
|
if (m_command) {
|
||||||
m_log.warn("Terminating previous shell command");
|
m_log.warn("Terminating previous shell command");
|
||||||
@ -382,13 +379,12 @@ bool controller::on(const sig_ui::button_press& evt) {
|
|||||||
|
|
||||||
string input{*evt()};
|
string input{*evt()};
|
||||||
|
|
||||||
if (input.length() >= sizeof(eventloop::input_data)) {
|
if (input.empty()) {
|
||||||
m_log.warn("Ignoring input event (size)");
|
m_log.err("Cannot enqueue empty input");
|
||||||
} else if (!m_sig.emit(enqueue_input{eventloop::make_input_data(move(input))})) {
|
return false;
|
||||||
m_log.trace_x("controller: Dispatcher busy");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return m_sig.emit(enqueue_input{move(input)});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool controller::on(const sig_ipc::process_action& evt) {
|
bool controller::on(const sig_ipc::process_action& evt) {
|
||||||
@ -396,16 +392,13 @@ bool controller::on(const sig_ipc::process_action& evt) {
|
|||||||
string action{a.payload};
|
string action{a.payload};
|
||||||
action.erase(0, strlen(ipc_action::prefix));
|
action.erase(0, strlen(ipc_action::prefix));
|
||||||
|
|
||||||
if (action.size() >= sizeof(eventloop::input_data)) {
|
if (action.empty()) {
|
||||||
m_log.warn("Ignoring input event (size)");
|
|
||||||
} else if (action.empty()) {
|
|
||||||
m_log.err("Cannot enqueue empty ipc action");
|
m_log.err("Cannot enqueue empty ipc action");
|
||||||
} else {
|
return false;
|
||||||
m_log.info("Enqueuing ipc action: %s", action);
|
|
||||||
m_eventloop->enqueue(eventloop::make_input_data(move(action)));
|
|
||||||
m_eventloop->enqueue(eventloop::make_input_evt());
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
m_log.info("Enqueuing ipc action: %s", action);
|
||||||
|
return m_sig.emit(enqueue_input{move(action)});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool controller::on(const sig_ipc::process_command& evt) {
|
bool controller::on(const sig_ipc::process_command& evt) {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
#include <csignal>
|
#include <csignal>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "components/config.hpp"
|
||||||
#include "components/eventloop.hpp"
|
#include "components/eventloop.hpp"
|
||||||
|
#include "components/logger.hpp"
|
||||||
#include "components/types.hpp"
|
#include "components/types.hpp"
|
||||||
#include "events/signal.hpp"
|
#include "events/signal.hpp"
|
||||||
#include "components/logger.hpp"
|
|
||||||
#include "components/config.hpp"
|
|
||||||
#include "modules/meta/base.hpp"
|
#include "modules/meta/base.hpp"
|
||||||
#include "utils/factory.hpp"
|
#include "utils/factory.hpp"
|
||||||
#include "utils/string.hpp"
|
#include "utils/string.hpp"
|
||||||
@ -21,31 +21,16 @@ eventloop::make_type eventloop::make() {
|
|||||||
return factory_util::unique<eventloop>(signal_emitter::make(), logger::make(), config::make());
|
return factory_util::unique<eventloop>(signal_emitter::make(), logger::make(), config::make());
|
||||||
}
|
}
|
||||||
|
|
||||||
eventloop::event eventloop::make_quit_evt(bool reload) {
|
|
||||||
return event{static_cast<uint8_t>(event_type::QUIT), reload};
|
|
||||||
}
|
|
||||||
eventloop::event eventloop::make_update_evt(bool force) {
|
|
||||||
return event{static_cast<uint8_t>(event_type::UPDATE), force};
|
|
||||||
}
|
|
||||||
eventloop::event eventloop::make_input_evt() {
|
|
||||||
return event{static_cast<uint8_t>(event_type::INPUT)};
|
|
||||||
}
|
|
||||||
eventloop::event eventloop::make_check_evt() {
|
|
||||||
return event{static_cast<uint8_t>(event_type::CHECK)};
|
|
||||||
}
|
|
||||||
eventloop::input_data eventloop::make_input_data(string&& data) {
|
|
||||||
input_data d{};
|
|
||||||
memcpy(d.data, &data[0], sizeof(d.data));
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct eventloop instance
|
* Construct eventloop instance
|
||||||
*/
|
*/
|
||||||
eventloop::eventloop(signal_emitter& emitter, const logger& logger, const config& config)
|
eventloop::eventloop(signal_emitter& emitter, const logger& logger, const config& config)
|
||||||
: m_sig(emitter), m_log(logger), m_conf(config) {
|
: m_sig(emitter), m_log(logger), m_conf(config) {
|
||||||
m_swallow_time = duration_t{m_conf.get<double>("settings", "eventloop-swallow-time", 10)};
|
m_swallow_limit = m_conf.deprecated<size_t>("settings", "eventloop-swallow", "throttle-output", m_swallow_limit);
|
||||||
m_swallow_limit = m_conf.get<size_t>("settings", "eventloop-swallow", 5U);
|
m_swallow_update = m_conf.deprecated<chrono::milliseconds>(
|
||||||
|
"settings", "eventloop-swallow-time", "throttle-output-for", m_swallow_update);
|
||||||
|
m_swallow_input =
|
||||||
|
m_conf.get<chrono::milliseconds>("settings", "throttle-input-for", m_swallow_update * m_swallow_limit);
|
||||||
m_sig.attach(this);
|
m_sig.attach(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +62,6 @@ void eventloop::start() {
|
|||||||
|
|
||||||
while (m_running) {
|
while (m_running) {
|
||||||
event evt, next;
|
event evt, next;
|
||||||
input_data data;
|
|
||||||
|
|
||||||
m_queue.wait_dequeue(evt);
|
m_queue.wait_dequeue(evt);
|
||||||
|
|
||||||
@ -86,12 +70,10 @@ void eventloop::start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (evt.type == static_cast<uint8_t>(event_type::INPUT)) {
|
if (evt.type == static_cast<uint8_t>(event_type::INPUT)) {
|
||||||
while (m_running && m_inputqueue.try_dequeue(data)) {
|
handle_inputdata();
|
||||||
m_sig.emit(process_input{move(data)});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
size_t swallowed{0};
|
size_t swallowed{0};
|
||||||
while (swallowed++ < m_swallow_limit && m_queue.wait_dequeue_timed(next, m_swallow_time)) {
|
while (swallowed++ < m_swallow_limit && m_queue.wait_dequeue_timed(next, m_swallow_update)) {
|
||||||
if (next.type == static_cast<uint8_t>(event_type::QUIT)) {
|
if (next.type == static_cast<uint8_t>(event_type::QUIT)) {
|
||||||
evt = next;
|
evt = next;
|
||||||
break;
|
break;
|
||||||
@ -100,8 +82,8 @@ void eventloop::start() {
|
|||||||
evt = next;
|
evt = next;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else if (!compare_events(evt, next)) {
|
} else if (evt.type != next.type) {
|
||||||
enqueue(move(next));
|
m_queue.try_enqueue(move(next));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -111,11 +93,15 @@ void eventloop::start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (evt.type == static_cast<uint8_t>(event_type::INPUT)) {
|
if (evt.type == static_cast<uint8_t>(event_type::INPUT)) {
|
||||||
while (m_inputqueue.try_dequeue(data)) {
|
handle_inputdata();
|
||||||
m_sig.emit(process_input{move(data)});
|
} else if (evt.type == static_cast<uint8_t>(event_type::QUIT)) {
|
||||||
}
|
m_sig.emit(process_quit{reinterpret_cast<event&&>(evt)});
|
||||||
|
} else if (evt.type == static_cast<uint8_t>(event_type::UPDATE)) {
|
||||||
|
m_sig.emit(process_update{reinterpret_cast<event&&>(evt)});
|
||||||
|
} else if (evt.type == static_cast<uint8_t>(event_type::CHECK)) {
|
||||||
|
m_sig.emit(process_check{reinterpret_cast<event&&>(evt)});
|
||||||
} else {
|
} else {
|
||||||
forward_event(evt);
|
m_log.warn("Unknown event type for enqueued event (%d)", evt.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,14 +109,6 @@ void eventloop::start() {
|
|||||||
m_log.info("Queue worker done");
|
m_log.info("Queue worker done");
|
||||||
}
|
}
|
||||||
|
|
||||||
void eventloop::process_inputqueue() {
|
|
||||||
input_data data{};
|
|
||||||
|
|
||||||
while (m_inputqueue.try_dequeue(data)) {
|
|
||||||
m_sig.emit(process_input{move(data)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop main loop by enqueuing a QUIT event
|
* Stop main loop by enqueuing a QUIT event
|
||||||
*/
|
*/
|
||||||
@ -155,15 +133,25 @@ bool eventloop::enqueue(event&& evt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enqueue input event
|
* Enqueue input data
|
||||||
*/
|
*/
|
||||||
bool eventloop::enqueue(input_data&& evt) {
|
bool eventloop::enqueue(string&& input_data) {
|
||||||
if (!m_inputqueue.enqueue(move(evt))) {
|
if (m_inputlock.try_lock()) {
|
||||||
m_log.warn("Failed to enqueue input_data");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
std::lock_guard<std::mutex> guard(m_inputlock, std::adopt_lock);
|
||||||
|
|
||||||
|
if (!m_inputdata.empty()) {
|
||||||
|
m_log.trace("eventloop: Swallowing input event (pending data)");
|
||||||
|
return false;
|
||||||
|
} else if (chrono::system_clock::now() - m_swallow_input < m_lastinput) {
|
||||||
|
m_log.trace("eventloop: Swallowing input event (throttled)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_inputdata = forward<string>(input_data);
|
||||||
|
return enqueue(make_input_evt());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -216,33 +204,19 @@ void eventloop::dispatch_modules() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare given events
|
* Process pending input data
|
||||||
*/
|
*/
|
||||||
inline bool eventloop::compare_events(event evt, event evt2) {
|
void eventloop::handle_inputdata() {
|
||||||
return evt.type != evt2.type;
|
std::lock_guard<std::mutex> guard(m_inputlock);
|
||||||
}
|
if (!m_inputdata.empty()) {
|
||||||
|
m_sig.emit(process_input{move(m_inputdata)});
|
||||||
inline bool eventloop::compare_events(input_data data, input_data data2) {
|
m_lastinput = chrono::time_point_cast<decltype(m_swallow_input)>(chrono::system_clock::now());
|
||||||
return data.data[0] == data2.data[0] && strncmp(data.data, data2.data, strlen(data.data)) == 0;
|
m_inputdata.clear();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Forward event to handler based on type
|
|
||||||
*/
|
|
||||||
void eventloop::forward_event(event evt) {
|
|
||||||
if (evt.type == static_cast<uint8_t>(event_type::QUIT)) {
|
|
||||||
m_sig.emit(process_quit{reinterpret_cast<event&&>(evt)});
|
|
||||||
} else if (evt.type == static_cast<uint8_t>(event_type::UPDATE)) {
|
|
||||||
m_sig.emit(process_update{reinterpret_cast<event&&>(evt)});
|
|
||||||
} else if (evt.type == static_cast<uint8_t>(event_type::CHECK)) {
|
|
||||||
m_sig.emit(process_check{reinterpret_cast<event&&>(evt)});
|
|
||||||
} else {
|
|
||||||
m_log.warn("Unknown event type for enqueued event (%d)", evt.type);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool eventloop::on(const process_input& evt) {
|
bool eventloop::on(const process_input& evt) {
|
||||||
string input{(*evt()).data};
|
string input{*evt()};
|
||||||
|
|
||||||
for (auto&& block : m_modules) {
|
for (auto&& block : m_modules) {
|
||||||
for (auto&& module : block.second) {
|
for (auto&& module : block.second) {
|
||||||
@ -302,7 +276,7 @@ bool eventloop::on(const enqueue_update& evt) {
|
|||||||
|
|
||||||
bool eventloop::on(const enqueue_input& evt) {
|
bool eventloop::on(const enqueue_input& evt) {
|
||||||
m_log.trace("eventloop: enqueuing INPUT event");
|
m_log.trace("eventloop: enqueuing INPUT event");
|
||||||
return enqueue(input_data{(*evt())}) && enqueue(make_input_evt());
|
return enqueue(string{move(*evt())});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool eventloop::on(const enqueue_check& evt) {
|
bool eventloop::on(const enqueue_check& evt) {
|
||||||
@ -312,4 +286,17 @@ bool eventloop::on(const enqueue_check& evt) {
|
|||||||
return enqueue(move(check));
|
return enqueue(move(check));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eventloop::event eventloop::make_quit_evt(bool reload) {
|
||||||
|
return event{static_cast<uint8_t>(event_type::QUIT), reload};
|
||||||
|
}
|
||||||
|
eventloop::event eventloop::make_update_evt(bool force) {
|
||||||
|
return event{static_cast<uint8_t>(event_type::UPDATE), force};
|
||||||
|
}
|
||||||
|
eventloop::event eventloop::make_input_evt() {
|
||||||
|
return event{static_cast<uint8_t>(event_type::INPUT)};
|
||||||
|
}
|
||||||
|
eventloop::event eventloop::make_check_evt() {
|
||||||
|
return event{static_cast<uint8_t>(event_type::CHECK)};
|
||||||
|
}
|
||||||
|
|
||||||
POLYBAR_NS_END
|
POLYBAR_NS_END
|
||||||
|
@ -11,7 +11,7 @@ POLYBAR_NS
|
|||||||
* Create instance
|
* Create instance
|
||||||
*/
|
*/
|
||||||
logger::make_type logger::make(loglevel level) {
|
logger::make_type logger::make(loglevel level) {
|
||||||
return static_cast<const logger&>(*factory_util::singleton<const logger>(level));
|
return static_cast<logger::make_type>(*factory_util::singleton<std::remove_reference_t<logger::make_type>>(level));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,10 +29,10 @@ logger::logger(loglevel level) : m_level(level) {
|
|||||||
m_suffixes[loglevel::WARNING] = "\033[0m";
|
m_suffixes[loglevel::WARNING] = "\033[0m";
|
||||||
m_suffixes[loglevel::ERROR] = "\033[0m";
|
m_suffixes[loglevel::ERROR] = "\033[0m";
|
||||||
} else {
|
} else {
|
||||||
m_prefixes.emplace(make_pair(loglevel::TRACE, "polybar|trace "));
|
m_prefixes.emplace(make_pair(loglevel::TRACE, "polybar|trace: "));
|
||||||
m_prefixes.emplace(make_pair(loglevel::INFO, "polybar|infoe "));
|
m_prefixes.emplace(make_pair(loglevel::INFO, "polybar|info: "));
|
||||||
m_prefixes.emplace(make_pair(loglevel::WARNING, "polybar|warne "));
|
m_prefixes.emplace(make_pair(loglevel::WARNING, "polybar|warn: "));
|
||||||
m_prefixes.emplace(make_pair(loglevel::ERROR, "polybar|error "));
|
m_prefixes.emplace(make_pair(loglevel::ERROR, "polybar|error: "));
|
||||||
m_suffixes.emplace(make_pair(loglevel::TRACE, ""));
|
m_suffixes.emplace(make_pair(loglevel::TRACE, ""));
|
||||||
m_suffixes.emplace(make_pair(loglevel::INFO, ""));
|
m_suffixes.emplace(make_pair(loglevel::INFO, ""));
|
||||||
m_suffixes.emplace(make_pair(loglevel::WARNING, ""));
|
m_suffixes.emplace(make_pair(loglevel::WARNING, ""));
|
||||||
|
Loading…
Reference in New Issue
Block a user