From 4e298d5a1d386da2f50c013de8fed3b666fb81c5 Mon Sep 17 00:00:00 2001 From: Axel Wagner Date: Sat, 4 Sep 2010 18:26:30 +0200 Subject: [PATCH] Reimplement double-buffering Due to a merge-fuckup, the double-buffer-code got lost. Know flickering should not happen anymore. --- i3bar/src/xcb.c | 132 ++++++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 49 deletions(-) diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index d5a72ae3..42a49ced 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -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) { - printf("ERROR: Could not create Window. XCB-errorcode: %d\n", err->error_code); - exit(EXIT_FAILURE); - } + 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_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); - exit(EXIT_FAILURE); - } - + 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; - cookie = xcb_create_gc_checked(xcb_connection, - walk->bargc, - walk->bar, - mask, - values); + xcb_void_cookie_t gc_cookie = xcb_create_gc_checked(xcb_connection, + walk->bargc, + walk->bar, + mask, + values); - if ((err = xcb_request_check(xcb_connection, cookie)) != NULL) { + /* 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); + } + + 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); + } + + 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, 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); + } +}