Resizing the window

Running coloredwindow.c and enlarging the window, the squares are confined into the area the window occupied before the resizing.

The reason is easy to understand: the size of the window is found by calling XGetWindowAttributes, and this is done only at the beginning. The structure wa is not changed when the window is resized. In order for updating this variabile, we need to call XGetWindowAttributes each time the window size is changed.

An easy solution may be to update wa once in a while, using a small delay just to be sure not to miss a resize. This works for this module, but it is not the appropriate solution. There are cases in which we really have to do some more complex operations when the window is resized, and this would require to store the old value of the size.

The clean way to deal with a resize is by using events. Each time the size of a window is changed, the X server send an event of type Expose. What we have to do is to check whether there is any event for us, and update the structure wa if there is an event of type Expose.

In practice, we have to first tell the X server that we are interested in knowing whether an Expose event has been generated for our window. This tells the X server that we want to receive events of type Expose:

  /* we want expose events */
  XSelectInput(dpy, w, ExposureMask);

While we are drawing inside the window, it may be that the window is resized. This can be checked with the function XCheckWindowEvent. In particular, XCheckWindowEvent(dpy, w, ExposureMask, &e) returns True if there is an Expose event pending for the window w, otherwise it returns False. Note that resizing a window may generate more than one event, and we are only interested into the final size of the window. We can then simply read all pending events, and then getting the window attributes again. This amounts to putting the code below in the cycle of drawing.

      /* check events */
      if( XCheckWindowEvent(dpy, w, ExposureMask, &e) ) {
        while( XCheckWindowEvent(dpy, w, ExposureMask, &e) );

        XGetWindowAttributes (dpy, w, &wa);
      }

Note that Xflush is not needed any more, as XCheckWindowEvent flushes the output.

The complete code resizewindow.c is different from the previous module only for the fact that we first call XSelectInput to tell the X server that we want Expose events, and the fragment of checking whether such events has been sent to us.


Next: saving the contents.