]> git.sur5r.net Git - i3/i3/commitdiff
Reimplement double-buffering
authorAxel Wagner <mail@merovius.de>
Sat, 4 Sep 2010 16:26:30 +0000 (18:26 +0200)
committerAxel Wagner <mail@merovius.de>
Sat, 4 Sep 2010 16:26:30 +0000 (18:26 +0200)
Due to a merge-fuckup, the double-buffer-code got lost. Know flickering
should not happen anymore.

i3bar/src/xcb.c

index d5a72ae3d8dd057b80dffa7497184bd6a42e0be3..42a49cede09e4413e8268e5162f590ba268fd980 100644 (file)
@@ -229,7 +229,7 @@ void xcb_chk_cb(struct ev_loop *loop, ev_check *watcher, int revents) {
     switch (event->response_type & ~0x80) {
         case XCB_EXPOSE:
             /* Expose-events happen, when the window needs to be redrawn */
-            draw_bars();
+            redraw_bars();
             break;
         case XCB_BUTTON_PRESS:
             /* Button-press-events are mouse-buttons clicked on one of our bars */
@@ -483,7 +483,6 @@ void reconfig_windows() {
     uint32_t mask;
     uint32_t values[5];
 
-    xcb_void_cookie_t   cookie;
     xcb_generic_error_t *err;
 
     i3_output *walk;
@@ -499,6 +498,7 @@ void reconfig_windows() {
             printf("Creating Window for output %s\n", walk->name);
 
             walk->bar = xcb_generate_id(xcb_connection);
+            walk->buffer = xcb_generate_id(xcb_connection);
             mask = XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
             /* Black background */
             values[0] = xcb_screens->black_pixel;
@@ -507,55 +507,68 @@ void reconfig_windows() {
             /* The events we want to receive */
             values[2] = XCB_EVENT_MASK_EXPOSURE |
                         XCB_EVENT_MASK_BUTTON_PRESS;
-            cookie = xcb_create_window_checked(xcb_connection,
-                                               xcb_screens->root_depth,
-                                               walk->bar,
-                                               xcb_root,
-                                               walk->rect.x, walk->rect.y,
-                                               walk->rect.w, font_height + 6,
-                                               1,
-                                               XCB_WINDOW_CLASS_INPUT_OUTPUT,
-                                               xcb_screens->root_visual,
-                                               mask,
-                                               values);
-            if ((err = xcb_request_check(xcb_connection, cookie)) != NULL) {
+            xcb_void_cookie_t win_cookie = xcb_create_window_checked(xcb_connection,
+                                                                     xcb_screens->root_depth,
+                                                                     walk->bar,
+                                                                     xcb_root,
+                                                                     walk->rect.x, walk->rect.y,
+                                                                     walk->rect.w, font_height + 6,
+                                                                     1,
+                                                                     XCB_WINDOW_CLASS_INPUT_OUTPUT,
+                                                                     xcb_screens->root_visual,
+                                                                     mask,
+                                                                     values);
+
+            xcb_void_cookie_t pm_cookie = xcb_create_pixmap_checked(xcb_connection,
+                                                                    xcb_screens->root_depth,
+                                                                    walk->buffer,
+                                                                    walk->bar,
+                                                                    walk->rect.w,
+                                                                    walk->rect.h);
+
+            /* We want dock-windows (for now) */
+            xcb_void_cookie_t prop_cookie = xcb_change_property(xcb_connection,
+                                                                XCB_PROP_MODE_REPLACE,
+                                                                walk->bar,
+                                                                atoms[_NET_WM_WINDOW_TYPE],
+                                                                atoms[ATOM],
+                                                                32,
+                                                                1,
+                                                                (unsigned char*) &atoms[_NET_WM_WINDOW_TYPE_DOCK]);
+            /* We also want a graphics-context (the "canvas" on which we draw) */
+            walk->bargc = xcb_generate_id(xcb_connection);
+            mask = XCB_GC_FONT;
+            values[0] = xcb_font;
+            xcb_void_cookie_t gc_cookie = xcb_create_gc_checked(xcb_connection,
+                                                                walk->bargc,
+                                                                walk->bar,
+                                                                mask,
+                                                                values);
+
+            /* We finally map the bar (display it on screen) */
+            xcb_void_cookie_t map_cookie = xcb_map_window_checked(xcb_connection, walk->bar);
+
+            if ((err = xcb_request_check(xcb_connection, win_cookie)) != NULL) {
                 printf("ERROR: Could not create Window. XCB-errorcode: %d\n", err->error_code);
                 exit(EXIT_FAILURE);
             }
 
-            /* We want dock-windows (for now) */
-            xcb_change_property(xcb_connection,
-                                XCB_PROP_MODE_REPLACE,
-                                walk->bar,
-                                atoms[_NET_WM_WINDOW_TYPE],
-                                atoms[ATOM],
-                                32,
-                                1,
-                                (unsigned char*) &atoms[_NET_WM_WINDOW_TYPE_DOCK]);
-            if ((err = xcb_request_check(xcb_connection, cookie)) != NULL) {
-                printf("ERROR: Could not set dock mode. XCB-errorcode: %d\n", err->error_code);
+            if ((err = xcb_request_check(xcb_connection, pm_cookie)) != NULL) {
+                printf("ERROR: Could not create Pixmap. XCB-errorcode: %d\n", err->error_code);
                 exit(EXIT_FAILURE);
             }
 
-            /* We also want a graphics-context (the "canvas" on which we draw) */
-            walk->bargc = xcb_generate_id(xcb_connection);
-            mask = XCB_GC_FONT;
-            values[0] = xcb_font;
-            cookie = xcb_create_gc_checked(xcb_connection,
-                                           walk->bargc,
-                                           walk->bar,
-                                           mask,
-                                           values);
+            if ((err = xcb_request_check(xcb_connection, prop_cookie)) != NULL) {
+                printf("ERROR: Could not set dock mode. XCB-errorcode: %d\n", err->error_code);
+                exit(EXIT_FAILURE);
+            }
 
-            if ((err = xcb_request_check(xcb_connection, cookie)) != NULL) {
+            if ((err = xcb_request_check(xcb_connection, gc_cookie)) != NULL) {
                 printf("ERROR: Could not create graphical context. XCB-errorcode: %d\n", err->error_code);
                 exit(EXIT_FAILURE);
             }
 
-            /* We finally map the bar (display it on screen) */
-            cookie = xcb_map_window_checked(xcb_connection, walk->bar);
-
-            if ((err = xcb_request_check(xcb_connection, cookie)) != NULL) {
+            if ((err = xcb_request_check(xcb_connection, map_cookie)) != NULL) {
                 printf("ERROR: Could not map window. XCB-errorcode: %d\n", err->error_code);
                 exit(EXIT_FAILURE);
             }
@@ -572,12 +585,12 @@ void reconfig_windows() {
             values[3] = font_height + 6;
             values[4] = XCB_STACK_MODE_ABOVE;
             printf("Reconfiguring Window for output %s to %d,%d\n", walk->name, values[0], values[1]);
-            cookie = xcb_configure_window_checked(xcb_connection,
-                                                  walk->bar,
-                                                  mask,
-                                                  values);
+            xcb_void_cookie_t cfg_cookie = xcb_configure_window_checked(xcb_connection,
+                                                                        walk->bar,
+                                                                        mask,
+                                                                        values);
 
-            if ((err = xcb_request_check(xcb_connection, cookie)) != NULL) {
+            if ((err = xcb_request_check(xcb_connection, cfg_cookie)) != NULL) {
                 printf("ERROR: Could not reconfigure window. XCB-errorcode: %d\n", err->error_code);
                 exit(EXIT_FAILURE);
             }
@@ -608,7 +621,7 @@ void draw_bars() {
                       &color);
         xcb_rectangle_t rect = { 0, 0, outputs_walk->rect.w, font_height + 6 };
         xcb_poly_fill_rectangle(xcb_connection,
-                                outputs_walk->bar,
+                                outputs_walk->buffer,
                                 outputs_walk->bargc,
                                 1,
                                 &rect);
@@ -630,7 +643,7 @@ void draw_bars() {
             xcb_void_cookie_t cookie;
             cookie = xcb_image_text_16(xcb_connection,
                                        glyph_count,
-                                       outputs_walk->bar,
+                                       outputs_walk->buffer,
                                        outputs_walk->bargc,
                                        outputs_walk->rect.w - get_string_width(text, glyph_count) - 4,
                                        font_height + 1,
@@ -665,7 +678,7 @@ void draw_bars() {
                           &color);
             xcb_rectangle_t rect = { i + 1, 1, ws_walk->name_width + 8, font_height + 4 };
             xcb_poly_fill_rectangle(xcb_connection,
-                                    outputs_walk->bar,
+                                    outputs_walk->buffer,
                                     outputs_walk->bargc,
                                     1,
                                     &rect);
@@ -676,13 +689,34 @@ void draw_bars() {
                           &color);
             xcb_image_text_16(xcb_connection,
                               ws_walk->name_glyphs,
-                              outputs_walk->bar,
+                              outputs_walk->buffer,
                               outputs_walk->bargc,
                               i + 5, font_height + 1,
                               ws_walk->ucs2_name);
             i += 10 + ws_walk->name_width;
         }
 
+        redraw_bars();
+
         i = 0;
     }
 }
+
+/*
+ * Redraw the bars, i.e. simply copy the buffer to the barwindow
+ *
+ */
+void redraw_bars() {
+    i3_output *outputs_walk;
+    SLIST_FOREACH(outputs_walk, outputs, slist) {
+        xcb_copy_area(xcb_connection,
+                      outputs_walk->buffer,
+                      outputs_walk->bar,
+                      outputs_walk->bargc,
+                      0, 0,
+                      0, 0,
+                      outputs_walk->rect.w,
+                      outputs_walk->rect.h);
+        xcb_flush(xcb_connection);
+    }
+}