From 84d58e76198419211721bfe32b41baf2aa2c053b Mon Sep 17 00:00:00 2001 From: Michael Carlberg Date: Thu, 24 Nov 2016 19:24:47 +0100 Subject: [PATCH] refactor: Cleanup handling of syntax tags --- include/common.hpp | 1 - include/components/builder.hpp | 92 ++--- include/components/parser.hpp | 5 +- include/components/renderer.hpp | 32 +- include/components/signals.hpp | 12 +- include/components/types.hpp | 70 ++-- include/config.hpp.cmake | 28 +- include/drawtypes/progressbar.hpp | 9 +- include/utils/color.hpp | 18 +- include/x11/fonts.hpp | 4 +- src/adapters/mpd.cpp | 1 + src/components/bar.cpp | 101 ++---- src/components/builder.cpp | 532 +++++++++++++++++----------- src/components/controller.cpp | 25 +- src/components/parser.cpp | 164 ++++----- src/components/renderer.cpp | 321 +++++++++++------ src/components/signals.cpp | 16 +- src/drawtypes/progressbar.cpp | 8 +- src/modules/bspwm.cpp | 6 +- src/modules/i3.cpp | 6 +- src/modules/menu.cpp | 6 +- src/modules/meta/inotify_module.cpp | 104 ------ src/modules/xbacklight.cpp | 4 +- src/x11/fonts.cpp | 8 +- tests/unit_tests/utils/color.cpp | 6 + 25 files changed, 863 insertions(+), 716 deletions(-) delete mode 100644 src/modules/meta/inotify_module.cpp diff --git a/include/common.hpp b/include/common.hpp index 98a5cb6d..f986d625 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -5,7 +5,6 @@ #endif #include -#include #include #include #include diff --git a/include/components/builder.hpp b/include/components/builder.hpp index 0c03505d..b13cc8a3 100644 --- a/include/components/builder.hpp +++ b/include/components/builder.hpp @@ -25,88 +25,74 @@ using namespace drawtypes; class builder { public: - explicit builder(const bar_settings bar, bool lazy = false) : m_bar(bar), m_lazy(lazy) {} - - void set_lazy(bool mode); + explicit builder(const bar_settings bar) : m_bar(bar) {} string flush(); - void append(string text); - void node(string str, bool add_space = false); void node(string str, int font_index, bool add_space = false); - // void node(progressbar_t bar, float perc, bool add_space = false); void node(label_t label, bool add_space = false); - // void node(ramp_t ramp, float perc, bool add_space = false); - // void node(animation_t animation, bool add_space = false); - void offset(int pixels = 0); void space(int width = DEFAULT_SPACING); void remove_trailing_space(int width = DEFAULT_SPACING); - - void invert(); - void font(int index); - void font_close(bool force = false); - + void font_close(); void background(string color); - void background_close(bool force = false); - - void color(string color_); - void color_alpha(string alpha_); - void color_close(bool force = false); - + void background_close(); + void color(string color); + void color_alpha(string alpha); + void color_close(); void line_color(string color); - void line_color_close(bool force = false); + void line_color_close(); void overline_color(string color); - void overline_color_close(bool force = false); + void overline_color_close(); void underline_color(string color); - void underline_color_close(bool force = false); - + void underline_color_close(); void overline(string color = ""); - void overline_close(bool force = false); - + void overline_close(); void underline(string color = ""); - void underline_close(bool force = false); - + void underline_close(); void cmd(mousebtn index, string action, bool condition = true); - void cmd_close(bool force = false); + void cmd_close(); protected: - void tag_open(char tag, string value); - void tag_close(char tag); + string background_hex(); + string foreground_hex(); + + void tag_open(syntaxtag tag, string value); + void tag_open(attribute attr); + void tag_close(syntaxtag tag); + void tag_close(attribute attr); private: const bar_settings m_bar; - string m_output; - bool m_lazy = true; - map m_counters{ - // clang-format off - {syntaxtag::A, 0}, - {syntaxtag::B, 0}, - {syntaxtag::F, 0}, - {syntaxtag::T, 0}, - {syntaxtag::U, 0}, - {syntaxtag::Uo, 0}, - {syntaxtag::Uu, 0}, - {syntaxtag::O, 0}, - {syntaxtag::R, 0}, - // clang-format on + map m_tags{ + // clang-format off + {syntaxtag::A, 0}, + {syntaxtag::B, 0}, + {syntaxtag::F, 0}, + {syntaxtag::T, 0}, + {syntaxtag::u, 0}, + {syntaxtag::o, 0}, + // clang-format on }; map m_colors{ - // clang-format off - {syntaxtag::B, ""}, - {syntaxtag::F, ""}, - {syntaxtag::U, ""}, - {syntaxtag::Uu, ""}, - {syntaxtag::Uo, ""}, - // clang-format on + // clang-format off + {syntaxtag::B, ""}, + {syntaxtag::F, ""}, + {syntaxtag::u, ""}, + {syntaxtag::o, ""}, + // clang-format on }; - int m_fontindex = 1; + uint8_t m_attributes{static_cast(attribute::NONE)}; + uint8_t m_fontindex{1}; + + string m_background; + string m_foreground; }; POLYBAR_NS_END diff --git a/include/components/parser.hpp b/include/components/parser.hpp index ba828069..437010a7 100644 --- a/include/components/parser.hpp +++ b/include/components/parser.hpp @@ -4,15 +4,17 @@ POLYBAR_NS +class logger; struct bar_settings; enum class attribute : uint8_t; enum class mousebtn : uint8_t; DEFINE_ERROR(unrecognized_token); +DEFINE_ERROR(unrecognized_attribute); class parser { public: - explicit parser(const bar_settings& bar); + explicit parser(const logger& logger, const bar_settings& bar); void operator()(string data); void codeblock(string data); size_t text(string data); @@ -25,6 +27,7 @@ class parser { string parse_action_cmd(string data); private: + const logger& m_log; const bar_settings& m_bar; vector m_actions; }; diff --git a/include/components/renderer.hpp b/include/components/renderer.hpp index 13429e22..576f6f3b 100644 --- a/include/components/renderer.hpp +++ b/include/components/renderer.hpp @@ -12,6 +12,8 @@ class logger; class renderer { 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, const bar_settings& bar, const vector& fonts); @@ -27,26 +29,29 @@ class renderer { void set_foreground(const uint32_t color); void set_underline(const uint32_t color); void set_overline(const uint32_t color); - void set_fontindex(const uint8_t font); + void set_fontindex(const int8_t font); void set_alignment(const alignment align); void set_attribute(const attribute attr, const bool state); + void toggle_attribute(const attribute attr); + bool check_attribute(const attribute attr); void fill_background(); void fill_border(const map& borders, edge border); void fill_overline(int16_t x, uint16_t w); void fill_underline(int16_t x, uint16_t w); + void fill_shift(const int16_t px); - void draw_character(uint16_t character); - void draw_textstring(const char* text, size_t len); + void draw_character(const uint16_t character); + void draw_textstring(const char* text, const size_t len); - int16_t shift_content(int16_t x, int16_t shift_x); - int16_t shift_content(int16_t shift_x); - - void begin_action(const mousebtn btn, const string& cmd); + void begin_action(const mousebtn btn, const string cmd); void end_action(const mousebtn btn); const vector get_actions(); protected: + int16_t shift_content(const int16_t x, const int16_t shift_x); + int16_t shift_content(const int16_t shift_x); + void debughints(); private: @@ -67,16 +72,13 @@ class renderer { vector m_actions; // bool m_autosize{false}; - int m_currentx{0}; - int m_attributes{0}; + uint16_t m_currentx{0U}; alignment m_alignment{alignment::NONE}; + map m_colors; + uint8_t m_attributes{0U}; + int8_t m_fontindex{DEFAULT_FONT_INDEX}; - xcb_font_t m_gcfont{0}; - - uint32_t m_background{0}; - uint32_t m_foreground{0}; - uint32_t m_underline{0}; - uint32_t m_overline{0}; + xcb_font_t m_gcfont{XCB_NONE}; edge m_reserve_at{edge::NONE}; uint16_t m_reserve; diff --git a/include/components/signals.hpp b/include/components/signals.hpp index e02a9704..57750c14 100644 --- a/include/components/signals.hpp +++ b/include/components/signals.hpp @@ -12,7 +12,6 @@ enum class mousebtn : uint8_t; enum class syntaxtag : uint8_t; enum class alignment : uint8_t; enum class attribute : uint8_t; -enum class gc : uint8_t; // }}} @@ -26,14 +25,18 @@ namespace g_signals { } namespace parser { + extern callback background_change; + extern callback foreground_change; + extern callback underline_change; + extern callback overline_change; extern callback alignment_change; extern callback attribute_set; extern callback attribute_unset; - extern callback action_block_open; - extern callback action_block_close; - extern callback color_change; + extern callback attribute_toggle; extern callback font_change; extern callback pixel_offset; + extern callback action_block_open; + extern callback action_block_close; extern callback ascii_text_write; extern callback unicode_text_write; extern callback string_write; @@ -41,7 +44,6 @@ namespace g_signals { namespace tray { extern callback report_slotcount; - extern callback clear_bg; } } diff --git a/include/components/types.hpp b/include/components/types.hpp index 6d6f3aa3..f39438c6 100644 --- a/include/components/types.hpp +++ b/include/components/types.hpp @@ -6,14 +6,28 @@ POLYBAR_NS -enum class edge : uint8_t { NONE = 0, TOP, BOTTOM, LEFT, RIGHT, ALL }; -enum class alignment : uint8_t { NONE = 0, LEFT, CENTER, RIGHT }; -enum class syntaxtag : uint8_t { NONE = 0, A, B, F, T, U, Uu, Uo, O, R, o, u }; -enum class attribute : uint8_t { NONE = 0, o = 1 << 0, u = 1 << 1 }; -enum class mousebtn : uint8_t { NONE = 0, LEFT, MIDDLE, RIGHT, SCROLL_UP, SCROLL_DOWN }; -enum class gc : uint8_t { NONE = 0, BG, FG, OL, UL, BT, BB, BL, BR }; +enum class edge : uint8_t { NONE = 0U, TOP, BOTTOM, LEFT, RIGHT, ALL }; + +enum class alignment : uint8_t { NONE = 0U, LEFT, CENTER, RIGHT }; + +enum class attribute : uint8_t { NONE = 0U, UNDERLINE, OVERLINE }; + +enum class syntaxtag : uint8_t { + NONE = 0U, + A, // mouse action + B, // background color + F, // foreground color + T, // font index + O, // pixel offset + R, // flip colors + o, // overline color + u, // underline color +}; + +enum class mousebtn : uint8_t { NONE = 0U, LEFT, MIDDLE, RIGHT, SCROLL_UP, SCROLL_DOWN }; + enum class strut : uint16_t { - LEFT = 0, + LEFT = 0U, RIGHT, TOP, BOTTOM, @@ -33,45 +47,45 @@ struct position { }; struct size { - uint16_t w{0}; - uint16_t h{0}; + uint16_t w{1U}; + uint16_t h{1U}; }; struct side_values { - uint16_t left{0}; - uint16_t right{0}; + uint16_t left{0U}; + uint16_t right{0U}; }; struct edge_values { - uint16_t left{0}; - uint16_t right{0}; - uint16_t top{0}; - uint16_t bottom{0}; + uint16_t left{0U}; + uint16_t right{0U}; + uint16_t top{0U}; + uint16_t bottom{0U}; }; struct border_settings { uint32_t color{0xFF000000}; - uint16_t size{0}; + uint16_t size{0U}; }; struct line_settings { uint32_t color{0xFF000000}; - uint16_t size{0}; + uint16_t size{0U}; }; struct bar_settings { monitor_t monitor; - edge origin{edge::TOP}; - - struct size size{0, 0}; + struct size size { + 1U, 1U + }; position pos{0, 0}; position offset{0, 0}; position center{0, 0}; - side_values padding{0, 0}; - side_values margin{0, 0}; - side_values module_margin{0, 2}; - edge_values strut{0, 0, 0, 0}; + side_values padding{0U, 0U}; + side_values margin{0U, 0U}; + side_values module_margin{0U, 2U}; + edge_values strut{0U, 0U, 0U, 0U}; uint32_t background{0xFFFFFFFF}; uint32_t foreground{0xFF000000}; @@ -81,7 +95,7 @@ struct bar_settings { map borders; - int8_t spacing{1}; + uint8_t spacing{1U}; string separator; string wmname; @@ -89,8 +103,12 @@ struct bar_settings { bool force_docking{false}; - const xcb_rectangle_t inner_area() const { + const xcb_rectangle_t inner_area(bool local_coords = false) const { xcb_rectangle_t rect{pos.x, pos.y, size.w, size.h}; + if (local_coords) { + rect.x = 0; + rect.y = 0; + } rect.y += borders.at(edge::TOP).size; rect.height -= borders.at(edge::TOP).size; rect.height -= borders.at(edge::BOTTOM).size; diff --git a/include/config.hpp.cmake b/include/config.hpp.cmake index 87100c3a..6b9dc443 100644 --- a/include/config.hpp.cmake +++ b/include/config.hpp.cmake @@ -28,20 +28,22 @@ #endif #endif -#define BUILDER_SPACE_TOKEN "%__" +static constexpr const char* ALSA_SOUNDCARD{"default"}; +static constexpr const char* BSPWM_SOCKET_PATH{"/tmp/bspwm_0_0-socket"}; +static constexpr const char* BSPWM_STATUS_PREFIX{"W"}; +static constexpr const char* CONNECTION_TEST_IP{"8.8.8.8"}; +static constexpr const char* PATH_ADAPTER{"/sys/class/power_supply/%adapter%"}; +static constexpr const char* PATH_BACKLIGHT_MAX{"/sys/class/backlight/%card%/max_brightness"}; +static constexpr const char* PATH_BACKLIGHT_VAL{"/sys/class/backlight/%card%/brightness"}; +static constexpr const char* PATH_BATTERY{"/sys/class/power_supply/%battery%"}; +static constexpr const char* PATH_CPU_INFO{"/proc/stat"}; +static constexpr const char* PATH_MEMORY_INFO{"/proc/meminfo"}; +static constexpr const char* PATH_MESSAGING_FIFO{"/tmp/polybar_mqueue.%pid%"}; +static constexpr const char* PATH_TEMPERATURE_INFO{"/sys/class/thermal/thermal_zone%zone%/temp"}; -#define ALSA_SOUNDCARD "@SETTING_ALSA_SOUNDCARD@" -#define BSPWM_SOCKET_PATH "@SETTING_BSPWM_SOCKET_PATH@" -#define BSPWM_STATUS_PREFIX "@SETTING_BSPWM_STATUS_PREFIX@" -#define CONNECTION_TEST_IP "@SETTING_CONNECTION_TEST_IP@" -#define PATH_ADAPTER "@SETTING_PATH_ADAPTER@" -#define PATH_BACKLIGHT_MAX "@SETTING_PATH_BACKLIGHT_MAX@" -#define PATH_BACKLIGHT_VAL "@SETTING_PATH_BACKLIGHT_VAL@" -#define PATH_BATTERY "@SETTING_PATH_BATTERY@" -#define PATH_CPU_INFO "@SETTING_PATH_CPU_INFO@" -#define PATH_MEMORY_INFO "@SETTING_PATH_MEMORY_INFO@" -#define PATH_MESSAGING_FIFO "@SETTING_PATH_MESSAGING_FIFO@" -#define PATH_TEMPERATURE_INFO "@SETTING_PATH_TEMPERATURE_INFO@" +static constexpr const char* BUILDER_SPACE_TOKEN{"%__"}; + +static const int8_t DEFAULT_FONT_INDEX{-1}; auto version_details = [](const std::vector& args) { for (auto&& arg : args) { diff --git a/include/drawtypes/progressbar.hpp b/include/drawtypes/progressbar.hpp index 1551a222..c9c026b1 100644 --- a/include/drawtypes/progressbar.hpp +++ b/include/drawtypes/progressbar.hpp @@ -12,11 +12,7 @@ POLYBAR_NS namespace drawtypes { class progressbar : public non_copyable_mixin { public: - explicit progressbar( - const bar_settings& bar, int width, string format, bool lazy_builder_closing = true) - : m_builder(make_unique(bar, lazy_builder_closing)) - , m_format(format) - , m_width(width) {} + explicit progressbar(const bar_settings bar, int width, string format); void set_fill(icon_t&& fill); void set_empty(icon_t&& empty); @@ -44,8 +40,7 @@ namespace drawtypes { using progressbar_t = shared_ptr; - progressbar_t load_progressbar( - const bar_settings& bar, const config& conf, string section, string name); + progressbar_t load_progressbar(const bar_settings& bar, const config& conf, string section, string name); } POLYBAR_NS_END diff --git a/include/utils/color.hpp b/include/utils/color.hpp index 1598ddaf..bb830d9b 100644 --- a/include/utils/color.hpp +++ b/include/utils/color.hpp @@ -88,7 +88,23 @@ namespace color_util { inline uint32_t parse(string hex, uint32_t fallback = 0) { if ((hex = parse_hex(hex)).empty()) return fallback; - return std::strtoul(&hex[1], nullptr, 16); + return strtoul(&hex[1], nullptr, 16); + } + + inline string simplify_hex(string hex) { + // convert #ffrrggbb to #rrggbb + if (hex.length() == 9 && hex[1] == 'f' && hex[2] == 'f') { + hex.erase(1, 2); + } + + // convert #rrggbb to #rgb + if (hex.length() == 7) { + if (hex[1] == hex[2] && hex[3] == hex[4] && hex[5] == hex[6]) { + hex = {'#', hex[1], hex[3], hex[5]}; + } + } + + return hex; } } diff --git a/include/x11/fonts.hpp b/include/x11/fonts.hpp index fb1249e9..9c1c685c 100644 --- a/include/x11/fonts.hpp +++ b/include/x11/fonts.hpp @@ -42,7 +42,7 @@ class font_manager { explicit font_manager(connection& conn, const logger& logger); ~font_manager(); - bool load(string name, int8_t fontindex = -1, int8_t offset_y = 0); + bool load(string name, int8_t fontindex = DEFAULT_FONT_INDEX, int8_t offset_y = 0); void set_preferred_font(int8_t index); @@ -72,7 +72,7 @@ class font_manager { Colormap m_colormap{}; map m_fonts; - int8_t m_fontindex{-1}; + int8_t m_fontindex{DEFAULT_FONT_INDEX}; XftColor m_xftcolor{}; XftDraw* m_xftdraw{nullptr}; diff --git a/src/adapters/mpd.cpp b/src/adapters/mpd.cpp index ccb85b77..47936049 100644 --- a/src/adapters/mpd.cpp +++ b/src/adapters/mpd.cpp @@ -1,3 +1,4 @@ +#include #include #include "adapters/mpd.hpp" diff --git a/src/components/bar.cpp b/src/components/bar.cpp index 4348352d..692586c6 100644 --- a/src/components/bar.cpp +++ b/src/components/bar.cpp @@ -19,6 +19,8 @@ POLYBAR_NS +namespace ph = std::placeholders; + /** * Configure injection module */ @@ -47,21 +49,6 @@ bar::bar(connection& conn, const config& config, const logger& logger, unique_pt */ bar::~bar() { std::lock_guard guard(m_mutex); - - // Disconnect signal handlers {{{ - g_signals::parser::alignment_change = nullptr; - g_signals::parser::attribute_set = nullptr; - g_signals::parser::attribute_unset = nullptr; - g_signals::parser::action_block_open = nullptr; - g_signals::parser::action_block_close = nullptr; - g_signals::parser::color_change = nullptr; - g_signals::parser::font_change = nullptr; - g_signals::parser::pixel_offset = nullptr; - g_signals::parser::ascii_text_write = nullptr; - g_signals::parser::unicode_text_write = nullptr; - g_signals::parser::string_write = nullptr; - g_signals::tray::report_slotcount = nullptr; // }}} - m_connection.detach_sink(this, 1); } @@ -152,52 +139,6 @@ void bar::bootstrap(bool nodraw) { return; } - m_log.trace("bar: Attach parser signal handlers"); - { - // clang-format off - g_signals::parser::alignment_change = [this](const alignment align) { - m_renderer->set_alignment(align); - }; - g_signals::parser::attribute_set = [this](const attribute attr) { - m_renderer->set_attribute(attr, true); - }; - g_signals::parser::attribute_unset = [this](const attribute attr) { - m_renderer->set_attribute(attr, false); - }; - g_signals::parser::action_block_open = [this](const mousebtn btn, string cmd) { - m_renderer->begin_action(btn, cmd); - }; - g_signals::parser::action_block_close = [this](const mousebtn btn) { - m_renderer->end_action(btn); - }; - g_signals::parser::color_change= [this](const gc gcontext, const uint32_t color) { - if (gcontext == gc::BG) - m_renderer->set_background(color); - else if (gcontext == gc::FG) - m_renderer->set_foreground(color); - else if (gcontext == gc::UL) - m_renderer->set_underline(color); - else if (gcontext == gc::OL) - m_renderer->set_overline(color); - }; - g_signals::parser::font_change = [this](const int8_t font) { - m_renderer->set_fontindex(font); - }; - g_signals::parser::pixel_offset = [this](const int16_t px) { - m_renderer->shift_content(px); - }; - g_signals::parser::ascii_text_write = [this](const uint16_t c) { - m_renderer->draw_character(c); - }; - g_signals::parser::unicode_text_write = [this](const uint16_t c) { - m_renderer->draw_character(c); - }; - g_signals::parser::string_write = [this](const char* text, const size_t len) { - m_renderer->draw_textstring(text, len); - }; - // clang-format on - } - m_log.trace("bar: Attaching sink to registry"); m_connection.attach_sink(this, 1); @@ -210,11 +151,33 @@ void bar::bootstrap(bool nodraw) { reconfigure_window(); m_connection.map_window(m_window); - m_connection.flush(); + + m_log.trace("bar: Attach parser signal handlers"); + g_signals::parser::background_change = bind(&renderer::set_background, m_renderer.get(), ph::_1); + g_signals::parser::foreground_change = bind(&renderer::set_foreground, m_renderer.get(), ph::_1); + g_signals::parser::underline_change = bind(&renderer::set_underline, m_renderer.get(), ph::_1); + g_signals::parser::overline_change = bind(&renderer::set_overline, m_renderer.get(), ph::_1); + g_signals::parser::pixel_offset = bind(&renderer::fill_shift, m_renderer.get(), ph::_1); + g_signals::parser::alignment_change = bind(&renderer::set_alignment, m_renderer.get(), ph::_1); + g_signals::parser::attribute_set = bind(&renderer::set_attribute, m_renderer.get(), ph::_1, true); + g_signals::parser::attribute_unset = bind(&renderer::set_attribute, m_renderer.get(), ph::_1, false); + g_signals::parser::attribute_toggle = bind(&renderer::toggle_attribute, m_renderer.get(), ph::_1); + g_signals::parser::action_block_open = bind(&renderer::begin_action, m_renderer.get(), ph::_1, ph::_2); + g_signals::parser::action_block_close = bind(&renderer::end_action, m_renderer.get(), ph::_1); + g_signals::parser::font_change = bind(&renderer::set_fontindex, m_renderer.get(), ph::_1); + g_signals::parser::ascii_text_write = bind(&renderer::draw_character, m_renderer.get(), ph::_1); + g_signals::parser::unicode_text_write = bind(&renderer::draw_character, m_renderer.get(), ph::_1); + g_signals::parser::string_write = bind(&renderer::draw_textstring, m_renderer.get(), ph::_1, ph::_2); // Render empty bar - m_renderer->begin(); - m_renderer->end(); + try { + m_renderer->begin(); + m_renderer->end(); + } catch (const exception& err) { + throw application_error("Failed to output empty bar window (reason: " + string{err.what()} + ")"); + } + + m_connection.flush(); } /** @@ -404,13 +367,18 @@ void bar::parse(string data, bool force) { m_renderer->begin(); try { - parser parser(m_opts); + parser parser{m_log, m_opts}; parser(data); } catch (const unrecognized_token& err) { m_log.err("Unrecognized syntax token '%s'", err.what()); + } catch (const unrecognized_attribute& err) { + m_log.err("Unrecognized attribute '%s'", err.what()); + } catch (const exception& err) { + m_log.err("Error parsing contents (err: %s)", err.what()); } m_renderer->end(); + m_connection.flush(); } /** @@ -666,7 +634,6 @@ void bar::handle(const evt::expose& evt) { * pseudo-transparent background when it changes */ void bar::handle(const evt::property_notify& evt) { - (void)evt; #if DEBUG string atom_name = m_connection.get_atom_name(evt->atom).name(); m_log.trace("bar: property_notify(%s)", atom_name); @@ -674,7 +641,7 @@ void bar::handle(const evt::property_notify& evt) { if (evt->window == m_window && evt->atom == WM_STATE) { if (!g_signals::bar::visibility_change) { - return; + return m_log.trace("bar: no callback handler set for bar visibility change"); } try { diff --git a/src/components/builder.cpp b/src/components/builder.cpp index 370a4215..46986787 100644 --- a/src/components/builder.cpp +++ b/src/components/builder.cpp @@ -6,41 +6,57 @@ POLYBAR_NS -void builder::set_lazy(bool mode) { - m_lazy = mode; -} - +/** + * Flush contents of the builder and return built string + * + * This will also close any unclosed tags + */ string builder::flush() { - while (m_counters[syntaxtag::A] > 0) cmd_close(true); - while (m_counters[syntaxtag::B] > 0) background_close(true); - while (m_counters[syntaxtag::F] > 0) color_close(true); - while (m_counters[syntaxtag::T] > 0) font_close(true); - while (m_counters[syntaxtag::Uo] > 0) overline_color_close(true); - while (m_counters[syntaxtag::Uu] > 0) underline_color_close(true); - while (m_counters[syntaxtag::U] > 0) line_color_close(true); - while (m_counters[syntaxtag::u] > 0) underline_close(true); - while (m_counters[syntaxtag::o] > 0) overline_close(true); + if (m_tags[syntaxtag::A]) + cmd_close(); + if (m_tags[syntaxtag::B]) + background_close(); + if (m_tags[syntaxtag::F]) + color_close(); + if (m_tags[syntaxtag::T]) + font_close(); + if (m_tags[syntaxtag::o]) + overline_color_close(); + if (m_tags[syntaxtag::u]) + underline_color_close(); + if ((m_attributes >> static_cast(attribute::UNDERLINE)) & 1U) + underline_close(); + if ((m_attributes >> static_cast(attribute::OVERLINE)) & 1U) + overline_close(); string output = m_output.data(); // reset values - m_output.clear(); - for (auto& counter : m_counters) counter.second = 0; + for (auto& counter : m_tags) counter.second = 0; for (auto& value : m_colors) value.second = ""; + m_output.clear(); m_fontindex = 1; return string_util::replace_all(output, string{BUILDER_SPACE_TOKEN}, " "); } +/** + * Insert raw text string + */ void builder::append(string text) { string str(text); - auto len = str.length(); + size_t len{str.length()}; if (len > 2 && str[0] == '"' && str[len - 1] == '"') m_output += str.substr(1, len - 2); else m_output += str; } +/** + * Insert text node + * + * This will also parse raw syntax tags + */ void builder::node(string str, bool add_space) { string::size_type n, m; string s(str); @@ -50,7 +66,7 @@ void builder::node(string str, bool add_space) { break; } else if ((n = s.find("%{F-}")) == 0) { - color_close(true); + color_close(); s.erase(0, 5); } else if ((n = s.find("%{F#")) == 0 && (m = s.find("}")) != string::npos) { @@ -61,7 +77,7 @@ void builder::node(string str, bool add_space) { s.erase(n, m + 1); } else if ((n = s.find("%{B-}")) == 0) { - background_close(true); + background_close(); s.erase(0, 5); } else if ((n = s.find("%{B#")) == 0 && (m = s.find("}")) != string::npos) { @@ -69,7 +85,7 @@ void builder::node(string str, bool add_space) { s.erase(n, m + 1); } else if ((n = s.find("%{T-}")) == 0) { - font_close(true); + font_close(); s.erase(0, 5); } else if ((n = s.find("%{T")) == 0 && (m = s.find("}")) != string::npos) { @@ -77,23 +93,23 @@ void builder::node(string str, bool add_space) { s.erase(n, m + 1); } else if ((n = s.find("%{U-}")) == 0) { - line_color_close(true); + line_color_close(); s.erase(0, 5); - } else if ((n = s.find("%{Uu-}")) == 0) { - underline_color_close(true); - s.erase(0, 6); + } else if ((n = s.find("%{u-}")) == 0) { + underline_color_close(); + s.erase(0, 5); - } else if ((n = s.find("%{Uo-}")) == 0) { - overline_color_close(true); - s.erase(0, 6); + } else if ((n = s.find("%{o-}")) == 0) { + overline_color_close(); + s.erase(0, 5); - } else if ((n = s.find("%{Uu#")) == 0 && (m = s.find("}")) != string::npos) { - underline_color(s.substr(n + 4, m - 4)); + } else if ((n = s.find("%{u#")) == 0 && (m = s.find("}")) != string::npos) { + underline_color(s.substr(n + 3, m - 3)); s.erase(n, m + 1); - } else if ((n = s.find("%{Uo#")) == 0 && (m = s.find("}")) != string::npos) { - overline_color(s.substr(n + 4, m - 4)); + } else if ((n = s.find("%{o#")) == 0 && (m = s.find("}")) != string::npos) { + overline_color(s.substr(n + 3, m - 3)); s.erase(n, m + 1); } else if ((n = s.find("%{U#")) == 0 && (m = s.find("}")) != string::npos) { @@ -109,15 +125,15 @@ void builder::node(string str, bool add_space) { s.erase(0, 5); } else if ((n = s.find("%{-u}")) == 0) { - underline_close(true); + underline_close(); s.erase(0, 5); } else if ((n = s.find("%{-o}")) == 0) { - overline_close(true); + overline_close(); s.erase(0, 5); } else if ((n = s.find("%{A}")) == 0) { - cmd_close(true); + cmd_close(); s.erase(0, 4); } else if ((n = s.find("%{")) == 0 && (m = s.find("}")) != string::npos) { @@ -138,35 +154,36 @@ void builder::node(string str, bool add_space) { space(); } +/** + * Insert text node with specific font index + * + * @see builder::node + */ void builder::node(string str, int font_index, bool add_space) { font(font_index); node(str, add_space); font_close(); } -// void builder::node(progressbar_t bar, float perc, bool add_space) { -// if (!bar) -// return; -// node(bar->get_output(math_util::cap(0, 100, perc)), add_space); -// } - +/** + * Insert tags for given label + */ void builder::node(label_t label, bool add_space) { if (!label || !*label) return; - auto text = label->get(); + string text{label->get()}; if (label->m_maxlen > 0 && text.length() > label->m_maxlen) { text = text.substr(0, label->m_maxlen) + "..."; } - if ((label->m_overline.empty() && m_counters[syntaxtag::o] > 0) || - (m_counters[syntaxtag::o] > 0 && label->m_margin > 0)) - overline_close(true); - if ((label->m_underline.empty() && m_counters[syntaxtag::u] > 0) || - (m_counters[syntaxtag::u] > 0 && label->m_margin > 0)) - underline_close(true); + // if ((label->m_overline.empty() && m_tags[syntaxtag::o] > 0) || (m_tags[syntaxtag::o] > 0 && label->m_margin > 0)) + // overline_close(); + // if ((label->m_underline.empty() && m_tags[syntaxtag::u] > 0) || (m_tags[syntaxtag::u] > 0 && label->m_margin > 0)) + // underline_close(); + // TODO: Replace with margin-left if (label->m_margin > 0) space(label->m_margin); @@ -175,46 +192,48 @@ void builder::node(label_t label, bool add_space) { if (!label->m_underline.empty()) underline(label->m_underline); - background(label->m_background); - color(label->m_foreground); + if (!label->m_background.empty()) + background(label->m_background); + if (!label->m_foreground.empty()) + color(label->m_foreground); + // TODO: Replace with padding-left if (label->m_padding > 0) space(label->m_padding); node(text, label->m_font, add_space); + // TODO: Replace with padding-right if (label->m_padding > 0) space(label->m_padding); - color_close(m_lazy && label->m_margin > 0); - background_close(m_lazy && label->m_margin > 0); + if (!label->m_background.empty()) + background_close(); + if (!label->m_foreground.empty()) + color_close(); - if (!label->m_underline.empty() || (label->m_margin > 0 && m_counters[syntaxtag::u] > 0)) - underline_close(m_lazy && label->m_margin > 0); - if (!label->m_overline.empty() || (label->m_margin > 0 && m_counters[syntaxtag::o] > 0)) - overline_close(m_lazy && label->m_margin > 0); + if (!label->m_underline.empty() || (label->m_margin > 0 && m_tags[syntaxtag::u] > 0)) + underline_close(); + if (!label->m_overline.empty() || (label->m_margin > 0 && m_tags[syntaxtag::o] > 0)) + overline_close(); + // TODO: Replace with margin-right if (label->m_margin > 0) space(label->m_margin); } -// void builder::node(ramp_t ramp, float perc, bool add_space) { -// if (!ramp) -// return; -// node(ramp->get_by_percentage(math_util::cap(0, 100, perc)), add_space); -// } - -// void builder::node(animation_t animation, bool add_space) { -// if (!animation) -// return; -// node(animation->get(), add_space); -// } - +/** + * Insert tag that will offset the contents by given pixels + */ void builder::offset(int pixels) { - if (pixels != 0) - tag_open('O', std::to_string(pixels)); + if (pixels == 0) + return; + tag_open(syntaxtag::O, to_string(pixels)); } +/** + * Insert spaces + */ void builder::space(int width) { if (width == DEFAULT_SPACING) width = m_bar.spacing; @@ -224,6 +243,9 @@ void builder::space(int width) { append(str); } +/** + * Remove trailing space + */ void builder::remove_trailing_space(int width) { if (width == DEFAULT_SPACING) width = m_bar.spacing; @@ -235,87 +257,70 @@ void builder::remove_trailing_space(int width) { m_output = m_output.substr(0, m_output.length() - spacing); } -void builder::invert() { - tag_open('R', ""); -} - +/** + * Insert tag to alter the current font index + */ void builder::font(int index) { - if (index <= 0 && m_counters[syntaxtag::T] > 0) - font_close(true); - if (index <= 0 || index == m_fontindex) - return; - if (m_lazy && m_counters[syntaxtag::T] > 0) - font_close(true); - - m_counters[syntaxtag::T]++; m_fontindex = index; - tag_open('T', std::to_string(index)); + tag_open(syntaxtag::T, to_string(index)); } -void builder::font_close(bool force) { - if ((!force && m_lazy) || m_counters[syntaxtag::T] <= 0) - return; - - m_counters[syntaxtag::T]--; +/** + * Insert tag to reset the font index + */ +void builder::font_close() { m_fontindex = 1; - tag_close('T'); + tag_close(syntaxtag::T); } +/** + * Insert tag to alter the current background color + */ void builder::background(string color) { if (color.length() == 2 || (color.find("#") == 0 && color.length() == 3)) { + string bg{background_hex()}; color = "#" + color.substr(color.length() - 2); - auto bg = color_util::hex(m_bar.background); color += bg.substr(bg.length() - (bg.length() < 6 ? 3 : 6)); } else if (color.length() >= 7 && color == "#" + string(color.length() - 1, color[1])) { color = color.substr(0, 4); } - if (color.empty() && m_counters[syntaxtag::B] > 0) - background_close(true); - if (color.empty() || color == m_colors[syntaxtag::B]) - return; - if (m_lazy && m_counters[syntaxtag::B] > 0) - background_close(true); - - m_counters[syntaxtag::B]++; + color = color_util::simplify_hex(color); m_colors[syntaxtag::B] = color; - tag_open('B', color); + tag_open(syntaxtag::B, color); } -void builder::background_close(bool force) { - if ((!force && m_lazy) || m_counters[syntaxtag::B] <= 0) - return; - - m_counters[syntaxtag::B]--; +/** + * Insert tag to reset the background color + */ +void builder::background_close() { m_colors[syntaxtag::B] = ""; - tag_close('B'); + tag_close(syntaxtag::B); } -void builder::color(string color_) { - auto color(color_); +/** + * Insert tag to alter the current foreground color + */ +void builder::color(string color) { if (color.length() == 2 || (color.find("#") == 0 && color.length() == 3)) { + string fg{foreground_hex()}; color = "#" + color.substr(color.length() - 2); - auto fg = color_util::hex(m_bar.foreground); color += fg.substr(fg.length() - (fg.length() < 6 ? 3 : 6)); } else if (color.length() >= 7 && color == "#" + string(color.length() - 1, color[1])) { color = color.substr(0, 4); } - if (color.empty() && m_counters[syntaxtag::F] > 0) - color_close(true); - if (color.empty() || color == m_colors[syntaxtag::F]) - return; - if (m_lazy && m_counters[syntaxtag::F] > 0) - color_close(true); - - m_counters[syntaxtag::F]++; + color = color_util::simplify_hex(color); m_colors[syntaxtag::F] = color; - tag_open('F', color); + tag_open(syntaxtag::F, color); } -void builder::color_alpha(string alpha_) { - auto alpha(alpha_); - string val = color_util::hex(m_bar.foreground); +/** + * Insert tag to alter the alpha value of the default foreground color + */ +void builder::color_alpha(string alpha) { + string val{foreground_hex()}; + if (alpha.find("#") == std::string::npos) { alpha = "#" + alpha; } @@ -332,117 +337,103 @@ void builder::color_alpha(string alpha_) { color((alpha.substr(0, 3) + val.substr(val.size() - 6)).substr(0, 9)); } -void builder::color_close(bool force) { - if ((!force && m_lazy) || m_counters[syntaxtag::F] <= 0) - return; - - m_counters[syntaxtag::F]--; +/** + * Insert tag to reset the foreground color + */ +void builder::color_close() { m_colors[syntaxtag::F] = ""; - tag_close('F'); + tag_close(syntaxtag::F); } +/** + * Insert tag to alter the current overline/underline color + */ void builder::line_color(string color) { - if (color.empty() && m_counters[syntaxtag::U] > 0) - line_color_close(true); - if (color.empty() || color == m_colors[syntaxtag::U]) - return; - if (m_lazy && m_counters[syntaxtag::U] > 0) - line_color_close(true); - - m_counters[syntaxtag::U]++; - m_colors[syntaxtag::U] = color; - tag_open('U', color); + overline_color(color); + underline_color(color); } -void builder::line_color_close(bool force) { - if ((!force && m_lazy) || m_counters[syntaxtag::U] <= 0) - return; - - m_counters[syntaxtag::U]--; - m_colors[syntaxtag::U] = ""; - tag_close('U'); +/** + * Close overline/underline color tag + */ +void builder::line_color_close() { + overline_color_close(); + underline_color_close(); } +/** + * Insert tag to alter the current overline color + */ void builder::overline_color(string color) { - if (color.empty() && m_counters[syntaxtag::Uo] > 0) - overline_color_close(true); - if (color.empty() || color == m_colors[syntaxtag::Uo]) - return; - if (m_lazy && m_counters[syntaxtag::Uo] > 0) - overline_color_close(true); - - m_counters[syntaxtag::Uo]++; - m_colors[syntaxtag::Uo] = color; - append("%{Uo" + color + "}"); + color = color_util::simplify_hex(color); + m_colors[syntaxtag::o] = color; + tag_open(syntaxtag::o, color); + tag_open(attribute::OVERLINE); } -void builder::overline_color_close(bool force) { - if ((!force && m_lazy) || m_counters[syntaxtag::Uo] <= 0) - return; - - m_counters[syntaxtag::Uo]--; - m_colors[syntaxtag::Uo] = ""; - append("%{Uu-}"); +/** + * Close underline color tag + */ +void builder::overline_color_close() { + m_colors[syntaxtag::o] = ""; + tag_close(syntaxtag::o); } +/** + * Insert tag to alter the current underline color + */ void builder::underline_color(string color) { - if (color.empty() && m_counters[syntaxtag::Uu] > 0) - underline_color_close(true); - if (color.empty() || color == m_colors[syntaxtag::Uu]) - return; - if (m_lazy && m_counters[syntaxtag::Uu] > 0) - underline_color_close(true); - - m_counters[syntaxtag::Uu]++; - m_colors[syntaxtag::Uu] = color; - append("%{Uu" + color + "}"); + color = color_util::simplify_hex(color); + m_colors[syntaxtag::u] = color; + tag_open(syntaxtag::u, color); + tag_open(attribute::UNDERLINE); } -void builder::underline_color_close(bool force) { - if ((!force && m_lazy) || m_counters[syntaxtag::Uu] <= 0) - return; - - m_counters[syntaxtag::Uu]--; - m_colors[syntaxtag::Uu] = ""; - append("%{Uu-}"); +/** + * Close underline color tag + */ +void builder::underline_color_close() { + tag_close(syntaxtag::u); + m_colors[syntaxtag::u] = ""; } +/** + * Insert tag to enable the overline attribute + */ void builder::overline(string color) { if (!color.empty()) overline_color(color); - if (m_counters[syntaxtag::o] > 0) - return; - - m_counters[syntaxtag::o]++; - append("%{+o}"); + else + tag_open(attribute::OVERLINE); } -void builder::overline_close(bool force) { - if ((!force && m_lazy) || m_counters[syntaxtag::o] <= 0) - return; - - m_counters[syntaxtag::o]--; - append("%{-o}"); +/** + * Close overline attribute tag + */ +void builder::overline_close() { + tag_close(attribute::OVERLINE); } +/** + * Insert tag to enable the underline attribute + */ void builder::underline(string color) { if (!color.empty()) underline_color(color); - if (m_counters[syntaxtag::u] > 0) - return; - - m_counters[syntaxtag::u]++; - append("%{+u}"); + else + tag_open(attribute::UNDERLINE); } -void builder::underline_close(bool force) { - if ((!force && m_lazy) || m_counters[syntaxtag::u] <= 0) - return; - - m_counters[syntaxtag::u]--; - append("%{-u}"); +/** + * Close underline attribute tag + */ +void builder::underline_close() { + tag_close(attribute::UNDERLINE); } +/** + * Open command tag + */ void builder::cmd(mousebtn index, string action, bool condition) { int button = static_cast(index); @@ -455,23 +446,148 @@ void builder::cmd(mousebtn index, string action, bool condition) { action = string_util::replace_all(action, "{", "\\{"); action = string_util::replace_all(action, "%", "\x0025"); - append("%{A" + std::to_string(button) + ":" + action + ":}"); - m_counters[syntaxtag::A]++; + tag_open(syntaxtag::A, to_string(button) + ":" + action + ":"); } -void builder::cmd_close(bool force) { - if (m_counters[syntaxtag::A] > 0 || force) - append("%{A}"); - if (m_counters[syntaxtag::A] > 0) - m_counters[syntaxtag::A]--; +/** + * Close command tag + */ +void builder::cmd_close() { + tag_close(syntaxtag::A); } -void builder::tag_open(char tag, string value) { - append("%{" + string({tag}) + value + "}"); +/** + * Get default background hex string + */ +string builder::background_hex() { + if (m_background.empty()) + m_background = color_util::hex(m_bar.background); + return m_background; } -void builder::tag_close(char tag) { - append("%{" + string({tag}) + "-}"); +/** + * Get default foreground hex string + */ +string builder::foreground_hex() { + if (m_foreground.empty()) + m_foreground = color_util::hex(m_bar.foreground); + return m_foreground; +} + +/** + * Insert directive to change value of given tag + */ +void builder::tag_open(syntaxtag tag, string value) { + if (m_tags.find(tag) != m_tags.end()) + m_tags[tag]++; + + switch (tag) { + case syntaxtag::NONE: + break; + case syntaxtag::A: + append("%{A" + value + "}"); + break; + case syntaxtag::F: + append("%{F" + value + "}"); + break; + case syntaxtag::B: + append("%{B" + value + "}"); + break; + case syntaxtag::T: + append("%{T" + value + "}"); + break; + case syntaxtag::u: + append("%{u" + value + "}"); + break; + case syntaxtag::o: + append("%{o" + value + "}"); + break; + case syntaxtag::R: + append("%{R}"); + break; + case syntaxtag::O: + append("%{O" + value + "}"); + break; + } +} + +/** + * Insert directive to use given attribute unless already set + */ +void builder::tag_open(attribute attr) { + if ((m_attributes >> static_cast(attr)) & 1U) + return; + + m_attributes |= 1U << static_cast(attr); + + switch (attr) { + case attribute::NONE: + break; + case attribute::UNDERLINE: + append("%{+u}"); + break; + case attribute::OVERLINE: + append("%{+o}"); + break; + } +} + +/** + * Insert directive to reset given tag if it's open and closable + */ +void builder::tag_close(syntaxtag tag) { + if (!m_tags[tag] || m_tags.find(tag) == m_tags.end()) + return; + + m_tags[tag]--; + + switch (tag) { + case syntaxtag::NONE: + break; + case syntaxtag::A: + append("%{A}"); + break; + case syntaxtag::F: + append("%{F-}"); + break; + case syntaxtag::B: + append("%{B-}"); + break; + case syntaxtag::T: + append("%{T-}"); + break; + case syntaxtag::u: + append("%{u-}"); + break; + case syntaxtag::o: + append("%{o-}"); + break; + case syntaxtag::R: + break; + case syntaxtag::O: + break; + } +} + +/** + * Insert directive to remove given attribute if set + */ +void builder::tag_close(attribute attr) { + if (!((m_attributes >> static_cast(attr)) & 1U)) + return; + + m_attributes &= ~(1U << static_cast(attr)); + + switch (attr) { + case attribute::NONE: + break; + case attribute::UNDERLINE: + append("%{-u}"); + break; + case attribute::OVERLINE: + append("%{-o}"); + break; + } } POLYBAR_NS_END diff --git a/src/components/controller.cpp b/src/components/controller.cpp index eb8691b7..183d85ba 100644 --- a/src/components/controller.cpp +++ b/src/components/controller.cpp @@ -430,7 +430,7 @@ void controller::bootstrap_modules() { module_count++; } catch (const std::runtime_error& err) { - m_log.err("Disabling module \"%s\" (error: %s)", module_name, err.what()); + m_log.err("Disabling module \"%s\" (reason: %s)", module_name, err.what()); } } } @@ -555,8 +555,8 @@ void controller::on_update() { block_contents = string_util::replace_all(block_contents, "B-}%{B#", "B#"); block_contents = string_util::replace_all(block_contents, "F-}%{F#", "F#"); block_contents = string_util::replace_all(block_contents, "U-}%{U#", "U#"); - block_contents = string_util::replace_all(block_contents, "Uu-}%{Uu#", "Uu#"); - block_contents = string_util::replace_all(block_contents, "Uo-}%{Uo#", "Uo#"); + block_contents = string_util::replace_all(block_contents, "u-}%{u#", "u#"); + block_contents = string_util::replace_all(block_contents, "o-}%{o#", "o#"); // Join consecutive tags contents += string_util::replace_all(block_contents, "}%{", " "); @@ -564,13 +564,22 @@ void controller::on_update() { if (m_writeback) { std::cout << contents << std::endl; - } else { - m_bar->parse(contents); + return; } - if (!m_trayactivated) { - m_trayactivated = true; - m_bar->activate_tray(); + try { + m_bar->parse(contents); + } catch (const exception& err) { + m_log.err("Failed to update bar contents (reason: %s)", err.what()); + } + + try { + if (!m_trayactivated) { + m_trayactivated = true; + m_bar->activate_tray(); + } + } catch (const exception& err) { + m_log.err("Failed to active tray manager (reason: %s)", err.what()); } } diff --git a/src/components/parser.cpp b/src/components/parser.cpp index 6866b4e3..d246194a 100644 --- a/src/components/parser.cpp +++ b/src/components/parser.cpp @@ -1,3 +1,6 @@ +#include + +#include "components/logger.hpp" #include "components/parser.hpp" #include "components/signals.hpp" #include "components/types.hpp" @@ -6,14 +9,35 @@ POLYBAR_NS -parser::parser(const bar_settings& bar) : m_bar(bar) {} +/** + * Construct parser instance + */ +parser::parser(const logger& logger, const bar_settings& bar) : m_log(logger), m_bar(bar) { + assert(g_signals::parser::background_change != nullptr); + assert(g_signals::parser::foreground_change != nullptr); + assert(g_signals::parser::underline_change != nullptr); + assert(g_signals::parser::overline_change != nullptr); + assert(g_signals::parser::alignment_change != nullptr); + assert(g_signals::parser::attribute_set != nullptr); + assert(g_signals::parser::attribute_unset != nullptr); + assert(g_signals::parser::attribute_toggle != nullptr); + assert(g_signals::parser::font_change != nullptr); + assert(g_signals::parser::pixel_offset != nullptr); + assert(g_signals::parser::action_block_open != nullptr); + assert(g_signals::parser::action_block_close != nullptr); + assert(g_signals::parser::ascii_text_write != nullptr); + assert(g_signals::parser::unicode_text_write != nullptr); + assert(g_signals::parser::string_write != nullptr); +} /** - * Parse input data + * Process input string */ void parser::operator()(string data) { size_t pos; + m_log.trace_x("parser: %s", data); + while (data.length()) { if (data.compare(0, 2, "%{") == 0 && (pos = data.find("}")) != string::npos) { codeblock(data.substr(2, pos - 2)); @@ -27,7 +51,7 @@ void parser::operator()(string data) { } /** - * Parse contents in tag blocks, i.e: %{...} + * Process contents within tag blocks, i.e: %{...} */ void parser::codeblock(string data) { size_t pos; @@ -38,7 +62,7 @@ void parser::codeblock(string data) { if (data.empty()) break; - char tag = data[0]; + char tag{data[0]}; string value; // Remove the tag @@ -51,72 +75,61 @@ void parser::codeblock(string data) { switch (tag) { case 'B': - // Ignore tag if it occurs again later in the same block - if (data.find(" B") == string::npos && g_signals::parser::color_change) - g_signals::parser::color_change(gc::BG, parse_color(value, m_bar.background)); + g_signals::parser::background_change(parse_color(value, m_bar.background)); break; case 'F': - // Ignore tag if it occurs again later in the same block - if (data.find(" F") == string::npos && g_signals::parser::color_change) - g_signals::parser::color_change(gc::FG, parse_color(value, m_bar.foreground)); - break; - - case 'U': - if (g_signals::parser::color_change) { - if (value[0] == 'u') { - if (data.find(" Uu") == string::npos) - g_signals::parser::color_change(gc::UL, parse_color(value.substr(1), m_bar.underline.color)); - } else if (value[0] == 'o') { - if (data.find(" Uo") == string::npos) - g_signals::parser::color_change(gc::OL, parse_color(value.substr(1), m_bar.overline.color)); - } else if (data.find(" U") == string::npos) { - g_signals::parser::color_change(gc::UL, parse_color(value, m_bar.underline.color)); - g_signals::parser::color_change(gc::OL, parse_color(value, m_bar.overline.color)); - } - } - break; - - case 'R': - if (g_signals::parser::color_change) { - g_signals::parser::color_change(gc::BG, m_bar.foreground); - g_signals::parser::color_change(gc::FG, m_bar.background); - } + g_signals::parser::foreground_change(parse_color(value, m_bar.foreground)); break; case 'T': - if (data.find(" T") == string::npos && g_signals::parser::font_change) - g_signals::parser::font_change(parse_fontindex(value)); + g_signals::parser::font_change(parse_fontindex(value)); + break; + + case 'U': + g_signals::parser::underline_change(parse_color(value, m_bar.underline.color)); + g_signals::parser::overline_change(parse_color(value, m_bar.overline.color)); + break; + + case 'u': + g_signals::parser::underline_change(parse_color(value, m_bar.underline.color)); + break; + + case 'o': + g_signals::parser::overline_change(parse_color(value, m_bar.overline.color)); + break; + + case 'R': + g_signals::parser::background_change(m_bar.foreground); + g_signals::parser::foreground_change(m_bar.background); break; case 'O': - if (g_signals::parser::pixel_offset) - g_signals::parser::pixel_offset(std::atoi(value.c_str())); + g_signals::parser::pixel_offset(atoi(value.c_str())); break; case 'l': - if (g_signals::parser::alignment_change) - g_signals::parser::alignment_change(alignment::LEFT); + g_signals::parser::alignment_change(alignment::LEFT); break; case 'c': - if (g_signals::parser::alignment_change) - g_signals::parser::alignment_change(alignment::CENTER); + g_signals::parser::alignment_change(alignment::CENTER); break; case 'r': - if (g_signals::parser::alignment_change) - g_signals::parser::alignment_change(alignment::RIGHT); + g_signals::parser::alignment_change(alignment::RIGHT); break; case '+': - if (g_signals::parser::attribute_set) - g_signals::parser::attribute_set(parse_attr(value[0])); + g_signals::parser::attribute_set(parse_attr(value[0])); break; case '-': - if (g_signals::parser::attribute_unset) - g_signals::parser::attribute_unset(parse_attr(value[0])); + g_signals::parser::attribute_unset(parse_attr(value[0])); + break; + + case '!': + g_signals::parser::attribute_toggle(parse_attr(value[0])); break; case 'A': @@ -125,16 +138,14 @@ void parser::codeblock(string data) { mousebtn btn = parse_action_btn(data); m_actions.push_back(static_cast(btn)); - if (g_signals::parser::action_block_open) - g_signals::parser::action_block_open(btn, value); + g_signals::parser::action_block_open(btn, value); // make sure we strip the correct length (btn+wrapping colons) - if (data[0] != ':') + if (value[0] != ':') value += "0"; value += "::"; } else if (!m_actions.empty()) { - if (g_signals::parser::action_block_close) - g_signals::parser::action_block_close(parse_action_btn(data)); + g_signals::parser::action_block_close(parse_action_btn(value)); m_actions.pop_back(); } break; @@ -149,12 +160,12 @@ void parser::codeblock(string data) { } /** - * Parse text strings + * Process text contents */ size_t parser::text(string data) { uint8_t* utf = (uint8_t*)data.c_str(); - if (g_signals::parser::string_write && utf[0] < 0x80) { + if (utf[0] < 0x80) { // grab all consecutive ascii chars size_t next_tag = data.find("%{"); if (next_tag != string::npos) { @@ -165,39 +176,29 @@ size_t parser::text(string data) { ; g_signals::parser::string_write(data.substr(0, n).c_str(), n); return n; - } else if (utf[0] < 0x80) { - if (g_signals::parser::ascii_text_write) - g_signals::parser::ascii_text_write(utf[0]); - return 1; } else if ((utf[0] & 0xe0) == 0xc0) { // 2 byte utf-8 sequence - if (g_signals::parser::unicode_text_write) - g_signals::parser::unicode_text_write((utf[0] & 0x1f) << 6 | (utf[1] & 0x3f)); + g_signals::parser::unicode_text_write((utf[0] & 0x1f) << 6 | (utf[1] & 0x3f)); return 2; } else if ((utf[0] & 0xf0) == 0xe0) { // 3 byte utf-8 sequence - if (g_signals::parser::unicode_text_write) - g_signals::parser::unicode_text_write((utf[0] & 0xf) << 12 | (utf[1] & 0x3f) << 6 | (utf[2] & 0x3f)); + g_signals::parser::unicode_text_write((utf[0] & 0xf) << 12 | (utf[1] & 0x3f) << 6 | (utf[2] & 0x3f)); return 3; } else if ((utf[0] & 0xf8) == 0xf0) { // 4 byte utf-8 sequence - if (g_signals::parser::unicode_text_write) - g_signals::parser::unicode_text_write(0xfffd); + g_signals::parser::unicode_text_write(0xfffd); return 4; } else if ((utf[0] & 0xfc) == 0xf8) { // 5 byte utf-8 sequence - if (g_signals::parser::unicode_text_write) - g_signals::parser::unicode_text_write(0xfffd); + g_signals::parser::unicode_text_write(0xfffd); return 5; } else if ((utf[0] & 0xfe) == 0xfc) { // 6 byte utf-8 sequence - if (g_signals::parser::unicode_text_write) - g_signals::parser::unicode_text_write(0xfffd); + g_signals::parser::unicode_text_write(0xfffd); return 6; } else { // invalid utf-8 sequence - if (g_signals::parser::ascii_text_write) - g_signals::parser::ascii_text_write(utf[0]); + g_signals::parser::ascii_text_write(utf[0]); return 1; } } /** - * TODO: docstring + * Process color hex string and convert it to the correct value */ uint32_t parser::parse_color(string s, uint32_t fallback) { uint32_t color{0}; @@ -207,10 +208,10 @@ uint32_t parser::parse_color(string s, uint32_t fallback) { } /** - * TODO: docstring + * Process font index and convert it to the correct value */ int8_t parser::parse_fontindex(string s) { - if (s.empty() || s == "-") { + if (s.empty() || s[0] == '-') { return -1; } @@ -222,22 +223,21 @@ int8_t parser::parse_fontindex(string s) { } /** - * TODO: docstring + * Process attribute token and convert it to the correct value */ -attribute parser::parse_attr(const char s) { - switch (s) { +attribute parser::parse_attr(const char attr) { + switch (attr) { case 'o': - return attribute::o; - break; + return attribute::OVERLINE; case 'u': - return attribute::u; - break; + return attribute::UNDERLINE; + default: + throw unrecognized_attribute(string{attr}); } - return attribute::NONE; } /** - * TODO: docstring + * Process action button token and convert it to the correct value */ mousebtn parser::parse_action_btn(string data) { if (data[0] == ':') @@ -251,7 +251,7 @@ mousebtn parser::parse_action_btn(string data) { } /** - * TODO: docstring + * Process action command string */ string parser::parse_action_cmd(string data) { size_t start, end; diff --git a/src/components/renderer.cpp b/src/components/renderer.cpp index 509e704c..46dfdc37 100644 --- a/src/components/renderer.cpp +++ b/src/components/renderer.cpp @@ -22,6 +22,9 @@ di::injector> configure_renderer(const bar_settings& bar, c // clang-format on } +/** + * Construct renderer instance + */ renderer::renderer(connection& conn, const logger& logger, unique_ptr font_manager, const bar_settings& bar, const vector& fonts) : m_connection(conn), m_log(logger), m_fontmanager(forward(font_manager)), m_bar(bar) { @@ -35,20 +38,19 @@ renderer::renderer(connection& conn, const logger& logger, unique_ptrroot, m_visual->visual_id); m_window = m_connection.generate_id(); - m_log.trace("renderer: Create window %s", m_connection.id(m_window)); + m_log.trace("renderer: Create window (xid=%s)", m_connection.id(m_window)); { uint32_t mask{0}; uint32_t values[16]{0}; xcb_params_cw_t params; - // clang-format off XCB_AUX_ADD_PARAM(&mask, ¶ms, back_pixel, 0); XCB_AUX_ADD_PARAM(&mask, ¶ms, border_pixel, 0); XCB_AUX_ADD_PARAM(&mask, ¶ms, backing_store, XCB_BACKING_STORE_WHEN_MAPPED); XCB_AUX_ADD_PARAM(&mask, ¶ms, colormap, m_colormap); XCB_AUX_ADD_PARAM(&mask, ¶ms, override_redirect, m_bar.force_docking); - XCB_AUX_ADD_PARAM(&mask, ¶ms, event_mask, XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS); - // clang-format on + XCB_AUX_ADD_PARAM(&mask, ¶ms, event_mask, + XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS); xutils::pack_values(mask, ¶ms, values); m_connection.create_window(32, m_window, screen->root, m_bar.pos.x, m_bar.pos.y, m_bar.size.w, m_bar.size.h, 0, @@ -74,17 +76,17 @@ renderer::renderer(connection& conn, const logger& logger, unique_ptr fd = string_util::split(f, ';'); + vector fd{string_util::split(f, ';')}; string pattern{fd[0]}; int offset{0}; @@ -123,27 +125,41 @@ renderer::renderer(connection& conn, const logger& logger, unique_ptrcreate_xftdraw(m_pixmap, m_colormap); } +/** + * End render routine + */ void renderer::end() { + m_log.trace_x("renderer: end"); + redraw(); m_fontmanager->destroy_xftdraw(); @@ -155,74 +171,104 @@ void renderer::end() { m_reserve_at = edge::NONE; } +/** + * Redraw window contents + */ void renderer::redraw() { - m_log.info("renderer: redrawing"); + m_log.info("Redrawing"); - xcb_rectangle_t rect{0, 0, m_bar.size.w, m_bar.size.h}; + xcb_rectangle_t r{0, 0, m_bar.size.w, m_bar.size.h}; if (m_reserve_at == edge::LEFT) { - rect.x += m_reserve; - rect.width -= m_reserve; + r.x += m_reserve; + r.width -= m_reserve; } else if (m_reserve_at == edge::RIGHT) { - rect.width -= m_reserve; + r.width -= m_reserve; } - fill_border(m_bar.borders, edge::ALL); - - m_connection.copy_area( - m_pixmap, m_window, m_gcontexts.at(gc::FG), rect.x, rect.y, rect.x, rect.y, rect.width, rect.height); - m_connection.flush(); + m_connection.copy_area(m_pixmap, m_window, m_gcontexts.at(gc::FG), r.x, r.y, r.x, r.y, r.width, r.height); } +/** + * Reserve space at given edge + */ void renderer::reserve_space(edge side, uint16_t w) { m_log.trace_x("renderer: reserve_space(%i, %i)", static_cast(side), w); m_reserve = w; m_reserve_at = side; } +/** + * Change value of background gc + */ void renderer::set_background(const uint32_t color) { - if (color == m_background) - return; + if (m_colors[gc::BG] == color) { + return m_log.trace_x("renderer: ignoring unchanged background color(#%08x)", color); + } m_log.trace_x("renderer: set_background(#%08x)", color); m_connection.change_gc(m_gcontexts.at(gc::BG), XCB_GC_FOREGROUND, &color); - m_background = color; + m_colors[gc::BG] = color; shift_content(0); } +/** + * Change value of foreground gc + */ void renderer::set_foreground(const uint32_t color) { - if (color == m_foreground) - return; + if (m_colors[gc::FG] == color) { + return m_log.trace_x("renderer: ignoring unchanged foreground color(#%08x)", color); + } m_log.trace_x("renderer: set_foreground(#%08x)", color); m_connection.change_gc(m_gcontexts.at(gc::FG), XCB_GC_FOREGROUND, &color); m_fontmanager->allocate_color(color); - m_foreground = color; + m_colors[gc::FG] = color; } +/** + * Change value of underline gc + */ void renderer::set_underline(const uint32_t color) { - if (color == m_foreground) - return; + if (m_colors[gc::UL] == color) { + return m_log.trace_x("renderer: ignoring unchanged underline color(#%08x)", color); + } m_log.trace_x("renderer: set_underline(#%08x)", color); m_connection.change_gc(m_gcontexts.at(gc::UL), XCB_GC_FOREGROUND, &color); - m_underline = color; + m_colors[gc::UL] = color; } +/** + * Change value of overline gc + */ void renderer::set_overline(const uint32_t color) { - if (color == m_foreground) - return; + if (m_colors[gc::OL] == color) { + return m_log.trace_x("renderer: ignoring unchanged overline color(#%08x)", color); + } m_log.trace_x("renderer: set_overline(#%08x)", color); m_connection.change_gc(m_gcontexts.at(gc::OL), XCB_GC_FOREGROUND, &color); - m_overline = color; + m_colors[gc::OL] = color; } -void renderer::set_fontindex(const uint8_t font) { - m_log.trace_x("renderer: set_fontindex(%i)", static_cast(font)); +/** + * Change preferred font index used when matching glyphs + */ +void renderer::set_fontindex(const int8_t font) { + if (m_fontindex == font) { + return m_log.trace_x("renderer: ignoring unchanged font index(%i)", static_cast(font)); + } + m_log.trace_x("renderer: set_fontindex(%i)", static_cast(font)); m_fontmanager->set_preferred_font(font); + m_fontindex = font; } +/** + * Change current alignment + */ void renderer::set_alignment(const alignment align) { if (align == m_alignment) { - return; - } else if (align == alignment::LEFT) { + return m_log.trace_x("renderer: ignoring unchanged alignment(%i)", static_cast(align)); + } + + if (align == alignment::LEFT) { m_currentx = m_bar.borders.at(edge::LEFT).size; } else if (align == alignment::RIGHT) { m_currentx = m_bar.borders.at(edge::RIGHT).size; @@ -240,17 +286,40 @@ void renderer::set_alignment(const alignment align) { m_alignment = align; } +/** + * Enable/remove attribute + */ void renderer::set_attribute(const attribute attr, bool state) { m_log.trace_x("renderer: set_attribute(%i, %i)", static_cast(attr), state); if (state) { - m_attributes |= static_cast(attr); + m_attributes |= 1U << static_cast(attr); } else { - m_attributes ^= static_cast(attr); + m_attributes &= ~(1U << static_cast(attr)); } } +/** + * Toggle attribute + */ +void renderer::toggle_attribute(const attribute attr) { + m_log.trace_x("renderer: toggle_attribute(%i)", static_cast(attr)); + m_attributes ^= 1U << static_cast(attr); +} + +/** + * Check if the given attribute is set + */ +bool renderer::check_attribute(const attribute attr) { + return (m_attributes >> static_cast(attr)) & 1U; +} + +/** + * Fill background area + */ void renderer::fill_background() { + m_log.trace_x("renderer: fill_background"); + xcb_rectangle_t rect{0, 0, m_bar.size.w, m_bar.size.h}; if (m_reserve_at == edge::LEFT) { @@ -263,11 +332,14 @@ void renderer::fill_background() { draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), rect.x, rect.y, rect.width, rect.height); } +/** + * Fill border area + */ void renderer::fill_border(const map& borders, edge border) { + m_log.trace_x("renderer: fill_border(%i)", static_cast(border)); + for (auto&& b : borders) { - if (border != edge::ALL && b.first != border) - continue; - if (b.second.size <= 0) + if (!b.second.size || (border != edge::ALL && b.first != border)) continue; switch (b.first) { @@ -295,25 +367,52 @@ void renderer::fill_border(const map& borders, edge borde } } +/** + * Fill overline area + */ void renderer::fill_overline(int16_t x, uint16_t w) { - if (!m_bar.overline.size || !(m_attributes & static_cast(attribute::o))) - return; - int16_t y{static_cast(m_bar.borders.at(edge::TOP).size)}; - draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::OL), x, y, w, m_bar.overline.size); + if (!check_attribute(attribute::OVERLINE)) { + return m_log.trace_x("renderer: not filling overline (flag unset)"); + } else if (!m_bar.overline.size) { + return m_log.trace_x("renderer: not filling overline (size=0)"); + } + m_log.trace_x("renderer: fill_overline(%i, #%08x)", m_bar.overline.size, m_colors[gc::OL]); + const xcb_rectangle_t inner{m_bar.inner_area(true)}; + draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::OL), x, inner.y, w, m_bar.overline.size); } +/** + * Fill underline area + */ void renderer::fill_underline(int16_t x, uint16_t w) { - if (!m_bar.underline.size || !(m_attributes & static_cast(attribute::u))) - return; - int16_t y{static_cast(m_bar.size.h - m_bar.borders.at(edge::BOTTOM).size - m_bar.underline.size)}; + if (!check_attribute(attribute::UNDERLINE)) { + return m_log.trace_x("renderer: not filling underline (flag unset)"); + } else if (!m_bar.underline.size) { + return m_log.trace_x("renderer: not filling underline (size=0)"); + } + m_log.trace_x("renderer: fill_underline(%i, #%08x)", m_bar.underline.size, m_colors[gc::UL]); + const xcb_rectangle_t inner{m_bar.inner_area(true)}; + int16_t y{static_cast(inner.height - m_bar.underline.size)}; draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::UL), x, y, w, m_bar.underline.size); } +/** + * Shift filled area by given pixels + */ +void renderer::fill_shift(const int16_t px) { + shift_content(px); +} + +/** + * Draw character glyph + */ void renderer::draw_character(uint16_t character) { + m_log.trace_x("renderer: draw_character(\"%c\")", character); + auto& font = m_fontmanager->match_char(character); if (!font) { - return; + return m_log.warn("No suitable font found (character=%i)", character); } if (font->ptr && font->ptr != m_gcfont) { @@ -340,7 +439,12 @@ void renderer::draw_character(uint16_t character) { } } +/** + * Draw character glyphs + */ void renderer::draw_textstring(const char* text, size_t len) { + m_log.trace_x("renderer: draw_textstring(\"%s\")", text); + for (size_t n = 0; n < len; n++) { vector chars; chars.emplace_back(text[n]); @@ -348,7 +452,7 @@ void renderer::draw_textstring(const char* text, size_t len) { auto& font = m_fontmanager->match_char(chars[0]); if (!font) { - return; + return m_log.warn("No suitable font found (character=%i)", chars[0]); } if (font->ptr && font->ptr != m_gcfont) { @@ -386,51 +490,10 @@ void renderer::draw_textstring(const char* text, size_t len) { } } -int16_t renderer::shift_content(int16_t x, int16_t shift_x) { - int delta = shift_x; - - if (m_alignment == alignment::CENTER) { - int base_x = m_bar.size.w; - base_x -= m_bar.borders.at(edge::RIGHT).size; - base_x /= 2; - base_x += m_bar.borders.at(edge::LEFT).size; - m_connection.copy_area( - m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), base_x - x / 2, 0, base_x - (x + shift_x) / 2, 0, x, m_bar.size.h); - x = base_x - (x + shift_x) / 2 + x; - delta /= 2; - } else if (m_alignment == alignment::RIGHT) { - m_connection.copy_area(m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), m_bar.size.w - x, 0, m_bar.size.w - x - shift_x, - 0, x, m_bar.size.h); - x = m_bar.size.w - shift_x - m_bar.borders.at(edge::RIGHT).size; - if (m_reserve_at == edge::RIGHT) - x -= m_reserve; - } - - draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), x, 0, m_bar.size.w - x, m_bar.size.h); - - // Translate pos of clickable areas - if (m_alignment != alignment::LEFT) { - for (auto&& action : m_actions) { - if (action.active || action.align != m_alignment) - continue; - action.start_x -= delta; - action.end_x -= delta; - } - } - - m_currentx += shift_x; - - fill_underline(x, shift_x); - fill_overline(x, shift_x); - - return x; -} - -int16_t renderer::shift_content(int16_t shift_x) { - return shift_content(m_currentx, shift_x); -} - -void renderer::begin_action(const mousebtn btn, const string& cmd) { +/** + * Create new action block at the current position + */ +void renderer::begin_action(const mousebtn btn, const string cmd) { action_block action{}; action.button = btn; action.align = m_alignment; @@ -443,6 +506,9 @@ void renderer::begin_action(const mousebtn btn, const string& cmd) { m_actions.emplace_back(action); } +/** + * End action block at the current position + */ void renderer::end_action(const mousebtn btn) { for (auto action = m_actions.rbegin(); action != m_actions.rend(); action++) { if (!action->active || action->button != btn) @@ -474,12 +540,73 @@ void renderer::end_action(const mousebtn btn) { } } +/** + * Get all action blocks + */ const vector renderer::get_actions() { return m_actions; } +/** + * Shift contents by given pixel value + */ +int16_t renderer::shift_content(const int16_t x, const int16_t shift_x) { + m_log.trace_x("renderer: shift_content(%i)", shift_x); + + int delta = shift_x; + int x2{x}; + + if (m_alignment == alignment::CENTER) { + int base_x = m_bar.size.w; + base_x -= m_bar.borders.at(edge::RIGHT).size; + base_x /= 2; + base_x += m_bar.borders.at(edge::LEFT).size; + m_connection.copy_area( + m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), base_x - x / 2, 0, base_x - (x + shift_x) / 2, 0, x, m_bar.size.h); + x2 = base_x - (x + shift_x) / 2 + x; + delta /= 2; + } else if (m_alignment == alignment::RIGHT) { + m_connection.copy_area(m_pixmap, m_pixmap, m_gcontexts.at(gc::FG), m_bar.size.w - x, 0, m_bar.size.w - x - shift_x, + 0, x, m_bar.size.h); + x2 = m_bar.size.w - shift_x - m_bar.borders.at(edge::RIGHT).size; + if (m_reserve_at == edge::RIGHT) + x2 -= m_reserve; + } + + draw_util::fill(m_connection, m_pixmap, m_gcontexts.at(gc::BG), x2, 0, m_bar.size.w - x, m_bar.size.h); + + // Translate pos of clickable areas + if (m_alignment != alignment::LEFT) { + for (auto&& action : m_actions) { + if (action.active || action.align != m_alignment) + continue; + action.start_x -= delta; + action.end_x -= delta; + } + } + + m_currentx += shift_x; + + fill_underline(x2, shift_x); + fill_overline(x2, shift_x); + + return x2; +} + +/** + * Shift contents by given pixel value + */ +int16_t renderer::shift_content(const int16_t shift_x) { + return shift_content(m_currentx, shift_x); +} + +/** + * Draw debugging hints onto the output window + */ void renderer::debughints() { #if DEBUG and DRAW_CLICKABLE_AREA_HINTS + m_log.info("Drawing debug hints"); + map hint_num{{ {alignment::LEFT, 0}, {alignment::CENTER, 0}, {alignment::RIGHT, 0}, }}; @@ -489,8 +616,6 @@ void renderer::debughints() { continue; } - m_log.info("Drawing clickable area hints"); - hint_num[action.align]++; auto x = action.start_x; @@ -507,8 +632,6 @@ void renderer::debughints() { XCB_WINDOW_CLASS_INPUT_OUTPUT, m_screen->root_visual, mask, values); m_connection.map_window(action.hint); } - - m_connection.flush(); #endif } diff --git a/src/components/signals.cpp b/src/components/signals.cpp index ecbd6e17..b2b4bea4 100644 --- a/src/components/signals.cpp +++ b/src/components/signals.cpp @@ -6,20 +6,24 @@ POLYBAR_NS /** * Signals used to communicate with the bar window */ -callback g_signals::bar::action_click{nullptr}; -callback g_signals::bar::visibility_change{nullptr}; +callback g_signals::bar::action_click{nullptr}; +callback g_signals::bar::visibility_change{nullptr}; /** * Signals used to communicate with the input parser */ +callback g_signals::parser::background_change{nullptr}; +callback g_signals::parser::foreground_change{nullptr}; +callback g_signals::parser::underline_change{nullptr}; +callback g_signals::parser::overline_change{nullptr}; callback g_signals::parser::alignment_change{nullptr}; callback g_signals::parser::attribute_set{nullptr}; callback g_signals::parser::attribute_unset{nullptr}; -callback g_signals::parser::action_block_open{nullptr}; -callback g_signals::parser::action_block_close{nullptr}; -callback g_signals::parser::color_change{nullptr}; +callback g_signals::parser::attribute_toggle{nullptr}; callback g_signals::parser::font_change{nullptr}; callback g_signals::parser::pixel_offset{nullptr}; +callback g_signals::parser::action_block_open{nullptr}; +callback g_signals::parser::action_block_close{nullptr}; callback g_signals::parser::ascii_text_write{nullptr}; callback g_signals::parser::unicode_text_write{nullptr}; callback g_signals::parser::string_write{nullptr}; @@ -27,6 +31,6 @@ callback g_signals::parser::string_write{nullptr}; /** * Signals used to communicate with the tray manager */ -callback g_signals::tray::report_slotcount{nullptr}; +callback g_signals::tray::report_slotcount{nullptr}; POLYBAR_NS_END diff --git a/src/drawtypes/progressbar.cpp b/src/drawtypes/progressbar.cpp index cbd6d6f3..ea32e57a 100644 --- a/src/drawtypes/progressbar.cpp +++ b/src/drawtypes/progressbar.cpp @@ -1,5 +1,5 @@ -#include "x11/color.hpp" #include "components/types.hpp" +#include "x11/color.hpp" #include "drawtypes/progressbar.hpp" #include "utils/math.hpp" @@ -7,6 +7,9 @@ POLYBAR_NS namespace drawtypes { + progressbar::progressbar(const bar_settings bar, int width, string format) + : m_builder(make_unique(bar)), m_format(format), m_width(width) {} + void progressbar::set_fill(icon_t&& fill) { m_fill = forward(fill); } @@ -82,8 +85,7 @@ namespace drawtypes { * Create a progressbar by loading values * from the configuration */ - progressbar_t load_progressbar( - const bar_settings& bar, const config& conf, string section, string name) { + progressbar_t load_progressbar(const bar_settings& bar, const config& conf, string section, string name) { // Remove the start and end tag from the name in case a format tag is passed name = string_util::ltrim(string_util::rtrim(name, '>'), '<'); diff --git a/src/modules/bspwm.cpp b/src/modules/bspwm.cpp index d724dac4..88247d97 100644 --- a/src/modules/bspwm.cpp +++ b/src/modules/bspwm.cpp @@ -332,7 +332,7 @@ namespace modules { builder->cmd(mousebtn::LEFT, event); builder->node(ws.second); - builder->cmd_close(true); + builder->cmd_close(); } else { builder->node(ws.second); } @@ -340,8 +340,8 @@ namespace modules { } if (m_scroll) { - builder->cmd_close(true); - builder->cmd_close(true); + builder->cmd_close(); + builder->cmd_close(); } return workspace_n > 0; diff --git a/src/modules/i3.cpp b/src/modules/i3.cpp index 218d85cd..6c7f3243 100644 --- a/src/modules/i3.cpp +++ b/src/modules/i3.cpp @@ -155,15 +155,15 @@ namespace modules { if (m_click) { builder->cmd(mousebtn::LEFT, string{EVENT_CLICK} + to_string(ws.get()->index)); builder->node(ws.get()->label); - builder->cmd_close(true); + builder->cmd_close(); } else { builder->node(ws.get()->label); } } if (m_scroll) { - builder->cmd_close(true); - builder->cmd_close(true); + builder->cmd_close(); + builder->cmd_close(); } return true; diff --git a/src/modules/menu.cpp b/src/modules/menu.cpp index 4b997db8..aff0bc2a 100644 --- a/src/modules/menu.cpp +++ b/src/modules/menu.cpp @@ -55,11 +55,11 @@ namespace modules { if (tag == TAG_LABEL_TOGGLE && m_level == -1) { builder->cmd(mousebtn::LEFT, string(EVENT_MENU_OPEN) + "0"); builder->node(m_labelopen); - builder->cmd_close(true); + builder->cmd_close(); } else if (tag == TAG_LABEL_TOGGLE && m_level > -1) { builder->cmd(mousebtn::LEFT, EVENT_MENU_CLOSE); builder->node(m_labelclose); - builder->cmd_close(true); + builder->cmd_close(); } else if (tag == TAG_MENU && m_level > -1) { for (auto&& item : m_levels[m_level]->items) { if (item != m_levels[m_level]->items.front()) @@ -68,7 +68,7 @@ namespace modules { builder->node(m_labelseparator, true); builder->cmd(mousebtn::LEFT, item->exec); builder->node(item->label); - builder->cmd_close(true); + builder->cmd_close(); } } else { return false; diff --git a/src/modules/meta/inotify_module.cpp b/src/modules/meta/inotify_module.cpp deleted file mode 100644 index d64e0fba..00000000 --- a/src/modules/meta/inotify_module.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "modules/meta/inotify_module.hpp" - -#include "modules/backlight.hpp" -#include "modules/battery.hpp" - -POLYBAR_NS - -namespace modules { - // public {{{ - - template - void inotify_module::start() { - CAST_MOD(Impl)->m_mainthread = thread(&inotify_module::runner, this); - } - - // }}} - // protected {{{ - - template - void inotify_module::runner() { - try { - // Send initial broadcast to warmup cache - if (CONST_MOD(Impl).running()) { - CAST_MOD(Impl)->on_event(nullptr); - CAST_MOD(Impl)->broadcast(); - } - - while (CONST_MOD(Impl).running()) { - CAST_MOD(Impl)->poll_events(); - } - } catch (const module_error& err) { - CAST_MOD(Impl)->halt(err.what()); - } catch (const std::exception& err) { - CAST_MOD(Impl)->halt(err.what()); - } - } - - template - void inotify_module::watch(string path, int mask) { - this->m_log.trace("%s: Attach inotify at %s", CONST_MOD(Impl).name(), path); - m_watchlist.insert(make_pair(path, mask)); - } - - template - void inotify_module::idle() { - CAST_MOD(Impl)->sleep(200ms); - } - - template - void inotify_module::poll_events() { - vector watches; - - try { - for (auto&& w : m_watchlist) { - watches.emplace_back(inotify_util::make_watch(w.first)); - watches.back()->attach(w.second); - } - } catch (const system_error& e) { - watches.clear(); - this->m_log.err("%s: Error while creating inotify watch (what: %s)", CONST_MOD(Impl).name(), e.what()); - CAST_MOD(Impl)->sleep(0.1s); - return; - } - - while (CONST_MOD(Impl).running()) { - std::unique_lock guard(this->m_lock); - { - for (auto&& w : watches) { - this->m_log.trace_x("%s: Poll inotify watch %s", CONST_MOD(Impl).name(), w->path()); - - if (w->poll(1000 / watches.size())) { - auto event = w->get_event(); - - for (auto&& w : watches) { - try { - w->remove(); - } catch (const system_error&) { - } - } - - if (CAST_MOD(Impl)->on_event(event.get())) - CAST_MOD(Impl)->broadcast(); - - CAST_MOD(Impl)->idle(); - - return; - } - - if (!CONST_MOD(Impl).running()) - break; - } - } - guard.unlock(); - CAST_MOD(Impl)->idle(); - } - } - - // }}} - - template class inotify_module; - template class inotify_module; -} - -POLYBAR_NS_END diff --git a/src/modules/xbacklight.cpp b/src/modules/xbacklight.cpp index 90888f31..f86f07ad 100644 --- a/src/modules/xbacklight.cpp +++ b/src/modules/xbacklight.cpp @@ -142,9 +142,9 @@ namespace modules { m_builder->node(static_module::get_output()); if (m_percentage < 100) - m_builder->cmd_close(true); + m_builder->cmd_close(); if (m_percentage > 0) - m_builder->cmd_close(true); + m_builder->cmd_close(); } else { m_builder->node(static_module::get_output()); } diff --git a/src/x11/fonts.cpp b/src/x11/fonts.cpp index 045375ea..b3d73923 100644 --- a/src/x11/fonts.cpp +++ b/src/x11/fonts.cpp @@ -38,10 +38,10 @@ font_manager::~font_manager() { } bool font_manager::load(string name, int8_t fontindex, int8_t offset_y) { - if (fontindex != -1 && m_fonts.find(fontindex) != m_fonts.end()) { + if (fontindex != DEFAULT_FONT_INDEX && m_fonts.find(fontindex) != m_fonts.end()) { m_logger.warn("A font with index '%i' has already been loaded, skip...", fontindex); return false; - } else if (fontindex == -1) { + } else if (fontindex == DEFAULT_FONT_INDEX) { fontindex = m_fonts.size(); m_logger.trace("font_manager: Assign font '%s' to index '%d'", name.c_str(), fontindex); } else { @@ -80,7 +80,7 @@ bool font_manager::load(string name, int8_t fontindex, int8_t offset_y) { void font_manager::set_preferred_font(int8_t index) { if (index <= 0) { - m_fontindex = -1; + m_fontindex = DEFAULT_FONT_INDEX; return; } @@ -95,7 +95,7 @@ void font_manager::set_preferred_font(int8_t index) { font_t& font_manager::match_char(uint16_t chr) { static font_t notfound; if (!m_fonts.empty()) { - if (m_fontindex != -1 && size_t(m_fontindex) <= m_fonts.size()) { + if (m_fontindex != DEFAULT_FONT_INDEX && size_t(m_fontindex) <= m_fonts.size()) { auto iter = m_fonts.find(m_fontindex); if (iter != m_fonts.end() && has_glyph(iter->second, chr)) return iter->second; diff --git a/tests/unit_tests/utils/color.cpp b/tests/unit_tests/utils/color.cpp index d079f1a5..f644023a 100644 --- a/tests/unit_tests/utils/color.cpp +++ b/tests/unit_tests/utils/color.cpp @@ -30,4 +30,10 @@ int main() { uint32_t colorC{0x00ffffff}; expect(color_util::hex(colorC).compare("#00ffffff") == 0); }; + + "simplify"_test = [] { + expect(color_util::simplify_hex("#ff223344") == "#234"); + expect(color_util::simplify_hex("#ee223344") == "#ee223344"); + expect(color_util::simplify_hex("#ff234567") == "#234567"); + }; }