← Back to team overview

desktop-packages team mailing list archive

[Bug 1088399] Re: Creating windows above just-destroyed windows causes newly created windows to receive invalid stack positions

 

Closing Compiz 0.9.9 task (0.9.9 series is obsolete)

** Changed in: compiz/0.9.9
       Status: Fix Committed => Fix Released

-- 
You received this bug notification because you are a member of Desktop
Packages, which is subscribed to compiz in Ubuntu.
https://bugs.launchpad.net/bugs/1088399

Title:
  Creating windows above just-destroyed windows causes newly created
  windows to receive invalid stack positions

Status in Compiz:
  Fix Released
Status in Compiz 0.9.9 series:
  Fix Released
Status in “compiz” package in Ubuntu:
  Fix Released

Bug description:
  There's a race condition in the stacking code which can cause windows
  to receive invalid stack positions.

  This sample program shows how that race condition might happen over
  two display connections:

  #include <X11/Xlib.h>
  #include <stdio.h>

  int main ()
  {
      Display *d = XOpenDisplay (NULL);
      Display *other = XOpenDisplay (NULL);
      Window root = DefaultRootWindow (d);
      Window container = XCreateSimpleWindow (d, root, 100, 100, 100, 100, 0, 0, 0);

      Window w1 = XCreateSimpleWindow (d, container, 0, 0, 10, 10, 0, 0xffff00, 0xffff00);
      Window w2 = XCreateSimpleWindow (d, container, 1, 1, 10, 10, 0, 0xff0000, 0xff0000);
      Window w3 = XCreateSimpleWindow (d, container, 2, 2, 10, 10, 0, 0x00ff00, 0x00ff00);

      /* Map all three */
      XMapWindow (d, w1);
      XMapWindow (d, w2);
      XMapWindow (d, w3);

      XMapWindow (d, container);

      /* Destroy 1 */
      XDestroyWindow (d, w1);
      XSync (d, 0);

      /* Stack 3 above 1 */
      XWindowChanges xwc;
      xwc.stack_mode = Above;
      xwc.sibling = w1;
      XConfigureWindow (other, w3, CWSibling | CWStackMode, &xwc);

      Window *children = NULL;
      unsigned int nchildren;
      Window dummy;

      XQueryTree (other, container, &dummy, &dummy, &children, &nchildren);
      int i = 0;
      for (i = 0; i < nchildren; ++i)
      {
  	printf ("0x%x\n", (unsigned int) children[i]);
      }

      XCloseDisplay (d);
      XCloseDisplay (other);
      return 0;
  }

  The problem is that configuring a window to be stacked relative to a
  destroyed window is an invalid operation, however, there's a race
  condition where if we are between handling events, we may find a
  suitable candidate to stack above, however we may not have received a
  DestroyNotify for that candidate yet. If we issue a ConfigureWindow
  request to stack above that candidate, it will fail with a BadWindow
  error when we later flush the output buffer, however we didn't really
  have a way of knowing it was going to fail (and furthermore, we ignore
  X errors, a bad thing in itself, but a separate bug), so that would
  cause us to mark the window as having successfully being restacked
  internally whereas in reality it wasn't restacked at all. Then when we
  restack other windows relative to the window that failed the restack,
  they are going to receive positions which are relative to its
  /original/ position (and not its changed position), which is usually
  above everything else and invalid.

  From a user point of view, I can reproduce this by opening ~20 or so
  gnome-terminals and restarting compiz in the classic session. The
  terminals will end up above the panels.

To manage notifications about this bug go to:
https://bugs.launchpad.net/compiz/+bug/1088399/+subscriptions