~compiz-team/compiz/compiz.fix_1088399

« back to all changes in this revision

Viewing changes to tests/system/xorg-gtest/tests/compiz_xorg_gtest_test_window_stacking.cpp

  • Committer: Sam Spilsbury
  • Date: 2012-12-10 12:29:06 UTC
  • Revision ID: sam.spilsbury@canonical.com-20121210122906-uzbht3ydng824cou
Added test case for restacking relative to destroyed windows.

Under TDD methodology, this should be a failing test, however it isn't,
because (LP: #1088399) is a race condition between when we receive
MapRequest for a client and map the window and then later between that, destroy
it and receive a CreateNotify for a new window on top of it, and restack
the new window on top of the not-yet-mapped, but-also-destroyed window

Show diffs side-by-side

added added

removed removed

Lines of Context:
293
293
    EXPECT_EQ (*it++, w3);
294
294
    EXPECT_EQ (*it++, w2);
295
295
}
 
296
 
 
297
/* This test isn't really an accurate representation of the problem
 
298
 * because the real problem is a race condition where in between
 
299
 * w3 getting a MapRequest and a MapNotify, w3 is destroyed on
 
300
 * the server and it would be an error to restack relative to it.
 
301
 *
 
302
 * Unfortunately there's no way to accurately reproduce that problem,
 
303
 * because it is purely timing based, so this test case just tests
 
304
 * the relevant codepath for regressions */
 
305
TEST_F (CompizXorgSystemStackingTest, TestCreateRelativeToDestroyedWindowFindsAnotherAppropriatePosition)
 
306
{
 
307
    ::Display *dpy = Display ();
 
308
    ct::PropertyNotifyXEventMatcher matcher (dpy, "_NET_CLIENT_LIST_STACKING");
 
309
 
 
310
    Window dock = ct::CreateNormalWindow (dpy);
 
311
 
 
312
    /* Make it a dock */
 
313
    MakeDock (dpy, dock);
 
314
 
 
315
    /* Immediately map the dock window and clear the event queue for it */
 
316
    XMapRaised (dpy, dock);
 
317
 
 
318
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, dock, ReparentNotify, -1, -1)));
 
319
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, dock, MapNotify, -1, -1)));
 
320
 
 
321
    /* Dock window needs to be in the client list */
 
322
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
 
323
                                                                       DefaultRootWindow (dpy),
 
324
                                                                       PropertyNotify,
 
325
                                                                       -1,
 
326
                                                                       -1,
 
327
                                                                       matcher)));
 
328
    std::list <Window> clientList = ct::NET_CLIENT_LIST_STACKING (dpy);
 
329
    ASSERT_EQ (clientList.size (), 1);
 
330
 
 
331
    Window w1 = ct::CreateNormalWindow (dpy);
 
332
    Window w2 = ct::CreateNormalWindow (dpy);
 
333
 
 
334
    XMapRaised (dpy, w1);
 
335
    XMapRaised (dpy, w2);
 
336
 
 
337
    /* All reparented and mapped */
 
338
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy,w1, ReparentNotify, -1, -1)));
 
339
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, w1, MapNotify, -1, -1)));
 
340
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, w2, ReparentNotify, -1, -1)));
 
341
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, w2, MapNotify, -1, -1)));
 
342
 
 
343
    /* Wait for property change notify on the root window to happen twice */
 
344
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
 
345
                                                                       DefaultRootWindow (dpy),
 
346
                                                                       PropertyNotify,
 
347
                                                                       -1,
 
348
                                                                       -1,
 
349
                                                                       matcher)));
 
350
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
 
351
                                                                       DefaultRootWindow (dpy),
 
352
                                                                       PropertyNotify,
 
353
                                                                       -1,
 
354
                                                                       -1,
 
355
                                                                       matcher)));
 
356
 
 
357
    /* Check the client list to see that w2 > w1 */
 
358
    clientList = ct::NET_CLIENT_LIST_STACKING (dpy);
 
359
 
 
360
    ASSERT_EQ (clientList.size (), 3);
 
361
 
 
362
    std::list <Window>::iterator it (clientList.begin ());
 
363
 
 
364
    EXPECT_EQ (w1, (*it++));
 
365
    EXPECT_EQ (w2, (*it++));
 
366
    EXPECT_EQ (dock, (*it++));
 
367
 
 
368
    /* Grab the server so that we can guaruntee that all of these requests
 
369
     * happen before compiz gets them */
 
370
    XGrabServer (dpy);
 
371
    XSync (dpy, false);
 
372
 
 
373
    /* Create window that has w3 as its
 
374
     * ideal candidate */
 
375
    Window w3 = ct::CreateNormalWindow (dpy);
 
376
 
 
377
    XMapRaised (dpy, w3);
 
378
 
 
379
    /* Destroy w2 */
 
380
    XDestroyWindow (dpy, w2);
 
381
 
 
382
    XUngrabServer (dpy);
 
383
    XSync (dpy, false);
 
384
 
 
385
    /* Reparented and mapped */
 
386
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, w3, ReparentNotify, -1, -1)));
 
387
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, w3, MapNotify, -1, -1)));
 
388
 
 
389
    /* Update _NET_CLIENT_LIST_STACKING twice */
 
390
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
 
391
                                                                       DefaultRootWindow (dpy),
 
392
                                                                       PropertyNotify,
 
393
                                                                       -1,
 
394
                                                                       -1,
 
395
                                                                       matcher)));
 
396
    ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
 
397
                                                                       DefaultRootWindow (dpy),
 
398
                                                                       PropertyNotify,
 
399
                                                                       -1,
 
400
                                                                       -1,
 
401
                                                                       matcher)));
 
402
 
 
403
    /* Check the client list to see that dock > w3 > w1 */
 
404
    clientList = ct::NET_CLIENT_LIST_STACKING (dpy);
 
405
 
 
406
    it = clientList.begin ();
 
407
 
 
408
    EXPECT_EQ (3, clientList.size ());
 
409
    EXPECT_EQ (w1, (*it++));
 
410
    EXPECT_EQ (w3, (*it++));
 
411
    EXPECT_EQ (dock, (*it++));
 
412
}