+ /* Set new position if rect changed (and if height > 0) */
+ if (memcmp(&(state->rect), &rect, sizeof(Rect)) != 0 &&
+ rect.height > 0) {
+ /* We first create the new pixmap, then render to it, set it as the
+ * background and only afterwards change the window size. This reduces
+ * flickering. */
+
+ /* As the pixmap only depends on the size and not on the position, it
+ * is enough to check if width/height have changed. Also, we don’t
+ * create a pixmap at all when the window is actually not visible
+ * (height == 0). */
+ if ((state->rect.width != rect.width ||
+ state->rect.height != rect.height)) {
+ DLOG("CACHE: creating new pixmap for con %p (old: %d x %d, new: %d x %d)\n",
+ con, state->rect.width, state->rect.height,
+ rect.width, rect.height);
+ if (con->pixmap == 0) {
+ con->pixmap = xcb_generate_id(conn);
+ con->pm_gc = xcb_generate_id(conn);
+ } else {
+ xcb_free_pixmap(conn, con->pixmap);
+ xcb_free_gc(conn, con->pm_gc);
+ }
+ xcb_create_pixmap(conn, root_depth, con->pixmap, con->frame, rect.width, rect.height);
+ /* For the graphics context, we disable GraphicsExposure events.
+ * Those will be sent when a CopyArea request cannot be fulfilled
+ * properly due to parts of the source being unmapped or otherwise
+ * unavailable. Since we always copy from pixmaps to windows, this
+ * is not a concern for us. */
+ uint32_t values[] = { 0 };
+ xcb_create_gc(conn, con->pm_gc, con->pixmap, XCB_GC_GRAPHICS_EXPOSURES, values);
+
+ con->pixmap_recreated = true;
+
+ /* Don’t render the decoration for windows inside a stack which are
+ * not visible right now */
+ if (!con->parent ||
+ con->parent->layout != L_STACKED ||
+ TAILQ_FIRST(&(con->parent->focus_head)) == con)
+ /* Render the decoration now to make the correct decoration visible
+ * from the very first moment. Later calls will be cached, so this
+ * doesn’t hurt performance. */
+ x_deco_recurse(con);
+ }
+