From 4a7bec5ba6eb51301583aa4a29c48a56aa37b8a0 Mon Sep 17 00:00:00 2001 From: bi4k8 Date: Fri, 24 Feb 2023 13:13:48 +0000 Subject: [PATCH] Premultiply background colors for X11 (#1421) * initialize XColor/XftColor this does not change behavior, but avoids passing uninitialized data to X/Xft functions * gui, x11: move have_argb_visual to x11 files this variable only has meaning with respect to X11 * x11: clear have_argb_visual if the setting changes to false otherwise, we may try to use colors with alpha when we no longer requested a 32-bit visual * x11: premultiply alpha of background colors * x11: clean up set_foreground_color a bit --------- Co-authored-by: bi4k8 --- src/colours.h | 22 +++++++++++++++------- src/display-x11.cc | 10 +++------- src/gui.cc | 4 ---- src/gui.h | 7 +------ src/x11.cc | 7 ++++++- src/x11.h | 6 +++++- 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/colours.h b/src/colours.h index 335f8f9f..803773a4 100644 --- a/src/colours.h +++ b/src/colours.h @@ -61,28 +61,36 @@ public: static Colour from_argb32(uint32_t argb); #ifdef BUILD_X11 - unsigned long to_x11_color(Display *display, int screen) { - if(display == nullptr) { + unsigned long to_x11_color(Display *display, int screen, + bool premultiply = false) { + if (display == nullptr) { /* cannot work if display is not open */ return 0; } - XColor xcolor; - xcolor.pixel = 0; + XColor xcolor{}; xcolor.red = red * 257; xcolor.green = green * 257; xcolor.blue = blue * 257; if (XAllocColor(display, DefaultColormap(display, screen), &xcolor) == 0) { - //NORM_ERR("can't allocate X color"); + // NORM_ERR("can't allocate X color"); return 0; } - return static_cast(xcolor.pixel); + unsigned long pixel = static_cast(xcolor.pixel) & 0xffffff; +#ifdef BUILD_ARGB + if (have_argb_visual) { + if (premultiply) + pixel = (red * alpha / 255) << 16 | (green * alpha / 255) << 8 | + (blue * alpha / 255); + pixel |= ((unsigned long)alpha << 24); + } +#endif /* BUILD_ARGB */ + return pixel; } #endif /* BUILD_X11 */ }; - extern Colour error_colour; Colour parse_color(const std::string &colour); diff --git a/src/display-x11.cc b/src/display-x11.cc index f2e0e63e..69d5efe8 100644 --- a/src/display-x11.cc +++ b/src/display-x11.cc @@ -606,14 +606,10 @@ void display_output_x11::cleanup() { } void display_output_x11::set_foreground_color(Colour c) { + current_color = c; #ifdef BUILD_ARGB if (have_argb_visual) { - current_color = c; current_color.alpha = own_window_argb_value.get(*state); - } else { -#endif /* BUILD_ARGB */ - current_color = c; -#ifdef BUILD_ARGB } #endif /* BUILD_ARGB */ XSetForeground(display, window.gc, current_color.to_x11_color(display, screen)); @@ -642,8 +638,8 @@ int display_output_x11::calc_text_width(const char *s) { void display_output_x11::draw_string_at(int x, int y, const char *s, int w) { #ifdef BUILD_XFT if (use_xft.get(*state)) { - XColor c; - XftColor c2; + XColor c{}; + XftColor c2{}; c.pixel = current_color.to_x11_color(display, screen); // query color on custom colormap diff --git a/src/gui.cc b/src/gui.cc index 630bc691..0b46d16e 100644 --- a/src/gui.cc +++ b/src/gui.cc @@ -41,10 +41,6 @@ #include #endif -#ifdef BUILD_ARGB -bool have_argb_visual; -#endif /* BUILD_ARGB */ - /* basic display attributes */ int display_width; int display_height; diff --git a/src/gui.h b/src/gui.h index 5d2d56d6..91c2b47b 100644 --- a/src/gui.h +++ b/src/gui.h @@ -29,14 +29,9 @@ #include "x11.h" #endif /* BUILD_X11 */ +#include "colour-settings.h" #include "colours.h" #include "setting.hh" -#include "colour-settings.h" - -#if defined(BUILD_ARGB) && defined(OWN_WINDOW) -/* true if use_argb_visual=true and argb visual was found*/ -extern bool have_argb_visual; -#endif #ifdef BUILD_X11 extern Display *display; diff --git a/src/x11.cc b/src/x11.cc index 39fe412e..f599eec7 100644 --- a/src/x11.cc +++ b/src/x11.cc @@ -68,6 +68,10 @@ Display *display = nullptr; /* Window stuff */ struct conky_x11_window window; +#ifdef BUILD_ARGB +bool have_argb_visual; +#endif /* BUILD_ARGB */ + conky::simple_config_setting display_name("display", std::string(), false); @@ -405,7 +409,7 @@ namespace { void do_set_background(Window win, uint8_t alpha) { Colour colour = background_colour.get(*state); colour.alpha = alpha; - unsigned long xcolor = colour.to_x11_color(display, screen); + unsigned long xcolor = colour.to_x11_color(display, screen, true); XSetWindowBackground(display, win, xcolor); } } // namespace @@ -511,6 +515,7 @@ void x11_init_window(lua::state &l __attribute__((unused)), bool own) { depth = CopyFromParent; visual = CopyFromParent; #ifdef BUILD_ARGB + have_argb_visual = false; } #endif /* BUILD_ARGB */ diff --git a/src/x11.h b/src/x11.h index 64e047de..eeef2be1 100644 --- a/src/x11.h +++ b/src/x11.h @@ -37,9 +37,13 @@ #include #endif -#include "colours.h" #include "setting.hh" +#ifdef BUILD_ARGB +/* true if use_argb_visual=true and argb visual was found*/ +extern bool have_argb_visual; +#endif /* BUILD_ARGB */ + #define ATOM(a) XInternAtom(display, #a, False) #ifdef OWN_WINDOW