1
0
Fork 0
mirror of https://github.com/polybar/polybar.git synced 2024-11-11 13:50:56 -05:00

fix(xft): Allocate xft color by value

- Solves the issue with transparency using Xft.
- X11 fonts are still affected by the alpha issue.

Closes jaagr/lemonbuddy#119
This commit is contained in:
Michael Carlberg 2016-10-30 02:18:39 +01:00
parent 41ba9beeee
commit efba06dc2d
8 changed files with 84 additions and 43 deletions

View file

@ -106,9 +106,9 @@ class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::propert
// }}} // }}}
// Set bar colors {{{ // Set bar colors {{{
m_bar.background = color::parse(m_conf.get<string>(bs, "background", m_bar.background.hex())); m_bar.background = color::parse(m_conf.get<string>(bs, "background", m_bar.background.hex_to_rgba()));
m_bar.foreground = color::parse(m_conf.get<string>(bs, "foreground", m_bar.foreground.hex())); m_bar.foreground = color::parse(m_conf.get<string>(bs, "foreground", m_bar.foreground.hex_to_rgba()));
m_bar.linecolor = color::parse(m_conf.get<string>(bs, "linecolor", m_bar.linecolor.hex())); m_bar.linecolor = color::parse(m_conf.get<string>(bs, "linecolor", m_bar.linecolor.hex_to_rgba()));
// }}} // }}}
// Set border values {{{ // Set border values {{{
@ -779,14 +779,14 @@ class bar : public xpp::event::sink<evt::button_press, evt::expose, evt::propert
*/ */
void on_color_change(gc gc_, color color_) { //{{{ void on_color_change(gc gc_, color color_) { //{{{
m_log.trace_x( m_log.trace_x(
"bar: color_change(%i, %s -> %s)", static_cast<int>(gc_), color_.hex(), color_.rgb()); "bar: color_change(%i, %s -> %s)", static_cast<int>(gc_), color_.hex_to_rgba(), color_.hex_to_rgb());
const uint32_t value_list[32]{color_.value()};
m_connection.change_gc(m_gcontexts.at(gc_), XCB_GC_FOREGROUND, value_list);
if (gc_ == gc::FG) { if (gc_ == gc::FG) {
m_fontmanager->allocate_color(color_); m_fontmanager->allocate_color(color_);
m_xfont_color = color::parse(color_.rgb()).value(); m_xfont_color = color_.value();
} else {
const uint32_t value_list[32]{color_.value()};
m_connection.change_gc(m_gcontexts.at(gc_), XCB_GC_FOREGROUND, value_list);
} }
} //}}} } //}}}

View file

@ -264,7 +264,7 @@ class builder {
void background(string color) { void background(string color) {
if (color.length() == 2 || (color.find("#") == 0 && color.length() == 3)) { if (color.length() == 2 || (color.find("#") == 0 && color.length() == 3)) {
color = "#" + color.substr(color.length() - 2); color = "#" + color.substr(color.length() - 2);
auto bg = m_bar.background.hex(); auto bg = m_bar.background.hex_to_rgba();
color += bg.substr(bg.length() - (bg.length() < 6 ? 3 : 6)); color += bg.substr(bg.length() - (bg.length() < 6 ? 3 : 6));
} else if (color.length() >= 7 && color == "#" + string(color.length() - 1, color[1])) { } else if (color.length() >= 7 && color == "#" + string(color.length() - 1, color[1])) {
color = color.substr(0, 4); color = color.substr(0, 4);
@ -295,7 +295,7 @@ class builder {
auto color(color_); auto color(color_);
if (color.length() == 2 || (color.find("#") == 0 && color.length() == 3)) { if (color.length() == 2 || (color.find("#") == 0 && color.length() == 3)) {
color = "#" + color.substr(color.length() - 2); color = "#" + color.substr(color.length() - 2);
auto bg = m_bar.foreground.hex(); auto bg = m_bar.foreground.hex_to_rgba();
color += bg.substr(bg.length() - (bg.length() < 6 ? 3 : 6)); color += bg.substr(bg.length() - (bg.length() < 6 ? 3 : 6));
} else if (color.length() >= 7 && color == "#" + string(color.length() - 1, color[1])) { } else if (color.length() >= 7 && color == "#" + string(color.length() - 1, color[1])) {
color = color.substr(0, 4); color = color.substr(0, 4);
@ -315,7 +315,7 @@ class builder {
void color_alpha(string alpha_) { void color_alpha(string alpha_) {
auto alpha(alpha_); auto alpha(alpha_);
string val = m_bar.foreground.hex(); string val = m_bar.foreground.hex_to_rgba();
if (alpha.find("#") == std::string::npos) { if (alpha.find("#") == std::string::npos) {
alpha = "#" + alpha; alpha = "#" + alpha;
} }

View file

@ -22,7 +22,9 @@ static map<string, class color> g_colorstore;
class color { class color {
public: public:
explicit color(string hex) : m_hex(string_util::upper(hex)) { explicit color(string hex) : m_hex(string_util::upper(hex)) {
m_rgba.v = static_cast<uint32_t>(strtoul(&hex[1], nullptr, 16)); m_rgba.v = (strtoul(&hex[1], nullptr, 16));
m_rgb = (m_rgba.v << 8) >> 8;
// premultiply alpha // premultiply alpha
m_rgba._.r = m_rgba._.r * m_rgba._.a / 255; m_rgba._.r = m_rgba._.r * m_rgba._.a / 255;
m_rgba._.g = m_rgba._.g * m_rgba._.a / 255; m_rgba._.g = m_rgba._.g * m_rgba._.a / 255;
@ -33,14 +35,34 @@ class color {
char buffer[7]; char buffer[7];
snprintf(buffer, sizeof(buffer), "%06x", v); snprintf(buffer, sizeof(buffer), "%06x", v);
m_hex = "#" + string{buffer}; m_hex = "#" + string{buffer};
m_rgba.v = v; m_rgba.v = (strtoul(&m_hex[1], nullptr, 16));
} }
uint32_t value() const { uint32_t value() const {
return m_rgba.v; return m_rgba.v;
} }
string rgb() const { uint32_t rgb() const {
return m_rgb;
}
uint32_t alpha() const {
return 0xFF & (value() >> 24);
}
uint32_t red() const {
return 0xFF & (rgb() >> 16);
}
uint32_t green() const {
return 0xFF & (rgb() >> 8);
}
uint32_t blue() const {
return 0xFF & rgb();
}
string hex_to_rgb() const {
// clang-format off // clang-format off
return string_util::from_stream(stringstream() return string_util::from_stream(stringstream()
<< "#" << "#"
@ -52,7 +74,7 @@ class color {
// clang-format on // clang-format on
} }
string hex() const { string hex_to_rgba() const {
return m_hex; return m_hex;
} }
@ -82,6 +104,7 @@ class color {
protected: protected:
rgba m_rgba; rgba m_rgba;
unsigned long m_rgb;
string m_hex; string m_hex;
}; };

View file

@ -51,8 +51,8 @@ class fontmanager {
explicit fontmanager(connection& conn, const logger& logger) explicit fontmanager(connection& conn, const logger& logger)
: m_connection(conn), m_logger(logger) { : m_connection(conn), m_logger(logger) {
m_display = xlib::get_display(); m_display = xlib::get_display();
m_visual = xlib::get_visual(); m_visual = xlib::get_visual(conn.default_screen());
m_colormap = XDefaultColormap(m_display, 0); m_colormap = xlib::create_colormap(conn.default_screen());
} }
~fontmanager() { ~fontmanager() {
@ -170,8 +170,15 @@ class fontmanager {
if (!initial_alloc) if (!initial_alloc)
XftColorFree(m_display, m_visual, m_colormap, &m_xftcolor); XftColorFree(m_display, m_visual, m_colormap, &m_xftcolor);
if (!XftColorAllocName(m_display, m_visual, m_colormap, xcolor.rgb().c_str(), &m_xftcolor)) XRenderColor color;
m_logger.err("Failed to allocate color '%s'", xcolor.hex());
color.red = (xcolor.red()) << 8;
color.green = (xcolor.green()) << 8;
color.blue = (xcolor.blue()) << 8;
color.alpha = xcolor.alpha() << 8;
if (!XftColorAllocValue(m_display, m_visual, m_colormap, &color, &m_xftcolor))
m_logger.err("Failed to allocate color '%s'", xcolor.hex_to_rgba());
} // }}} } // }}}
void set_gcontext_font(gcontext& gc, xcb_font_t font) { // {{{ void set_gcontext_font(gcontext& gc, xcb_font_t font) { // {{{

View file

@ -8,7 +8,7 @@ LEMONBUDDY_NS
namespace xlib { namespace xlib {
static Display* g_display = nullptr; static Display* g_display = nullptr;
static Visual* g_visual = nullptr; static XVisualInfo g_visual_info;
/** /**
* Get pointer of Xlib Display * Get pointer of Xlib Display
@ -22,22 +22,16 @@ namespace xlib {
/** /**
* Get pointer of Xlib visual * Get pointer of Xlib visual
*/ */
inline Visual* get_visual() { inline Visual* get_visual(int screen = 0) {
if (g_visual == nullptr) { if (g_visual_info.visual == nullptr) {
XVisualInfo xv; XMatchVisualInfo(get_display(), screen, 32, TrueColor, &g_visual_info);
xv.depth = 32;
int result = 0;
auto result_ptr = XGetVisualInfo(get_display(), VisualDepthMask, &xv, &result);
if (result > 0)
g_visual = result_ptr->visual;
else
g_visual = XDefaultVisual(get_display(), 0);
free(result_ptr);
} }
return g_visual; return g_visual_info.visual;
}
inline Colormap create_colormap(int screen = 0) {
return XCreateColormap(get_display(), XRootWindow(get_display(), screen), get_visual(), screen);
} }
/** /**

View file

@ -144,9 +144,9 @@ namespace drawtypes {
// avoid color bleed // avoid color bleed
if (icon_empty && icon_indicator) { if (icon_empty && icon_indicator) {
if (!icon_indicator->m_background.empty() && icon_empty->m_background.empty()) if (!icon_indicator->m_background.empty() && icon_empty->m_background.empty())
icon_empty->m_background = bar.background.hex(); icon_empty->m_background = bar.background.hex_to_rgba();
if (!icon_indicator->m_foreground.empty() && icon_empty->m_foreground.empty()) if (!icon_indicator->m_foreground.empty() && icon_empty->m_foreground.empty())
icon_empty->m_foreground = bar.foreground.hex(); icon_empty->m_foreground = bar.foreground.hex_to_rgba();
} }
progressbar->set_empty(move(icon_empty)); progressbar->set_empty(move(icon_empty));

View file

@ -18,3 +18,6 @@ unit_test("utils/string")
unit_test("components/command_line") unit_test("components/command_line")
unit_test("components/di") unit_test("components/di")
#unit_test("components/logger") #unit_test("components/logger")
unit_test("components/x11/color")
#unit_test("components/x11/connection")
#unit_test("components/x11/window")

View file

@ -7,8 +7,22 @@ int main() {
"color"_test = [] { "color"_test = [] {
color test{"#33990022"}; color test{"#33990022"};
expect(test.hex() == "#33990022"); expect(test.hex_to_rgba() == "#33990022");
expect(test.rgb() == "#1E0006"); expect(test.hex_to_rgb() == "#1E0006");
};
"channels"_test = [] {
color test{"#eefb9281"};
expect(test.alpha() == 0xee);
expect(test.red() == 0xfb);
expect(test.green() == 0x92);
expect(test.blue() == 0x81);
};
"base"_test = [] {
color test{"#eefb9281"};
auto hex = test.hex_to_rgb();
expect(std::strtoul(&hex[0], 0, 16) == 0x000000);
}; };
"cache"_test = [] { "cache"_test = [] {
@ -23,13 +37,13 @@ int main() {
}; };
"predefined"_test = [] { "predefined"_test = [] {
expect(g_colorblack.hex() == "#FF000000"); expect(g_colorblack.hex_to_rgba() == "#FF000000");
expect(g_colorwhite.hex() == "#FFFFFFFF"); expect(g_colorwhite.hex_to_rgba() == "#FFFFFFFF");
}; };
"parse"_test = [] { "parse"_test = [] {
expect(color::parse("#ff9900", g_colorblack).hex() == "#FFFF9900"); expect(color::parse("#ff9900", g_colorblack).hex_to_rgba() == "#FFFF9900");
expect(color::parse("invalid", g_colorwhite).hex() == "#FFFFFFFF"); expect(color::parse("invalid", g_colorwhite).hex_to_rgba() == "#FFFFFFFF");
expect(color::parse("33990022", g_colorwhite).rgb() == "#1E0006"); expect(color::parse("33990022", g_colorwhite).hex_to_rgb() == "#1E0006");
}; };
} }