refactor: Cleanup handling of syntax tags
This commit is contained in:
parent
199a825494
commit
84d58e7619
@ -5,7 +5,6 @@
|
||||
#endif
|
||||
|
||||
#include <boost/di.hpp>
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
|
@ -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<syntaxtag, int> 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<syntaxtag, int> 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<syntaxtag, string> 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<uint8_t>(attribute::NONE)};
|
||||
uint8_t m_fontindex{1};
|
||||
|
||||
string m_background;
|
||||
string m_foreground;
|
||||
};
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -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<int> m_actions;
|
||||
};
|
||||
|
@ -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> font_manager,
|
||||
const bar_settings& bar, const vector<string>& 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<edge, border_settings>& 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<action_block> 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<action_block> 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<gc, uint32_t> 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;
|
||||
|
@ -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<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 mousebtn, string> action_block_open;
|
||||
extern callback<const mousebtn> action_block_close;
|
||||
extern callback<const gc, const uint32_t> color_change;
|
||||
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;
|
||||
@ -41,7 +44,6 @@ namespace g_signals {
|
||||
|
||||
namespace tray {
|
||||
extern callback<const uint16_t> report_slotcount;
|
||||
extern callback<const uint32_t> clear_bg;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<edge, border_settings> 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;
|
||||
|
@ -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<std::string>& args) {
|
||||
for (auto&& arg : args) {
|
||||
|
@ -12,11 +12,7 @@ POLYBAR_NS
|
||||
namespace drawtypes {
|
||||
class progressbar : public non_copyable_mixin<progressbar> {
|
||||
public:
|
||||
explicit progressbar(
|
||||
const bar_settings& bar, int width, string format, bool lazy_builder_closing = true)
|
||||
: m_builder(make_unique<builder>(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>;
|
||||
|
||||
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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<uint8_t, font_t> m_fonts;
|
||||
int8_t m_fontindex{-1};
|
||||
int8_t m_fontindex{DEFAULT_FONT_INDEX};
|
||||
|
||||
XftColor m_xftcolor{};
|
||||
XftDraw* m_xftdraw{nullptr};
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <cassert>
|
||||
#include <thread>
|
||||
|
||||
#include "adapters/mpd.hpp"
|
||||
|
@ -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<std::mutex> 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 {
|
||||
|
@ -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<uint8_t>(attribute::UNDERLINE)) & 1U)
|
||||
underline_close();
|
||||
if ((m_attributes >> static_cast<uint8_t>(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<float>(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<float>(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<uint16_t>(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<uint16_t>(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<uint16_t>(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<int>(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<uint16_t>(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<uint16_t>(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<uint8_t>(attr)) & 1U)
|
||||
return;
|
||||
|
||||
m_attributes |= 1U << static_cast<uint8_t>(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<uint8_t>(attr)) & 1U))
|
||||
return;
|
||||
|
||||
m_attributes &= ~(1U << static_cast<uint8_t>(attr));
|
||||
|
||||
switch (attr) {
|
||||
case attribute::NONE:
|
||||
break;
|
||||
case attribute::UNDERLINE:
|
||||
append("%{-u}");
|
||||
break;
|
||||
case attribute::OVERLINE:
|
||||
append("%{-o}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,6 @@
|
||||
#include <cassert>
|
||||
|
||||
#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<int>(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;
|
||||
|
@ -22,6 +22,9 @@ di::injector<unique_ptr<renderer>> configure_renderer(const bar_settings& bar, c
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct renderer instance
|
||||
*/
|
||||
renderer::renderer(connection& conn, const logger& logger, unique_ptr<font_manager> font_manager,
|
||||
const bar_settings& bar, const vector<string>& fonts)
|
||||
: m_connection(conn), m_log(logger), m_fontmanager(forward<decltype(font_manager)>(font_manager)), m_bar(bar) {
|
||||
@ -35,20 +38,19 @@ renderer::renderer(connection& conn, const logger& logger, unique_ptr<font_manag
|
||||
m_connection.create_colormap(XCB_COLORMAP_ALLOC_NONE, m_colormap, screen->root, 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<font_manag
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
for (int i = 1; i <= 8; i++) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
uint32_t mask{0};
|
||||
uint32_t value_list[32]{0};
|
||||
|
||||
xcb_params_gc_t params;
|
||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, foreground, colors[i - 1]);
|
||||
|
||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, foreground, colors[i]);
|
||||
XCB_AUX_ADD_PARAM(&mask, ¶ms, graphics_exposures, 0);
|
||||
|
||||
xutils::pack_values(mask, ¶ms, value_list);
|
||||
m_gcontexts.emplace(gc(i), m_connection.generate_id());
|
||||
|
||||
m_colors.emplace(gc(i), colors[i]);
|
||||
m_log.trace("renderer: Create gcontext (gc=%i, xid=%s)", i, m_connection.id(m_gcontexts.at(gc(i))));
|
||||
m_connection.create_gc(m_gcontexts.at(gc(i)), m_pixmap, mask, value_list);
|
||||
}
|
||||
@ -100,7 +102,7 @@ renderer::renderer(connection& conn, const logger& logger, unique_ptr<font_manag
|
||||
|
||||
for (auto f : fonts) {
|
||||
fontindex++;
|
||||
vector<string> fd = string_util::split(f, ';');
|
||||
vector<string> fd{string_util::split(f, ';')};
|
||||
string pattern{fd[0]};
|
||||
int offset{0};
|
||||
|
||||
@ -123,27 +125,41 @@ renderer::renderer(connection& conn, const logger& logger, unique_ptr<font_manag
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get output window
|
||||
*/
|
||||
xcb_window_t renderer::window() const {
|
||||
return m_window;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin render routine
|
||||
*/
|
||||
void renderer::begin() {
|
||||
m_log.trace_x("renderer: begin");
|
||||
|
||||
#if DEBUG and DRAW_CLICKABLE_AREA_HINTS
|
||||
for (auto&& action : m_actions) {
|
||||
m_connection.destroy_window(action.hint);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_currentx = m_bar.borders.at(edge::LEFT).size;
|
||||
m_currentx = m_bar.inner_area(true).x;
|
||||
m_attributes = 0;
|
||||
m_actions.clear();
|
||||
|
||||
fill_border(m_bar.borders, edge::ALL);
|
||||
fill_background();
|
||||
|
||||
m_fontmanager->create_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<uint8_t>(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<uint8_t>(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<int8_t>(font));
|
||||
}
|
||||
m_log.trace_x("renderer: set_fontindex(%i)", static_cast<int8_t>(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<uint8_t>(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<uint8_t>(attr), state);
|
||||
|
||||
if (state) {
|
||||
m_attributes |= static_cast<uint8_t>(attr);
|
||||
m_attributes |= 1U << static_cast<uint8_t>(attr);
|
||||
} else {
|
||||
m_attributes ^= static_cast<uint8_t>(attr);
|
||||
m_attributes &= ~(1U << static_cast<uint8_t>(attr));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle attribute
|
||||
*/
|
||||
void renderer::toggle_attribute(const attribute attr) {
|
||||
m_log.trace_x("renderer: toggle_attribute(%i)", static_cast<uint8_t>(attr));
|
||||
m_attributes ^= 1U << static_cast<uint8_t>(attr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given attribute is set
|
||||
*/
|
||||
bool renderer::check_attribute(const attribute attr) {
|
||||
return (m_attributes >> static_cast<uint8_t>(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<edge, border_settings>& borders, edge border) {
|
||||
m_log.trace_x("renderer: fill_border(%i)", static_cast<uint8_t>(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<edge, border_settings>& 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<int>(attribute::o)))
|
||||
return;
|
||||
int16_t y{static_cast<int16_t>(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<int>(attribute::u)))
|
||||
return;
|
||||
int16_t y{static_cast<int16_t>(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<int16_t>(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<uint16_t> 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<action_block> 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<alignment, int> 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
|
||||
}
|
||||
|
||||
|
@ -6,20 +6,24 @@ POLYBAR_NS
|
||||
/**
|
||||
* Signals used to communicate with the bar window
|
||||
*/
|
||||
callback<string> g_signals::bar::action_click{nullptr};
|
||||
callback<bool> g_signals::bar::visibility_change{nullptr};
|
||||
callback<const string> g_signals::bar::action_click{nullptr};
|
||||
callback<const bool> g_signals::bar::visibility_change{nullptr};
|
||||
|
||||
/**
|
||||
* Signals used to communicate with the input parser
|
||||
*/
|
||||
callback<const uint32_t> g_signals::parser::background_change{nullptr};
|
||||
callback<const uint32_t> g_signals::parser::foreground_change{nullptr};
|
||||
callback<const uint32_t> g_signals::parser::underline_change{nullptr};
|
||||
callback<const uint32_t> g_signals::parser::overline_change{nullptr};
|
||||
callback<const alignment> g_signals::parser::alignment_change{nullptr};
|
||||
callback<const attribute> g_signals::parser::attribute_set{nullptr};
|
||||
callback<const attribute> g_signals::parser::attribute_unset{nullptr};
|
||||
callback<const mousebtn, string> g_signals::parser::action_block_open{nullptr};
|
||||
callback<const mousebtn> g_signals::parser::action_block_close{nullptr};
|
||||
callback<const gc, const uint32_t> g_signals::parser::color_change{nullptr};
|
||||
callback<const attribute> g_signals::parser::attribute_toggle{nullptr};
|
||||
callback<const int8_t> g_signals::parser::font_change{nullptr};
|
||||
callback<const int16_t> g_signals::parser::pixel_offset{nullptr};
|
||||
callback<const mousebtn, const string> g_signals::parser::action_block_open{nullptr};
|
||||
callback<const mousebtn> g_signals::parser::action_block_close{nullptr};
|
||||
callback<const uint16_t> g_signals::parser::ascii_text_write{nullptr};
|
||||
callback<const uint16_t> g_signals::parser::unicode_text_write{nullptr};
|
||||
callback<const char*, const size_t> g_signals::parser::string_write{nullptr};
|
||||
@ -27,6 +31,6 @@ callback<const char*, const size_t> g_signals::parser::string_write{nullptr};
|
||||
/**
|
||||
* Signals used to communicate with the tray manager
|
||||
*/
|
||||
callback<uint16_t> g_signals::tray::report_slotcount{nullptr};
|
||||
callback<const uint16_t> g_signals::tray::report_slotcount{nullptr};
|
||||
|
||||
POLYBAR_NS_END
|
||||
|
@ -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<builder>(bar)), m_format(format), m_width(width) {}
|
||||
|
||||
void progressbar::set_fill(icon_t&& fill) {
|
||||
m_fill = forward<decltype(fill)>(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, '>'), '<');
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,104 +0,0 @@
|
||||
#include "modules/meta/inotify_module.hpp"
|
||||
|
||||
#include "modules/backlight.hpp"
|
||||
#include "modules/battery.hpp"
|
||||
|
||||
POLYBAR_NS
|
||||
|
||||
namespace modules {
|
||||
// public {{{
|
||||
|
||||
template <class Impl>
|
||||
void inotify_module<Impl>::start() {
|
||||
CAST_MOD(Impl)->m_mainthread = thread(&inotify_module::runner, this);
|
||||
}
|
||||
|
||||
// }}}
|
||||
// protected {{{
|
||||
|
||||
template <class Impl>
|
||||
void inotify_module<Impl>::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 <class Impl>
|
||||
void inotify_module<Impl>::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 <class Impl>
|
||||
void inotify_module<Impl>::idle() {
|
||||
CAST_MOD(Impl)->sleep(200ms);
|
||||
}
|
||||
|
||||
template <class Impl>
|
||||
void inotify_module<Impl>::poll_events() {
|
||||
vector<inotify_util::watch_t> 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<concurrency_util::spin_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<backlight_module>;
|
||||
template class inotify_module<battery_module>;
|
||||
}
|
||||
|
||||
POLYBAR_NS_END
|
@ -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());
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -30,4 +30,10 @@ int main() {
|
||||
uint32_t colorC{0x00ffffff};
|
||||
expect(color_util::hex<uint16_t>(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");
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user