From 0de060f8dd6a0da0a6ec4f0a6c223fc23fd3017a Mon Sep 17 00:00:00 2001 From: danielb Date: Fri, 1 Jan 2010 15:01:51 -0800 Subject: [PATCH] Add ARGB visual support. This patch adds the possibility to use a argb visual for the conky window. Adding a boolean configuration entry 'own_window_argb_visual'. the 'set_transparent_background' method sets the alpha bytes of the argb color for transparency, instead of pseudo transparency. This patch would close following feature request: https://sourceforge.net/tracker/?func=detail&aid=1563931&group_id=143975&at id=757311 and would be a workaround for some reported transparency bugs (https://sourceforge.net/tracker/?func=detail&aid=1968923&group_id=143975&a tid=757308 for example) Signed-off-by: Brenden Matthews --- AUTHORS | 3 ++ configure.ac.in | 12 ++++++ doc/config_settings.xml | 13 +++++- src/conky.c | 28 +++++++++++-- src/fonts.c | 2 +- src/x11.c | 100 +++++++++++++++++++++++++++++++++++++++++++---- src/x11.h | 7 ++++ 7 files changed, 152 insertions(+), 13 deletions(-) diff --git a/AUTHORS b/AUTHORS index 98917f9..8ff5463 100644 --- a/AUTHORS +++ b/AUTHORS @@ -346,3 +346,6 @@ zimba-tm zotrix FreeBSD patch for <10 procs + +Daniel Beßler + argb visual patch diff --git a/configure.ac.in b/configure.ac.in index b3c84db..93243d2 100644 --- a/configure.ac.in +++ b/configure.ac.in @@ -423,6 +423,17 @@ if test "x$want_x11" = "xyes"; then fi dnl +dnl ARGB +dnl + +AC_ARG_ENABLE([argb], + AC_HELP_STRING([--enable-argb], [enable if you want a argb visual [[default=no]]]), + [want_argb="$enableval"], [want_argb=no]) +if test x$want_argb = xyes; then + AC_DEFINE(USE_ARGB, 1, [Define if you want argb visual support]) +fi + +dnl dnl IMLIB2 dnl @@ -965,6 +976,7 @@ $PACKAGE $VERSION configured successfully: XDamage support: $want_xdamage XDBE support: $want_double_buffer Xft support: $want_xft + ARGB support $want_argb * Music detection: Audacious: $want_audacious diff --git a/doc/config_settings.xml b/doc/config_settings.xml index c9be564..70d67d6 100644 --- a/doc/config_settings.xml +++ b/doc/config_settings.xml @@ -675,10 +675,21 @@ + + + + Boolean, use ARGB visual? ARGB can be used for real transparency, + note that a composite manager is required for real transparency. + + + + + - Boolean, set pseudo-transparency? + Boolean, set transparency? If argb visual is configured + true transparency is used, else pseudo transparency is used. diff --git a/src/conky.c b/src/conky.c index bd592f3..e744897 100644 --- a/src/conky.c +++ b/src/conky.c @@ -203,6 +203,9 @@ static void print_version(void) # ifdef XFT " * Xft\n" # endif /* XFT */ +# ifdef USE_ARGB + " * ARGB visual\n" +# endif /* USE_ARGB */ #endif /* X11 */ "\n Music detection:\n" #ifdef AUDACIOUS @@ -2692,8 +2695,16 @@ static inline void set_foreground_color(long c) { #ifdef X11 if (output_methods & TO_X) { - current_color = c; - XSetForeground(display, window.gc, c); +#ifdef USE_ARGB + if (have_argb_visual) { + current_color = c | (0xff << 24); + } else { +#endif /* USE_ARGB */ + current_color = c; +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ + XSetForeground(display, window.gc, current_color); } #endif /* X11 */ #ifdef NCURSES @@ -2794,7 +2805,8 @@ static void draw_string(const char *s) XftColor c2; c.pixel = current_color; - XQueryColor(display, DefaultColormap(display, screen), &c); + // query color on custom colormap + XQueryColor(display, window.colourmap, &c); c2.pixel = c.pixel; c2.color.red = c.red; @@ -3655,7 +3667,7 @@ static void main_loop(void) #ifdef OWN_WINDOW case ReparentNotify: - /* set background to ParentRelative for all parents */ + /* make background transparent */ if (own_window) { set_transparent_background(window.window); } @@ -4234,6 +4246,9 @@ static void set_default_configurations(void) window.hints = 0; strcpy(window.class_name, PACKAGE_NAME); sprintf(window.title, PACKAGE_NAME" (%s)", info.uname_s.nodename); +#ifdef USE_ARGB + use_argb_visual = 0; +#endif #endif stippled_borders = 0; window.border_inner_margin = 3; @@ -5006,6 +5021,11 @@ char load_config_file(const char *f) CONF_ERR; } } +#ifdef USE_ARGB + CONF("own_window_argb_visual") { + use_argb_visual = string_to_bool(value); + } +#endif /* USE_ARGB */ #endif CONF("stippled_borders") { if (value) { diff --git a/src/fonts.c b/src/fonts.c index b110d10..4215b15 100644 --- a/src/fonts.c +++ b/src/fonts.c @@ -58,7 +58,7 @@ void setup_fonts(void) window.xftdraw = 0; } window.xftdraw = XftDrawCreate(display, window.drawable, - DefaultVisual(display, screen), DefaultColormap(display, screen)); + window.visual, window.colourmap); } #endif /* XFT */ set_font(); diff --git a/src/x11.c b/src/x11.c index 36cc4e8..c81c2b4 100644 --- a/src/x11.c +++ b/src/x11.c @@ -51,6 +51,11 @@ int use_xft = 0; int use_xdbe; #endif +#ifdef USE_ARGB +int use_argb_visual; +int have_argb_visual; +#endif /* USE_ARGB */ + /* some basic X11 stuff */ Display *display = NULL; int display_width; @@ -171,11 +176,26 @@ static Window find_desktop_window(Window *p_root, Window *p_desktop) return win; } -/* sets background to ParentRelative for the Window and all parents */ +/* if no argb visual is configured sets background to ParentRelative for the Window and all parents, + else real transparency is used */ void set_transparent_background(Window win) { static int colour_set = -1; +#ifdef USE_ARGB + if (have_argb_visual) { + // real transparency + if (set_transparent) { + XSetWindowBackground(display, win, 0x00); + } else if (colour_set != background_colour) { + XSetWindowBackground(display, win, + background_colour | (0xff << 24)); + colour_set = background_colour; + } + } else { +#endif /* USE_ARGB */ + // pseudo transparency + if (set_transparent) { Window parent = win; unsigned int i; @@ -193,7 +213,35 @@ void set_transparent_background(Window win) XSetWindowBackground(display, win, background_colour); colour_set = background_colour; } +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ +} + +#ifdef USE_ARGB +static int get_argb_visual(Visual** visual, int *depth) { + /* code from gtk project, gdk_screen_get_rgba_visual */ + XVisualInfo visual_template; + XVisualInfo *visual_list; + int nxvisuals = 0, i; + + visual_template.screen = screen; + visual_list = XGetVisualInfo (display, VisualScreenMask, + &visual_template, &nxvisuals); + for (i = 0; i < nxvisuals; i++) { + if (visual_list[i].depth == 32 && + (visual_list[i].red_mask == 0xff0000 && + visual_list[i].green_mask == 0x00ff00 && + visual_list[i].blue_mask == 0x0000ff)) { + *visual = visual_list[i].visual; + *depth = visual_list[i].depth; + return 1; + } + } + // no argb visual available + return 0; } +#endif /* USE_ARGB */ void destroy_window(void) { @@ -220,9 +268,28 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, #ifdef OWN_WINDOW if (own_window) { + int depth = 0, flags; + Visual *visual = NULL; + if (!find_desktop_window(&window.root, &window.desktop)) { return; } + +#ifdef USE_ARGB + if (use_argb_visual && get_argb_visual(&visual, &depth)) { + have_argb_visual = 1; + window.visual = visual; + window.colourmap = XCreateColormap(display, + DefaultRootWindow(display), window.visual, AllocNone); + } else { +#endif /* USE_ARGB */ + window.visual = DefaultVisual(display, screen); + window.colourmap = DefaultColormap(display, screen); + depth = CopyFromParent; + visual = CopyFromParent; +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ if (window.type == TYPE_OVERRIDE) { @@ -231,11 +298,21 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, XSetWindowAttributes attrs = { ParentRelative, 0L, 0, 0L, 0, 0, Always, 0L, 0L, False, StructureNotifyMask | ExposureMask, 0L, True, 0, 0 }; +#ifdef USE_ARGB + if (have_argb_visual) { + attrs.colormap = window.colourmap; + flags = CWBorderPixel | CWColormap | CWOverrideRedirect; + } else { +#endif /* USE_ARGB */ + flags = CWBackPixel | CWOverrideRedirect; +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ /* Parent is desktop window (which might be a child of root) */ window.window = XCreateWindow(display, window.desktop, window.x, - window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, - CWBackPixel | CWOverrideRedirect, &attrs); + window.y, w, h, 0, depth, InputOutput, visual, + flags, &attrs); XLowerWindow(display, window.window); @@ -252,14 +329,25 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, XClassHint classHint; XWMHints wmHint; Atom xa; + +#ifdef USE_ARGB + if (have_argb_visual) { + attrs.colormap = window.colourmap; + flags = CWBorderPixel | CWColormap | CWOverrideRedirect; + } else { +#endif /* USE_ARGB */ + flags = CWBackPixel | CWOverrideRedirect; +#ifdef USE_ARGB + } +#endif /* USE_ARGB */ if (window.type == TYPE_DOCK) { window.x = window.y = 0; } /* Parent is root window so WM can take control */ window.window = XCreateWindow(display, window.root, window.x, - window.y, w, h, 0, CopyFromParent, InputOutput, CopyFromParent, - CWBackPixel | CWOverrideRedirect, &attrs); + window.y, w, h, 0, depth, InputOutput, visual, + flags, &attrs); classHint.res_name = window.class_name; classHint.res_class = classHint.res_name; @@ -472,8 +560,6 @@ void init_window(int own_window, int w, int h, int set_trans, int back_colour, fprintf(stderr, PACKAGE_NAME": drawing to single buffer\n"); } #endif - window.visual = DefaultVisual(display, DefaultScreen(display)); - window.colourmap = DefaultColormap(display, DefaultScreen(display)); #ifdef IMLIB2 { cimlib_init(display, window.drawable, window.visual, window.colourmap); diff --git a/src/x11.h b/src/x11.h index a4b2a2a..0ceaabb 100644 --- a/src/x11.h +++ b/src/x11.h @@ -75,6 +75,13 @@ extern int use_xdbe; extern int use_xft; #endif +#if defined(USE_ARGB) && defined(OWN_WINDOW) +/* 1 if config var set to 1, otherwise 0 */ +extern int use_argb_visual; +/* 1 if use_argb_visual=1 and argb visual was found, otherwise 0 */ +extern int have_argb_visual; +#endif + extern Display *display; extern int display_width; extern int display_height; -- 1.7.9.5