~townsend/compiz/fix-lp890747

« back to all changes in this revision

Viewing changes to tests/xorg-gtest/plugins/testhelper/src/testhelper.cpp

  • Committer: Tarmac
  • Author(s): Sam Spilsbury
  • Date: 2013-07-18 13:06:24 UTC
  • mfrom: (3745.2.3 compiz.fix_1171314)
  • Revision ID: tarmac-20130718130624-wdwqqxwkrphvu4kv
Don't add the frame to the toplevel stack if it hasn't been created yet.

In the event that a window is unreparented or destroyed, we usually need
to add its frame window to the toplevel window stack until the time at
which we recieve a DestroyNotify for it, as there may be incoming
ConfigureNotify events puporting to stack other windows relative to
that frame.

However, this does not apply in the case where we have not yet received
a CreateNotify for the frame window. In that case, it is not possible
for any stacking requests to be made relative to this window, so it
does not need to be added immediately. Instead, we can add it at the
time that we recieve a CreateNotify for it as a regular override
redirect window until the time that it is later destroyed.

(LP: #1171314). Fixes: https://bugs.launchpad.net/bugs/1171314.

Approved by PS Jenkins bot, MC Return.

Show diffs side-by-side

added added

removed removed

Lines of Context:
178
178
    }
179
179
}
180
180
 
 
181
void
 
182
TestHelperWindow::setDestroyOnReparent (long *)
 
183
{
 
184
    destroyOnReparent = true;
 
185
}
 
186
 
 
187
void
 
188
TestHelperWindow::restackAtLeastAbove (long *data)
 
189
{
 
190
    ServerLock lock (screen->serverGrabInterface ());
 
191
 
 
192
    Window            above = data[0];
 
193
    XWindowAttributes attrib;
 
194
 
 
195
    if (!XGetWindowAttributes (screen->dpy (), above, &attrib))
 
196
        return;
 
197
 
 
198
    CompWindow *w = screen->findTopLevelWindow (above, true);
 
199
    for (; w; w = w->next)
 
200
        if (!w->overrideRedirect ())
 
201
            break;
 
202
 
 
203
    if (!w)
 
204
        return;
 
205
 
 
206
    XWindowChanges xwc;
 
207
 
 
208
    xwc.stack_mode = Above;
 
209
    xwc.sibling = w->frame () ? w->frame () : w->id ();
 
210
 
 
211
    window->restackAndConfigureXWindow (CWStackMode | CWSibling,
 
212
                                        &xwc,
 
213
                                        lock);
 
214
}
 
215
 
 
216
void
 
217
TestHelperWindow::windowNotify (CompWindowNotify n)
 
218
{
 
219
    switch (n)
 
220
    {
 
221
        case CompWindowNotifyReparent:
 
222
            if (destroyOnReparent)
 
223
            {
 
224
                Window id = window->id ();
 
225
                window->destroy ();
 
226
                XDestroyWindow (screen->dpy (), id);
 
227
            }
 
228
            break;
 
229
        default:
 
230
            break;
 
231
    }
 
232
 
 
233
    window->windowNotify (n);
 
234
}
 
235
 
181
236
TestHelperWindow::TestHelperWindow (CompWindow *w) :
182
237
    PluginClassHandler <TestHelperWindow, CompWindow> (w),
183
238
    window (w),
184
 
    configureLock ()
 
239
    configureLock (),
 
240
    destroyOnReparent (false)
185
241
{
186
242
    WindowInterface::setHandler (w);
187
243
 
211
267
                     &TestHelperWindow::setFrameExtentsAndReport);
212
268
    watchForMessage (fetchAtom (ctm::TEST_HELPER_LOCK_CONFIGURE_REQUESTS),
213
269
                     &TestHelperWindow::setConfigureLock);
 
270
    watchForMessage (fetchAtom (ctm::TEST_HELPER_DESTROY_ON_REPARENT),
 
271
                     &TestHelperWindow::setDestroyOnReparent);
 
272
    watchForMessage (fetchAtom (ctm::TEST_HELPER_RESTACK_ATLEAST_ABOVE),
 
273
                     &TestHelperWindow::restackAtLeastAbove);
214
274
 
215
275
    ct::SendClientMessage (s->dpy (),
216
276
                           mAtomStore.FetchForString (ctm::TEST_HELPER_READY_MSG),