double red;
double green;
double blue;
+ double alpha;
/* The colorpixel we use for direct XCB calls. */
uint32_t colorpixel;
} color_t;
+#define COLOR_TRANSPARENT ((color_t){.red = 0.0, .green = 0.0, .blue = 0.0, .colorpixel = 0})
+
/* A wrapper grouping an XCB drawable and both a graphics context
* and the corresponding cairo objects representing it. */
typedef struct surface_t {
*
*/
uint16_t get_visual_depth(xcb_visualid_t visual_id);
+
+/**
+ * Get visual type specified by visualid
+ *
+ */
xcb_visualtype_t *get_visualtype_by_id(xcb_visualid_t visual_id);
/**
void draw_util_surface_init(xcb_connection_t *conn, surface_t *surface, xcb_drawable_t drawable,
xcb_visualtype_t *visual, int width, int height) {
surface->id = drawable;
- surface->visual_type = (visual == NULL) ? visual_type : visual;
+ surface->visual_type = ((visual == NULL) ? visual_type : visual);
surface->width = width;
surface->height = height;
*
*/
color_t draw_util_hex_to_color(const char *color) {
- char groups[3][3] = {
+ char alpha[2];
+ if (strlen(color) == strlen("#rrggbbaa")) {
+ alpha[0] = color[7];
+ alpha[1] = color[8];
+ } else {
+ alpha[0] = alpha[1] = 'F';
+ }
+
+ char groups[4][3] = {
{color[1], color[2], '\0'},
{color[3], color[4], '\0'},
- {color[5], color[6], '\0'}};
+ {color[5], color[6], '\0'},
+ {alpha[0], alpha[1], '\0'}};
return (color_t){
.red = strtol(groups[0], NULL, 16) / 255.0,
.green = strtol(groups[1], NULL, 16) / 255.0,
.blue = strtol(groups[2], NULL, 16) / 255.0,
+ .alpha = strtol(groups[3], NULL, 16) / 255.0,
.colorpixel = get_colorpixel(color)};
}
RETURN_UNLESS_SURFACE_INITIALIZED(surface);
#ifdef CAIRO_SUPPORT
- cairo_set_source_rgb(surface->cr, color.red, color.green, color.blue);
+ cairo_set_source_rgba(surface->cr, color.red, color.green, color.blue, color.alpha);
#else
uint32_t colorpixel = color.colorpixel;
xcb_change_gc(conn, surface->gc, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND,
new->depth = window->depth;
new->window->aspect_ratio = 0.0;
} else {
- new->depth = XCB_COPY_FROM_PARENT;
+ new->depth = root_depth;
}
DLOG("opening window\n");
* pixmaps. Will use 32 bit depth and an appropriate visual, if available,
* otherwise the root window’s default (usually 24 bit TrueColor). */
uint8_t root_depth;
-xcb_visualid_t visual_id;
xcb_visualtype_t *visual_type;
xcb_colormap_t colormap;
#include "atoms.xmacro"
#undef xmacro
- /* By default, we use the same depth and visual as the root window, which
- * usually is TrueColor (24 bit depth) and the corresponding visual.
- * However, we also check if a 32 bit depth and visual are available (for
- * transparency) and use it if so. */
root_depth = root_screen->root_depth;
- visual_id = root_screen->root_visual;
- visual_type = get_visualtype(root_screen);
colormap = root_screen->default_colormap;
+ visual_type = xcb_aux_find_visual_by_attrs(root_screen, -1, 32);
+ if (visual_type != NULL) {
+ root_depth = xcb_aux_get_depth_of_visual(root_screen, visual_type->visual_id);
+ colormap = xcb_generate_id(conn);
+
+ xcb_void_cookie_t cm_cookie = xcb_create_colormap_checked(conn,
+ XCB_COLORMAP_ALLOC_NONE,
+ colormap,
+ root,
+ visual_type->visual_id);
+
+ xcb_generic_error_t *error = xcb_request_check(conn, cm_cookie);
+ if (error != NULL) {
+ ELOG("Could not create colormap. Error code: %d\n", error->error_code);
+ exit(EXIT_FAILURE);
+ }
+ } else {
+ visual_type = get_visualtype(root_screen);
+ }
- DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_id);
+ DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_type->visual_id);
DLOG("root_screen->height_in_pixels = %d, root_screen->height_in_millimeters = %d, dpi = %d\n",
root_screen->height_in_pixels, root_screen->height_in_millimeters,
(int)((double)root_screen->height_in_pixels * 25.4 / (double)root_screen->height_in_millimeters));
uint32_t mask = 0;
uint32_t values[5];
- xcb_visualid_t visual = XCB_COPY_FROM_PARENT;
- xcb_colormap_t win_colormap = XCB_NONE;
- if (depth != root_depth && depth != XCB_COPY_FROM_PARENT) {
- /* For custom visuals, we need to create a colormap before creating
- * this window. It will be freed directly after creating the window. */
- visual = get_visualid_by_depth(depth);
- win_colormap = xcb_generate_id(conn);
- xcb_create_colormap_checked(conn, XCB_COLORMAP_ALLOC_NONE, win_colormap, root, visual);
-
- /* We explicitly set a background color and border color (even though we
- * don’t even have a border) because the X11 server requires us to when
- * using 32 bit color depths, see
- * http://stackoverflow.com/questions/3645632 */
- mask |= XCB_CW_BACK_PIXEL;
- values[0] = root_screen->black_pixel;
-
- mask |= XCB_CW_BORDER_PIXEL;
- values[1] = root_screen->black_pixel;
-
- /* our own frames should not be managed */
- mask |= XCB_CW_OVERRIDE_REDIRECT;
- values[2] = 1;
-
- /* see include/xcb.h for the FRAME_EVENT_MASK */
- mask |= XCB_CW_EVENT_MASK;
- values[3] = FRAME_EVENT_MASK & ~XCB_EVENT_MASK_ENTER_WINDOW;
-
- mask |= XCB_CW_COLORMAP;
- values[4] = win_colormap;
- } else {
- /* our own frames should not be managed */
- mask = XCB_CW_OVERRIDE_REDIRECT;
- values[0] = 1;
+ /* For custom visuals, we need to create a colormap before creating
+ * this window. It will be freed directly after creating the window. */
+ xcb_visualid_t visual = get_visualid_by_depth(depth);
+ xcb_colormap_t win_colormap = xcb_generate_id(conn);
+ xcb_create_colormap_checked(conn, XCB_COLORMAP_ALLOC_NONE, win_colormap, root, visual);
- /* see include/xcb.h for the FRAME_EVENT_MASK */
- mask |= XCB_CW_EVENT_MASK;
- values[1] = FRAME_EVENT_MASK & ~XCB_EVENT_MASK_ENTER_WINDOW;
+ /* We explicitly set a background color and border color (even though we
+ * don’t even have a border) because the X11 server requires us to when
+ * using 32 bit color depths, see
+ * http://stackoverflow.com/questions/3645632 */
+ mask |= XCB_CW_BACK_PIXEL;
+ values[0] = root_screen->black_pixel;
- mask |= XCB_CW_COLORMAP;
- values[2] = colormap;
- }
+ mask |= XCB_CW_BORDER_PIXEL;
+ values[1] = root_screen->black_pixel;
+
+ /* our own frames should not be managed */
+ mask |= XCB_CW_OVERRIDE_REDIRECT;
+ values[2] = 1;
+
+ /* see include/xcb.h for the FRAME_EVENT_MASK */
+ mask |= XCB_CW_EVENT_MASK;
+ values[3] = FRAME_EVENT_MASK & ~XCB_EVENT_MASK_ENTER_WINDOW;
+
+ mask |= XCB_CW_COLORMAP;
+ values[4] = win_colormap;
Rect dims = {-15, -15, 10, 10};
xcb_window_t frame_id = create_window(conn, dims, depth, visual, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCURSOR_CURSOR_POINTER, false, mask, values);
if (parent->frame_buffer.id == XCB_NONE)
goto copy_pixmaps;
+ /* For the first child, we clear the parent pixmap to ensure there's no
+ * garbage left on there. This is important to avoid tearing when using
+ * transparency. */
+ if (con == TAILQ_FIRST(&(con->parent->nodes_head))) {
+ draw_util_clear_surface(conn, &(con->parent->frame_buffer), COLOR_TRANSPARENT);
+ FREE(con->parent->deco_render_params);
+ }
+
/* 4: paint the bar */
draw_util_rectangle(conn, &(parent->frame_buffer), p->color->background,
con->deco_rect.x, con->deco_rect.y, con->deco_rect.width, con->deco_rect.height);
}
return 0;
}
+
+/*
+ * Get visual type specified by visualid
+ *
+ */
xcb_visualtype_t *get_visualtype_by_id(xcb_visualid_t visual_id) {
xcb_depth_iterator_t depth_iter;