i3 - improved tiling WM


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