Hi! I noticed in a different context that fluxbow was sending superfluous "expose" events when losing and gaining focus. These events are normally sent when parts of a window were exposed and thus need redrawing. I guess these could be responsible for the anomalous flickering.
The attached example program just creates a simple window using the X11 SHAPE extension. You can see that when losing focus, the window receives two expose events and when the window gains focus it receives four expose events. All these events are seemingly unnecessary, since nothing in the window was actually exposed. Notes: - I also tried the same program under icewm, where these events are not sent. - I have noticed that both gmplayer and xine suffer from the flickering, but I don't actually know if it is caused by the expose events. - I'm not sure if this is related, but #593061 is also about focus handling. I noticed here that when entering the window created by the example program, the window doesn't always receive focus. In particular when I cross the border quickly it seems to sometimes miss this. I hope this helps a bit. Uli
// Example program for Debian bug #544112 // // g++ -Wall `pkg-config xcb xcb-shape --cflags --libs` // #include <stdlib.h> #include <string.h> #include <xcb/xcb.h> #include <xcb/shape.h> #include <iostream> #include <stdexcept> #include <assert.h> /* global objects, the connection to the X server and the window created there. */ xcb_connection_t* connection = 0; xcb_window_t win; void init_connection() { /* open connection to the server */ connection = xcb_connect(NULL,NULL); if (xcb_connection_has_error(connection)) throw std::runtime_error("xcb_connect() failed"); } void check_shape_extension() { // query for availability xcb_query_extension_reply_t const* reply = xcb_get_extension_data( connection, &xcb_shape_id); if(!reply) throw std::runtime_error("xcb_get_extension_data failed"); if(!reply->present) throw std::runtime_error("X11 shape extension not present"); // query version xcb_shape_query_version_cookie_t cookie = xcb_shape_query_version_unchecked(connection); xcb_shape_query_version_reply_t* version = xcb_shape_query_version_reply(connection, cookie, 0); if(!version) throw std::runtime_error("xcb_shape_query_version failed"); } void create_window(int16_t x, int16_t y, uint16_t width, uint16_t height) { /* retrieve the first screen from the setup */ xcb_setup_t const* setup = xcb_get_setup(connection); if(!setup) throw std::runtime_error("xcb_get_setup() failed"); xcb_screen_t* screen = xcb_setup_roots_iterator(setup).data; if(!screen) throw std::runtime_error("missing root screen"); // create window xcb_window_t id = xcb_generate_id(connection); uint32_t const win_values[] = { screen->black_pixel, XCB_EVENT_MASK_EXPOSURE }; xcb_create_window(connection, XCB_COPY_FROM_PARENT, // depth id, screen->root, // parent x, y, width, height, // position, size 0, // border width XCB_WINDOW_CLASS_INPUT_OUTPUT, // class XCB_COPY_FROM_PARENT, // visual XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK, win_values); win = id; } int main(int argc, char** argv) { try { init_connection(); create_window(0, 0, 50, 50); // set rectangualar base outline xcb_rectangle_t const rect = {0, 0, 50, 50}; xcb_shape_rectangles(connection, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, 0, win, 0, 0, // offset 1, &rect); // actually display window xcb_map_window(connection, win); int const e = xcb_flush(connection); if(e<=0) // TODO: provide more detailed diagnostics if possible throw std::runtime_error("xcb_flush failed"); // poll connection's file descriptor for events int const ss = xcb_get_file_descriptor(connection); while(true) { // wait on the connection socket fd_set fd; FD_ZERO(&fd); FD_SET( ss, &fd); timeval timeout; timeout.tv_usec = 0; timeout.tv_sec = 1; switch(select( ss+1, &fd, 0, 0, &timeout)) { case -1: throw std::runtime_error("select failed"); case 0: std::cout << "select timed out" << std::endl; break; case 1: break; default: std::cout << "select return unexpected value" << std::endl; break; } // handle all available events xcb_generic_event_t* e = 0; while((e = xcb_poll_for_event(connection))) { switch (e->response_type & ~0x80) { case XCB_EXPOSE: { /* Note: Filling the whole window with background color is done automatically, so we don't have to do anything here at all. */ xcb_expose_event_t const& expose = (xcb_expose_event_t const&)*e; std::cout << "expose_event x=" << expose.x << ", y=" << expose.y << ", width=" << expose.width << ", height=" << expose.height << ", count=" << expose.count << std::endl; } break; default: std::cout << "received response " << unsigned(e->response_type) << std::endl; break; } free(e); } // check for connection errors if (xcb_connection_has_error(connection)) throw std::runtime_error("connection lost"); } return EXIT_SUCCESS; } catch(std::exception const& e) { std::cerr << "error: " << e.what() << std::endl; return EXIT_FAILURE; } }