I am developing a simple X11 application with cairo and xcb. I was wondering if there is any way to to put fully opaque elements (for example icons) in a window with a transparent background.
For the transparency I am using _NET_WM_WINDOW_OPACITY. I am also using the shape extension for a custom shape.
Note that I don't want a fully transparent window, but a certain opacity in the background with opaque icons/text.
This is where I create the window
const uint32_t value_mask = XCB_CW_BACK_PIXMAP | XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL
| XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP;
const uint32_t event_mask = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY
| XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_FOCUS_CHANGE
| XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS;
xcb_colormap_t colormap = xcb_generate_id(win->con->connection);
xcb_create_colormap(win->con->connection, XCB_COLORMAP_ALLOC_NONE, colormap, win->con->screen->root, win->con->visual_type->visual_id);
const uint32_t value_list[] = {
XCB_NONE, // back pixmap
0x00000000, // back pixel
0x00000000, // border pixel
true, // override redirect
event_mask, // event mask
colormap // colormap
};
win->window = xcb_generate_id(win->con->connection);
xcb_create_window(win->con->connection,
XCB_COPY_FROM_PARENT,
win->window, win->con->screen->root,
win->x, win->y,
win->width, win->height,
0, // border
XCB_WINDOW_CLASS_INPUT_OUTPUT,
win->con->screen->root_visual,
value_mask,
value_list);
This is where I create a buffer with cairo
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
cairo_t *cr = cairo_create(surface);
cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
double alpha = 0.8;
cairo_set_source_rgba(cr, 0.3, 0.3, 0.3, alpha);
cairo_paint(cr);
//...
And finally this is where I paint the window
cairo_xcb_surface_set_size(win->surface, width, height);
xcb_clear_area(win->con->connection, false, win->window, 0, 0, 0, 0);
cairo_set_source_surface(win->cr, surface, 0, 0);
cairo_paint(win->cr);
cairo_show_page(win->cr);