title: How to avoid cairo drawing xlib surface from flickering?
body: <p>I'm doing some programming with <strong>cairo</strong> and <strong>xlib</strong> in <strong>C++</strong>, my code is listed below.</p>
  
  <p>I had some flickering issues but by modifying my code, it seems works good now generally.<br>
  But when the window is resized at a <strong>small size</strong> (about 600x450 on my laptop), it is still <strong>flickering</strong>.<br>
  How can I fix it?</p>
  
  <pre><code>#include &lt;cairo.h&gt;
  #include &lt;cairo-xlib.h&gt;
  #include &lt;string&gt;
  #include &lt;cstdio&gt;
  
  using namespace std;
  
  int main (int argc, char *argv[])
  {
      cairo_surface_t *surface;
      cairo_t *cr;
  
      surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 800, 600);
      cr = cairo_create (surface);
      /* Examples are in 1.0 x
       * 1.0 coordinate space */
      cairo_scale (cr, 800, 600);
  
      cairo_set_source_rgb (cr, 1.0, 0, 0);
      cairo_rectangle (cr, 0, 0, 1.0, 1.0);
      cairo_fill(cr);
      cairo_destroy(cr);
  
      Display *display = XOpenDisplay(NULL);
      int default_scr = DefaultScreen(display);
      Visual *visual = DefaultVisual(display, default_scr);
      Window root_win = RootWindow(display, default_scr);
      Drawable drawable = XCreateSimpleWindow(display, root_win, 0, 0, 800, 600, 0,
              BlackPixel(display, default_scr), WhitePixel(display, default_scr));
      cairo_surface_t *x11_sf = cairo_xlib_surface_create(display, drawable, visual, 800, 600);
  
      XSelectInput(display, drawable, ExposureMask | StructureNotifyMask);
      XMapWindow(display, drawable);
      XFlush(display);
      XSync(display, default_scr);
      Atom wmDeleteMessage = XInternAtom(display, "WM_DELETE_WINDOW", False);
      XSetWMProtocols(display, drawable, &amp;wmDeleteMessage, 1);
  
      int height;
      int width;
      XEvent event;
      bool running = true;
      while (running)
      {
          XNextEvent(display, &amp;event);
          switch (event.type)
          {
          case Expose:
              {
                  cairo_t *x11_cr = cairo_create(x11_sf);
                  cairo_scale(x11_cr, double(width) / 800, double(height) / 600);
                  cairo_set_source_surface(x11_cr, surface, 0, 0);
                  cairo_paint(x11_cr);
                  cairo_destroy (x11_cr);
              }
              break;
          case ClientMessage:
              if (event.xclient.data.l[0] == wmDeleteMessage)
              {
                  running = false;
              }
              break;
          case ConfigureNotify:
              width = event.xconfigure.width;
              height = event.xconfigure.height;
              cairo_xlib_surface_set_size(x11_sf, width, height);
              break;
          }
      }
  
      cairo_surface_destroy (surface);
  
      return 0;
  }
  </code></pre>
  
  <hr>
  
  <p>I use <code>cairo_xlib_surface</code> to draw a window, which has a whole red background color. I tried to catch <code>XExpose</code> event and redraw it. But sometimes the redraw result gets strange.</p>
  
  <pre><code>#include &lt;cairo.h&gt;
  #include &lt;cairo-xlib.h&gt;
  #include &lt;string&gt;
  #include &lt;cstdio&gt;
  
  using namespace std;
  
  int main (int argc, char *argv[])
  {
      cairo_surface_t *surface;
      cairo_t *cr;
  
      surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 800, 600);
      cr = cairo_create (surface);
      /* Examples are in 1.0 x 1.0 coordinate space */
      cairo_scale (cr, 800, 600);
  
      /* Drawing code goes here */
      cairo_set_source_rgb (cr, 1.0, 0, 0);
      cairo_rectangle (cr, 0, 0, 1.0, 1.0);
      cairo_fill(cr);
  
      Display *display = XOpenDisplay(NULL);
      int default_scr = DefaultScreen(display);
      Visual *visual = DefaultVisual(display, default_scr);
      Window root_win = RootWindow(display, default_scr);
      Drawable drawable = XCreateSimpleWindow(display, root_win, 0, 0, 800, 600, 0,
              BlackPixel(display, default_scr), WhitePixel(display, default_scr));
  
      XSelectInput(display, drawable, ExposureMask);
      XMapWindow(display, drawable);
      XFlush(display);
      XSync(display, default_scr);
  
  
      int height;
      int width;
      XEvent event;
      while (1)
      {
          XNextEvent(display, &amp;event);
          switch (event.type)
          {
          case Expose:
              {
                  width = event.xexpose.width;
                  height = event.xexpose.height;
                  cairo_surface_t *x11_sf = cairo_xlib_surface_create(display, drawable, visual, width, height);
                  cairo_t *x11_cr = cairo_create(x11_sf);
                  cairo_scale(x11_cr, double(width) / 800, double(height) / 600);
                  cairo_set_source_surface(x11_cr, surface, 0, 0);
                  cairo_paint(x11_cr);
                  cairo_destroy (x11_cr);
                  cairo_surface_destroy (x11_sf);
              }
              break;
          }
      }
  
  
      /* Write output and clean up */
      cairo_destroy (cr);
      cairo_surface_destroy (surface);
  
      return 0;
  }
  </code></pre>
  
  <p>When I resize the window, sometimes I get the result like this:
  <a href="https://i.stack.imgur.com/cv1N5.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/cv1N5.png" alt="The result window"></a></p>
  
  <p>It seems it hasn't finished to draw the red background.</p>
  
  <p>Could someone tell me why this occurs and how to avoid it?</p>
  
  <p>If someone want to compile it under <strong>Linux</strong>, could use: g++ <code>\pkg-config --cflags --libs x11 cairo\</code> src.cpp</p>
  
  <p>Thanks!</p>