wip(refactor): Improve signal and event handling

This commit is contained in:
Michael Carlberg 2016-12-05 20:41:00 +01:00
parent d45fd76dcd
commit 08be86fbe1
73 changed files with 2228 additions and 2251 deletions

View file

@ -2,12 +2,16 @@
#include "common.hpp"
#include "components/config.hpp"
#include "components/screen.hpp"
#include "components/types.hpp"
#include "errors.hpp"
#include "events/signal_emitter.hpp"
#include "events/signal_fwd.hpp"
#include "utils/concurrency.hpp"
#include "utils/throttle.hpp"
#include "x11/connection.hpp"
#include "x11/events.hpp"
#include "x11/tray_manager.hpp"
#include "x11/types.hpp"
#include "x11/window.hpp"
@ -21,20 +25,16 @@ class renderer;
class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::property_notify> {
public:
explicit bar(connection& conn, const config& config, const logger& logger, unique_ptr<screen> screen, unique_ptr<tray_manager> tray_manager);
~bar();
explicit bar(connection& conn, signal_emitter& emitter, const config& config, const logger& logger,
unique_ptr<screen> screen, unique_ptr<tray_manager> tray_manager);
void bootstrap(bool nodraw = false);
void bootstrap_tray();
void activate_tray();
~bar();
const bar_settings settings() const;
void parse(const string& data, bool force = false);
protected:
void setup_monitor();
void configure_geom();
void restack_window();
void reconfigure_pos();
void reconfigure_struts();
@ -47,22 +47,37 @@ class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::propert
private:
connection& m_connection;
signal_emitter& m_sig;
const config& m_conf;
const logger& m_log;
unique_ptr<screen> m_screen;
unique_ptr<tray_manager> m_tray;
unique_ptr<renderer> m_renderer;
xcb_window_t m_window;
bar_settings m_opts;
string m_lastinput;
std::mutex m_mutex;
event_timer m_buttonpress{};
event_timer m_buttonpress{0L, 5L};
};
di::injector<unique_ptr<bar>> configure_bar();
namespace {
/**
* Configure bar controller
*/
inline unique_ptr<bar> make_bar() {
// clang-format off
return factory_util::unique<bar>(
make_connection(),
make_signal_emitter(),
make_confreader(),
make_logger(),
make_screen(),
make_tray_manager());
// clang-format on
}
}
POLYBAR_NS_END

View file

@ -1,5 +1,7 @@
#pragma once
#include <map>
#include "common.hpp"
#include "components/config.hpp"
#include "components/types.hpp"
@ -7,6 +9,8 @@
POLYBAR_NS
using std::map;
#define DEFAULT_SPACING -1
#ifndef BUILDER_SPACE_TOKEN
@ -28,7 +32,7 @@ class builder {
explicit builder(const bar_settings bar) : m_bar(bar) {}
string flush();
void append(string text);
void append(const string& text);
void node(string str, bool add_space = false);
void node(string str, int font_index, bool add_space = false);
void node(const label_t& label, bool add_space = false);

View file

@ -1,7 +1,10 @@
#pragma once
#include <map>
#include "common.hpp"
#include "errors.hpp"
#include "utils/factory.hpp"
POLYBAR_NS
@ -12,7 +15,7 @@ namespace command_line {
class option;
using choices = vector<string>;
using options = vector<option>;
using values = map<string, string>;
using values = std::map<string, string>;
// class definition : option {{{
@ -69,13 +72,8 @@ namespace {
/**
* Configure injection module
*/
template <class T = cliparser>
di::injector<T> configure_cliparser(string scriptname, const clioptions& opts) {
// clang-format off
return di::make_injector(
di::bind<>().to("Usage: " + scriptname + " bar_name [OPTION...]"),
di::bind<>().to(opts));
// clang-format on
inline unique_ptr<cliparser> make_command_line(string scriptname, const clioptions& opts) {
return factory_util::unique<cliparser>("Usage: " + scriptname + " bar_name [OPTION...]", opts);
}
}

View file

@ -268,9 +268,9 @@ namespace {
/**
* Configure injection module
*/
template <typename T = const config&>
di::injector<T> configure_config() {
return di::make_injector(configure_logger(), configure_xresource_manager());
inline const config& make_confreader() {
shared_ptr<config> instance = factory_util::singleton<config>(make_logger(), make_xresource_manager());
return static_cast<config&>(*instance);
}
}

View file

@ -3,11 +3,16 @@
#include <csignal>
#include "common.hpp"
#include "components/bar.hpp"
#include "components/config.hpp"
#include "components/eventloop.hpp"
#include "components/ipc.hpp"
#include "components/logger.hpp"
#include "components/types.hpp"
#include "config.hpp"
#include "events/signal_emitter.hpp"
#include "events/signal_fwd.hpp"
#include "events/signal_receiver.hpp"
#include "utils/command.hpp"
#include "utils/inotify.hpp"
#include "x11/connection.hpp"
@ -18,65 +23,46 @@ POLYBAR_NS
// fwd decl {{{
class bar;
struct bar_settings;
// }}}
using watch_t = inotify_util::watch_t;
class controller {
public:
explicit controller(connection& conn, const logger& logger, const config& config, unique_ptr<eventloop> eventloop,
unique_ptr<bar> bar, inotify_util::watch_t& confwatch)
: m_connection(conn)
, m_log(logger)
, m_conf(config)
, m_eventloop(forward<decltype(eventloop)>(eventloop))
, m_bar(forward<decltype(bar)>(bar))
, m_confwatch(confwatch) {}
namespace sig_ev = signals::eventloop;
namespace sig_ui = signals::ui;
namespace sig_ipc = signals::ipc;
class controller : public signal_receiver<SIGN_PRIORITY_CONTROLLER, sig_ev::process_update, sig_ev::process_input,
sig_ev::process_quit, sig_ui::button_press, sig_ipc::process_action, sig_ipc::process_command,
sig_ipc::process_hook> {
public:
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);
~controller();
void bootstrap(bool writeback = false, bool dump_wmname = false);
void setup();
bool run();
const bar_settings opts() const;
protected:
void install_sigmask();
void uninstall_sigmask();
void install_confwatch();
void uninstall_confwatch();
void wait_for_signal();
void wait_for_xevent();
void wait_for_eventloop();
void wait_for_configwatch();
void bootstrap_modules();
void on_ipc_action(const ipc_action& message);
void on_mouse_event(const string& input);
void on_unrecognized_action(string input);
void on_update(bool force);
private:
enum class thread_role {
EVENT_QUEUE,
EVENT_QUEUE_X,
IPC_LISTENER,
CONF_LISTENER,
};
bool is_thread_joinable(thread_role&& role) {
if (m_threads.find(role) == m_threads.end()) {
return false;
} else {
return m_threads[role].joinable();
}
}
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_ui::button_press& evt);
bool on(const sig_ipc::process_action& evt);
bool on(const sig_ipc::process_command& evt);
bool on(const sig_ipc::process_hook& evt);
private:
connection& m_connection;
registry m_registry{m_connection};
signal_emitter& m_sig;
const logger& m_log;
const config& m_conf;
unique_ptr<eventloop> m_eventloop;
@ -86,18 +72,37 @@ class controller {
stateflag m_running{false};
stateflag m_reload{false};
stateflag m_waiting{false};
stateflag m_trayactivated{false};
sigset_t m_blockmask;
sigset_t m_waitmask;
map<thread_role, thread> m_threads;
vector<thread> m_threads;
inotify_util::watch_t& m_confwatch;
command_util::command_t m_command;
watch_t m_confwatch;
command_t m_command;
bool m_writeback{false};
};
di::injector<unique_ptr<controller>> configure_controller(watch_t& confwatch);
namespace {
inline unique_ptr<controller> make_controller(watch_t&& confwatch, bool enableipc = false, bool writeback = false) {
unique_ptr<ipc> ipc;
if (enableipc) {
ipc = make_ipc();
}
// clang-format off
return factory_util::unique<controller>(
make_connection(),
make_signal_emitter(),
make_logger(),
make_confreader(),
make_eventloop(),
make_bar(),
move(ipc),
move(confwatch),
writeback);
// clang-format on
}
}
POLYBAR_NS_END

View file

@ -5,104 +5,107 @@
#include "common.hpp"
#include "components/logger.hpp"
#include "events/signal_emitter.hpp"
#include "events/signal_fwd.hpp"
#include "events/signal_receiver.hpp"
#include "modules/meta/base.hpp"
POLYBAR_NS
using namespace signals::eventloop;
using module_t = unique_ptr<modules::module_interface>;
using modulemap_t = map<alignment, vector<module_t>>;
enum class event_type : uint8_t {
NONE = 0,
UPDATE,
CHECK,
INPUT,
QUIT,
};
struct event {
uint8_t type{0};
char data[256]{'\0'};
};
struct quit_event {
const uint8_t type{static_cast<uint8_t>(event_type::QUIT)};
bool reload{false};
};
struct update_event {
const uint8_t type{static_cast<uint8_t>(event_type::UPDATE)};
bool force{false};
};
struct input_event {
const uint8_t type{static_cast<uint8_t>(event_type::INPUT)};
char data[256]{'\0'};
};
class eventloop {
class eventloop : public signal_receiver<SIGN_PRIORITY_EVENTLOOP, process_quit, process_input, process_check,
enqueue_event, enqueue_quit, enqueue_update, enqueue_input, enqueue_check> {
public:
/**
* Queue type
*/
using entry_t = event;
using queue_t = moodycamel::BlockingConcurrentQueue<entry_t>;
enum class event_type : uint8_t {
NONE = 0,
UPDATE,
CHECK,
INPUT,
QUIT,
};
struct event {
uint8_t type{static_cast<uint8_t>(event_type::NONE)};
bool flag{false};
};
struct input_data {
char data[EVENT_SIZE];
};
template <typename EventType>
using queue_t = moodycamel::BlockingConcurrentQueue<EventType>;
using duration_t = chrono::duration<double, std::milli>;
explicit eventloop(const logger& logger, const config& config);
public:
explicit eventloop(signal_emitter& emitter, const logger& logger, const config& config);
~eventloop();
void start();
void wait();
void stop();
bool enqueue(const entry_t& entry);
bool enqueue_delayed(const entry_t& entry);
void set_update_cb(callback<bool>&& cb);
void set_input_db(callback<string>&& cb);
bool enqueue(event&& evt);
bool enqueue(input_data&& evt);
void add_module(const alignment pos, module_t&& module);
const modulemap_t& modules() const;
size_t module_count() const;
static const eventloop::entry_t& make(update_event&& event, bool force = false) {
event.force = force;
return reinterpret_cast<const eventloop::entry_t&>(event);
static auto make_quit_evt(bool reload = false) {
return event{static_cast<uint8_t>(event_type::QUIT), reload};
}
static const eventloop::entry_t& make(quit_event&& event, bool reload = false) {
event.reload = reload;
return reinterpret_cast<const eventloop::entry_t&>(event);
static auto make_update_evt(bool force = false) {
return event{static_cast<uint8_t>(event_type::UPDATE), force};
}
static const eventloop::entry_t& make(input_event&& event, const string& data) {
snprintf(event.data, sizeof(event.data), "%s", data.c_str());
return reinterpret_cast<const eventloop::entry_t&>(event);
static auto make_input_evt() {
return event{static_cast<uint8_t>(event_type::INPUT)};
}
static auto make_input_data(string&& data) {
input_data d{};
memcpy(d.data, &data[0], sizeof(d.data));
return d;
}
static auto make_check_evt() {
return event{static_cast<uint8_t>(event_type::CHECK)};
}
protected:
void process_inputqueue();
void dispatch_modules();
void dispatch_queue_worker();
void dispatch_delayed_worker();
inline bool match_event(entry_t evt, event_type type);
inline bool compare_events(entry_t evt, entry_t evt2);
void forward_event(entry_t evt);
inline bool compare_events(event evt, event evt2);
inline bool compare_events(input_data data, input_data data1);
void on_update(const update_event& evt);
void on_input(const input_event& evt);
void on_check();
void on_quit(const quit_event& evt);
void forward_event(event evt);
bool on(const process_input& evt);
bool on(const process_check& evt);
bool on(const process_quit& evt);
bool on(const enqueue_event& evt);
bool on(const enqueue_quit& evt);
bool on(const enqueue_update& evt);
bool on(const enqueue_input& evt);
bool on(const enqueue_check& evt);
private:
signal_emitter& m_sig;
const logger& m_log;
const config& m_conf;
/**
* @brief Event queue
*/
queue_t m_queue;
queue_t<event> m_queue;
/**
* @brief Event queue
*/
queue_t<input_data> m_inputqueue;
/**
* @brief Loaded modules
@ -114,16 +117,6 @@ class eventloop {
*/
stateflag m_running;
/**
* @brief Callback fired when receiving UPDATE events
*/
callback<bool> m_update_cb;
/**
* @brief Callback fired for unprocessed INPUT events
*/
callback<string> m_unrecognized_input_cb;
/**
* @brief Time to wait for subsequent events
*/
@ -133,45 +126,11 @@ class eventloop {
* @brief Maximum amount of subsequent events to swallow within timeframe
*/
size_t m_swallow_limit{0};
/**
* @brief Time until releasing the lock on the delayed enqueue channel
*/
duration_t m_delayed_time;
/**
* @brief Lock used to control the condition variable
*/
std::mutex m_delayed_lock;
/**
* @brief Condition variable used to manage notifications for delayed enqueues
*/
std::condition_variable m_delayed_cond;
/**
* @brief Pending event on the delayed channel
*/
entry_t m_delayed_entry{0};
/**
* @brief Queue worker thread
*/
thread m_queue_thread;
/**
* @brief Delayed notifier thread
*/
thread m_delayed_thread;
};
namespace {
/**
* Configure injection module
*/
template <typename T = unique_ptr<eventloop>>
di::injector<T> configure_eventloop() {
return di::make_injector(configure_logger(), configure_config());
inline unique_ptr<eventloop> make_eventloop() {
return make_unique<eventloop>(make_signal_emitter(), make_logger(), make_confreader());
}
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "common.hpp"
POLYBAR_NS
enum class event_type;
struct event;
struct quit_event;
struct update_event;
struct input_event;
class eventloop {
public:
using entry_t = event;
};
POLYBAR_NS_END

View file

@ -2,8 +2,10 @@
#include "common.hpp"
#include "components/logger.hpp"
#include "events/signal_emitter.hpp"
#include "utils/concurrency.hpp"
#include "utils/functional.hpp"
#include "utils/factory.hpp"
POLYBAR_NS
@ -12,15 +14,15 @@ POLYBAR_NS
*/
struct ipc_command {
static constexpr const char* prefix{"cmd:"};
string payload;
char payload[EVENT_SIZE]{'\0'};
};
struct ipc_hook {
static constexpr const char* prefix{"hook:"};
string payload;
char payload[EVENT_SIZE]{'\0'};
};
struct ipc_action {
static constexpr const char* prefix{"action:"};
string payload;
char payload[EVENT_SIZE]{'\0'};
};
/**
@ -32,40 +34,28 @@ struct ipc_action {
*/
class ipc {
public:
explicit ipc(const logger& logger) : m_log(logger) {}
explicit ipc(signal_emitter& emitter, const logger& logger) : m_sig(emitter), m_log(logger) {}
~ipc();
void attach_callback(callback<const ipc_command&>&& cb);
void attach_callback(callback<const ipc_hook&>&& cb);
void attach_callback(callback<const ipc_action&>&& cb);
void receive_messages();
protected:
void parse(const string& payload) const;
void delegate(const ipc_command& message) const;
void delegate(const ipc_hook& message) const;
void delegate(const ipc_action& message) const;
private:
signal_emitter& m_sig;
const logger& m_log;
vector<callback<const ipc_command&>> m_command_callbacks;
vector<callback<const ipc_hook&>> m_hook_callbacks;
vector<callback<const ipc_action&>> m_action_callbacks;
stateflag m_running{false};
string m_fifo;
int m_fd;
stateflag m_running{false};
};
namespace {
/**
* Configure injection module
*/
template <typename T = unique_ptr<ipc>>
di::injector<T> configure_ipc() {
return di::make_injector(configure_logger());
inline unique_ptr<ipc> make_ipc() {
return factory_util::unique<ipc>(make_signal_emitter(), make_logger());
}
}

View file

@ -1,13 +1,15 @@
#pragma once
#include <cstdio>
#include <map>
#include <string>
#include "common.hpp"
#include "utils/factory.hpp"
POLYBAR_NS
enum class loglevel {
enum class loglevel : uint8_t {
NONE = 0,
ERROR,
WARNING,
@ -25,34 +27,26 @@ class logger {
void verbosity(loglevel level);
void verbosity(string level);
/**
* Output a trace message
*/
#ifdef DEBUG_LOGGER // {{{
template <typename... Args>
#ifdef DEBUG_LOGGER
void trace(string message, Args... args) const {
output(loglevel::TRACE, message, args...);
}
#else
#ifdef VERBOSE_TRACELOG
#undef VERBOSE_TRACELOG
#endif
void trace(string, Args...) const {
}
#endif
/**
* Output extra verbose trace message
*/
template <typename... Args>
#ifdef VERBOSE_TRACELOG
void trace_x(string message, Args... args) const {
output(loglevel::TRACE, message, args...);
}
#else
void trace_x(string, Args...) const {
}
template <typename... Args>
void trace_x(Args...) const {}
#endif
#else
template <typename... Args>
void trace(Args...) const {}
template <typename... Args>
void trace_x(Args...) const {}
#endif // }}}
/**
* Output an info message
@ -97,70 +91,56 @@ class logger {
*/
template <typename... Args>
void output(loglevel level, string format, Args... values) const {
if (level > m_level)
if (level > m_level) {
return;
}
auto prefix = m_prefixes.find(level)->second;
auto suffix = m_suffixes.find(level)->second;
// silence the compiler
#if defined(__clang__)
#if defined(__clang__) // {{{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wformat-security"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-security"
#endif
dprintf(m_fd, (prefix + format + suffix + "\n").c_str(), convert(values)...);
#if defined(__clang__)
#endif // }}}
dprintf(m_fd, (m_prefixes.at(level) + format + m_suffixes.at(level) + "\n").c_str(), convert(values)...);
#if defined(__clang__) // {{{
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
#endif // }}}
}
private:
/**
* Logger verbosity level
*/
loglevel m_level = loglevel::TRACE;
loglevel m_level{loglevel::TRACE};
/**
* File descriptor used when writing the log messages
*/
int m_fd = STDERR_FILENO;
int m_fd{STDERR_FILENO};
/**
* Loglevel specific prefixes
*/
// clang-format off
map<loglevel, string> m_prefixes {
{loglevel::TRACE, "polybar|trace "},
{loglevel::INFO, "polybar|info "},
{loglevel::WARNING, "polybar|warn "},
{loglevel::ERROR, "polybar|error "},
};
std::map<loglevel, string> m_prefixes;
/**
* Loglevel specific suffixes
*/
map<loglevel, string> m_suffixes {
{loglevel::TRACE, ""},
{loglevel::INFO, ""},
{loglevel::WARNING, ""},
{loglevel::ERROR, ""},
};
// clang-format on
std::map<loglevel, string> m_suffixes;
};
/**
* Configure injection module
*/
namespace {
/**
* Configure injection module
*/
template <typename T = const logger&>
di::injector<T> configure_logger(loglevel level = loglevel::NONE) {
auto instance = factory_util::generic_singleton<logger>(level);
return di::make_injector(di::bind<>().to(instance));
inline const logger& make_logger(loglevel level = loglevel::NONE) {
auto instance = factory_util::singleton<const logger>(level);
return static_cast<const logger&>(*instance);
}
}

View file

@ -5,6 +5,7 @@
POLYBAR_NS
class signal_emitter;
class logger;
struct bar_settings;
enum class attribute : uint8_t;
@ -17,7 +18,7 @@ DEFINE_CHILD_ERROR(unclosed_actionblocks, parser_error);
class parser {
public:
explicit parser(const logger& logger, const bar_settings& bar);
explicit parser(signal_emitter& emitter, const logger& logger, const bar_settings& bar);
void operator()(string data);
void codeblock(string data);
size_t text(string data);
@ -30,6 +31,7 @@ class parser {
string parse_action_cmd(const string& data);
private:
signal_emitter& m_sig;
const logger& m_log;
const bar_settings& m_bar;
vector<int> m_actions;

View file

@ -1,7 +1,13 @@
#pragma once
#include "common.hpp"
#include "components/logger.hpp"
#include "components/types.hpp"
#include "events/signal_emitter.hpp"
#include "events/signal_fwd.hpp"
#include "events/signal_receiver.hpp"
#include "x11/connection.hpp"
#include "x11/fonts.hpp"
#include "x11/types.hpp"
POLYBAR_NS
@ -10,12 +16,17 @@ class connection;
class font_manager;
class logger;
class renderer {
using namespace signals::parser;
class renderer
: public signal_receiver<SIGN_PRIORITY_RENDERER, change_background, change_foreground, change_underline,
change_overline, change_font, change_alignment, offset_pixel, attribute_set, attribute_unset,
attribute_toggle, action_begin, action_end, write_text_ascii, write_text_unicode, write_text_string> {
public:
enum class gc : uint8_t { BG, FG, OL, UL, BT, BB, BL, BR };
explicit renderer(connection& conn, const logger& logger, unique_ptr<font_manager> font_manager,
const bar_settings& bar, const vector<string>& fonts);
explicit renderer(connection& conn, signal_emitter& emitter, const logger& logger,
unique_ptr<font_manager> font_manager, const bar_settings& bar, const vector<string>& fonts);
~renderer();
xcb_window_t window() const;
@ -52,6 +63,22 @@ class renderer {
int16_t shift_content(int16_t x, const int16_t shift_x);
int16_t shift_content(const int16_t shift_x);
bool on(const change_background& evt);
bool on(const change_foreground& evt);
bool on(const change_underline& evt);
bool on(const change_overline& evt);
bool on(const change_font& evt);
bool on(const change_alignment& evt);
bool on(const offset_pixel& evt);
bool on(const attribute_set& evt);
bool on(const attribute_unset& evt);
bool on(const attribute_toggle& evt);
bool on(const action_begin& evt);
bool on(const action_end& evt);
bool on(const write_text_ascii& evt);
bool on(const write_text_unicode& evt);
bool on(const write_text_string& evt);
#ifdef DEBUG_HINTS
vector<xcb_window_t> m_debughints;
void debug_hints();
@ -65,13 +92,13 @@ class renderer {
private:
connection& m_connection;
signal_emitter& m_sig;
const logger& m_log;
unique_ptr<font_manager> m_fontmanager;
const bar_settings& m_bar;
xcb_rectangle_t m_rect{0, 0, 0U, 0U};
xcb_rectangle_t m_cleared{0, 0, 0U, 0U};
reserve_area m_cleararea{};
@ -95,6 +122,21 @@ class renderer {
xcb_font_t m_gcfont{XCB_NONE};
};
di::injector<unique_ptr<renderer>> configure_renderer(const bar_settings& bar, const vector<string>& fonts);
namespace {
/**
* Configure injection module
*/
inline unique_ptr<renderer> make_renderer(const bar_settings& bar, const vector<string>& fonts) {
// clang-format off
return factory_util::unique<renderer>(
make_connection(),
make_signal_emitter(),
make_logger(),
make_font_manager(),
bar,
fonts);
// clang-format on
}
}
POLYBAR_NS_END

View file

@ -1,7 +1,10 @@
#pragma once
#include "common.hpp"
#include "components/config.hpp"
#include "components/logger.hpp"
#include "components/types.hpp"
#include "events/signal_emitter.hpp"
#include "x11/events.hpp"
#include "x11/window.hpp"
@ -11,10 +14,11 @@ POLYBAR_NS
class config;
class logger;
class connection;
class signal_emitter;
class screen : public xpp::event::sink<evt::randr_screen_change_notify> {
public:
explicit screen(connection& conn, const logger& logger, const config& conf);
explicit screen(connection& conn, signal_emitter& emitter, const logger& logger, const config& conf);
~screen();
struct size size() const {
@ -30,6 +34,7 @@ class screen : public xpp::event::sink<evt::randr_screen_change_notify> {
private:
connection& m_connection;
signal_emitter& m_sig;
const logger& m_log;
const config& m_conf;
@ -37,10 +42,20 @@ class screen : public xpp::event::sink<evt::randr_screen_change_notify> {
xcb_window_t m_proxy{XCB_NONE};
vector<monitor_t> m_monitors;
struct size m_size{0U, 0U};
struct size m_size {
0U, 0U
};
bool m_sigraised{false};
};
di::injector<unique_ptr<screen>> configure_screen();
namespace {
/**
* Configure injection module
*/
inline unique_ptr<screen> make_screen() {
return factory_util::unique<screen>(
make_connection(), make_signal_emitter(), make_logger(), make_confreader());
}
}
POLYBAR_NS_END

View file

@ -1,68 +0,0 @@
#pragma once
#include "common.hpp"
#include "components/eventloop.hpp"
#include "utils/functional.hpp"
POLYBAR_NS
// fwd decl {{{
enum class mousebtn : uint8_t;
enum class syntaxtag : uint8_t;
enum class alignment : uint8_t;
enum class attribute : uint8_t;
// }}}
/**
* @TODO: Allow multiple signal handlers
* @TODO: Encapsulate signals
*/
namespace g_signals {
/**
* Helper used to create no-op "callbacks"
*/
template <typename... T>
static callback<T...> noop = [](T...) {};
/**
* Signals used to communicate with the event loop
*/
namespace event {
extern callback<const eventloop::entry_t&> enqueue;
extern callback<const eventloop::entry_t&> enqueue_delayed;
}
/**
* Signals used to communicate with the bar window
*/
namespace bar {
extern callback<string> action_click;
extern callback<const bool> visibility_change;
}
/**
* Signals used to communicate with the input parser
*/
namespace parser {
extern callback<const uint32_t> background_change;
extern callback<const uint32_t> foreground_change;
extern callback<const uint32_t> underline_change;
extern callback<const uint32_t> overline_change;
extern callback<const alignment> alignment_change;
extern callback<const attribute> attribute_set;
extern callback<const attribute> attribute_unset;
extern callback<const attribute> attribute_toggle;
extern callback<const int8_t> font_change;
extern callback<const int16_t> pixel_offset;
extern callback<const mousebtn, const string> action_block_open;
extern callback<const mousebtn> action_block_close;
extern callback<const uint16_t> ascii_text_write;
extern callback<const uint16_t> unicode_text_write;
extern callback<const char*, const size_t> string_write;
}
}
POLYBAR_NS_END

View file

@ -1,5 +1,7 @@
#pragma once
#include <string>
#include "common.hpp"
#include "x11/color.hpp"
#include "x11/randr.hpp"
@ -80,8 +82,8 @@ struct action {
struct action_block : public action {
alignment align{alignment::NONE};
double start_x{0.0};
double end_x{0.0};
volatile double start_x{0.0};
volatile double end_x{0.0};
bool active{true};
uint16_t width() const {
@ -90,6 +92,11 @@ struct action_block : public action {
};
struct bar_settings {
explicit bar_settings() = default;
bar_settings(const bar_settings& other) = default;
xcb_window_t window;
monitor_t monitor;
edge origin{edge::TOP};
struct size size {
@ -109,7 +116,7 @@ struct bar_settings {
line_settings underline;
line_settings overline;
map<edge, border_settings> borders;
std::unordered_map<edge, border_settings> borders;
uint8_t spacing{1U};
string separator;
@ -128,13 +135,20 @@ struct bar_settings {
rect.x = pos.x;
rect.y = pos.y;
}
rect.y += borders.at(edge::TOP).size;
rect.height -= borders.at(edge::TOP).size;
rect.height -= borders.at(edge::BOTTOM).size;
rect.x += borders.at(edge::LEFT).size;
rect.width -= borders.at(edge::LEFT).size;
rect.width -= borders.at(edge::RIGHT).size;
if (borders.find(edge::TOP) != borders.end()) {
rect.y += borders.at(edge::TOP).size;
rect.height -= borders.at(edge::TOP).size;
}
if (borders.find(edge::BOTTOM) != borders.end()) {
rect.height -= borders.at(edge::BOTTOM).size;
}
if (borders.find(edge::LEFT) != borders.end()) {
rect.x += borders.at(edge::LEFT).size;
rect.width -= borders.at(edge::LEFT).size;
}
if (borders.find(edge::RIGHT) != borders.end()) {
rect.width -= borders.at(edge::RIGHT).size;
}
return rect;
}
};