Do not create container pixmap when not needed
Patch status: needinfo
Patch by Tony Crisci
Long description:
A pixmap for a floating container without a border is not necessary because nothing meaningful will be drawn to it. It could possibly obscure areas meant to be transparent by the client. Destroy any pixmap for such a container. fixes #1013
To apply this patch, use:
curl http://cr.i3wm.org/patch/381/raw.patch | git am
b/src/x.c
20 |
@@ -667,9 +667,16 @@ void x_push_node(Con *con) { |
21 |
/* As the pixmap only depends on the size and not on the position, it |
22 |
* is enough to check if width/height have changed. Also, we don’t |
23 |
* create a pixmap at all when the window is actually not visible |
24 |
- * (height == 0). */ |
25 |
- if ((state->rect.width != rect.width || |
26 |
- state->rect.height != rect.height)) { |
27 |
+ * (height == 0) or when it is not needed. */ |
28 |
+ bool has_rect_changed = !(state->rect.width == rect.width && state->rect.height == rect.height); |
29 |
+ |
30 |
+ /* There is a special case where the window is visible (height > 0), |
31 |
+ * but no decorations will be drawn to the container's pixmap. These |
32 |
+ * windows may be overlays that expect a transparent background, so the |
33 |
+ * pixmap may get in the way (see #1013). */ |
34 |
+ bool is_pixmap_needed = !(con->border_style == BS_NONE && con_is_floating(con)); |
35 |
+ |
36 |
+ if (has_rect_changed && is_pixmap_needed) { |
37 |
if (con->pixmap == 0) { |
38 |
con->pixmap = xcb_generate_id(conn); |
39 |
con->pm_gc = xcb_generate_id(conn); |
40 |
@@ -705,6 +712,15 @@ void x_push_node(Con *con) { |
41 |
x_deco_recurse(con); |
42 |
} |
43 |
|
44 |
+ /* When the pixmap is not needed, the container may still have a pixmap |
45 |
+ * left over from being in a previous state, so we clean that up here. |
46 |
+ * */ |
47 |
+ if (!is_pixmap_needed && con->pixmap != XCB_NONE) { |
48 |
+ xcb_free_pixmap(conn, con->pixmap); |
49 |
+ xcb_free_gc(conn, con->pm_gc); |
50 |
+ con->pixmap = XCB_NONE; |
51 |
+ } |
52 |
+ |
53 |
DLOG("setting rect (%d, %d, %d, %d)\n", rect.x, rect.y, rect.width, rect.height); |
54 |
/* flush to ensure that the following commands are sent in a single |
55 |
* buffer and will be processed directly afterwards (the contents of a |