293
293
EXPECT_EQ (*it++, w3);
294
294
EXPECT_EQ (*it++, w2);
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.
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)
307
::Display *dpy = Display ();
308
ct::PropertyNotifyXEventMatcher matcher (dpy, "_NET_CLIENT_LIST_STACKING");
310
Window dock = ct::CreateNormalWindow (dpy);
313
MakeDock (dpy, dock);
315
/* Immediately map the dock window and clear the event queue for it */
316
XMapRaised (dpy, dock);
318
ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, dock, ReparentNotify, -1, -1)));
319
ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindow (dpy, dock, MapNotify, -1, -1)));
321
/* Dock window needs to be in the client list */
322
ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
323
DefaultRootWindow (dpy),
328
std::list <Window> clientList = ct::NET_CLIENT_LIST_STACKING (dpy);
329
ASSERT_EQ (clientList.size (), 1);
331
Window w1 = ct::CreateNormalWindow (dpy);
332
Window w2 = ct::CreateNormalWindow (dpy);
334
XMapRaised (dpy, w1);
335
XMapRaised (dpy, w2);
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)));
343
/* Wait for property change notify on the root window to happen twice */
344
ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
345
DefaultRootWindow (dpy),
350
ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
351
DefaultRootWindow (dpy),
357
/* Check the client list to see that w2 > w1 */
358
clientList = ct::NET_CLIENT_LIST_STACKING (dpy);
360
ASSERT_EQ (clientList.size (), 3);
362
std::list <Window>::iterator it (clientList.begin ());
364
EXPECT_EQ (w1, (*it++));
365
EXPECT_EQ (w2, (*it++));
366
EXPECT_EQ (dock, (*it++));
368
/* Grab the server so that we can guaruntee that all of these requests
369
* happen before compiz gets them */
373
/* Create window that has w3 as its
375
Window w3 = ct::CreateNormalWindow (dpy);
377
XMapRaised (dpy, w3);
380
XDestroyWindow (dpy, w2);
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)));
389
/* Update _NET_CLIENT_LIST_STACKING twice */
390
ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
391
DefaultRootWindow (dpy),
396
ASSERT_TRUE (Advance (dpy, ct::WaitForEventOfTypeOnWindowMatching (dpy,
397
DefaultRootWindow (dpy),
403
/* Check the client list to see that dock > w3 > w1 */
404
clientList = ct::NET_CLIENT_LIST_STACKING (dpy);
406
it = clientList.begin ();
408
EXPECT_EQ (3, clientList.size ());
409
EXPECT_EQ (w1, (*it++));
410
EXPECT_EQ (w3, (*it++));
411
EXPECT_EQ (dock, (*it++));