~3v1n0/compiz/gtk-decorator-finalize-menu-0.9.10

« back to all changes in this revision

Viewing changes to src/window.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:
1189
1189
        CompWindow *oldNext       = next;
1190
1190
        CompWindow *oldPrev       = prev;
1191
1191
 
1192
 
        /* This is where things get tricky ... it is possible
1193
 
         * to receive a ConfigureNotify relative to a frame window
1194
 
         * for a destroyed window in case we process a ConfigureRequest
1195
 
         * for the destroyed window and then a DestroyNotify for it directly
1196
 
         * afterwards. In that case, we will receive the ConfigureNotify
1197
 
         * for the XConfigureWindow request we made relative to that frame
1198
 
         * window. Because of this, we must keep the frame window in the stack
1199
 
         * as a new toplevel window so that the ConfigureNotify will be processed
1200
 
         * properly until it too receives a DestroyNotify */
1201
 
 
1202
 
        if (priv->serverFrame)
1203
 
        {
1204
 
            XWindowAttributes attrib;
1205
 
 
1206
 
            /* It's possible that the frame window was already destroyed because
1207
 
             * the client was unreparented before it was destroyed (eg
1208
 
             * UnmapNotify before DestroyNotify). In that case the frame window
1209
 
             * is going to be an invalid window but since we haven't received
1210
 
             * a DestroyNotify for it yet, it is possible that restacking
1211
 
             * operations could occurr relative to it so we need to hold it
1212
 
             * in the stack for now. Ensure that it is marked override redirect */
1213
 
            XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib);
1214
 
 
1215
 
            /* Put the frame window "above" the client window
1216
 
             * in the stack */
1217
 
            PrivateWindow::createCompWindow (priv->id, priv->id, attrib, priv->serverFrame);
1218
 
        }
 
1192
        priv->manageFrameWindowSeparately ();
1219
1193
 
1220
1194
        /* Immediately unhook the window once destroyed
1221
1195
         * as the stacking order will be invalid if we don't
6884
6858
}
6885
6859
 
6886
6860
void
 
6861
PrivateWindow::manageFrameWindowSeparately ()
 
6862
{
 
6863
    /* This is where things get tricky ... it is possible
 
6864
     * to receive a ConfigureNotify relative to a frame window
 
6865
     * for a destroyed window in case we process a ConfigureRequest
 
6866
     * for the destroyed window and then a DestroyNotify for it directly
 
6867
     * afterwards. In that case, we will receive the ConfigureNotify
 
6868
     * for the XConfigureWindow request we made relative to that frame
 
6869
     * window. Because of this, we must keep the frame window in the stack
 
6870
     * as a new toplevel window so that the ConfigureNotify will be processed
 
6871
     * properly until it too receives a DestroyNotify
 
6872
     *
 
6873
     * We only wish to do this if we have recieved a CreateNotify for the
 
6874
     * frame window. If we have not, then there will be no stacking operations
 
6875
     * dependent on it and we should wait until CreateNotify in order to manage
 
6876
     * it normally */
 
6877
 
 
6878
    if (frame)
 
6879
    {
 
6880
        XWindowAttributes attrib;
 
6881
 
 
6882
        /* It's possible that the frame window was already destroyed because
 
6883
         * the client was unreparented before it was destroyed (eg
 
6884
         * UnmapNotify before DestroyNotify). In that case the frame window
 
6885
         * is going to be an invalid window but since we haven't received
 
6886
         * a DestroyNotify for it yet, it is possible that restacking
 
6887
         * operations could occurr relative to it so we need to hold it
 
6888
         * in the stack for now. Ensure that it is marked override redirect */
 
6889
        window->priv->queryFrameAttributes (attrib);
 
6890
 
 
6891
        /* Put the frame window "above" the client window
 
6892
         * in the stack */
 
6893
        PrivateWindow::createCompWindow (id, id, attrib, frame);
 
6894
    }
 
6895
 
 
6896
}
 
6897
 
 
6898
void
6887
6899
PrivateWindow::unreparent ()
6888
6900
{
6889
6901
    if (!serverFrame)
6978
6990
    if (dbg)
6979
6991
        dbg->addDestroyedFrame (serverFrame);
6980
6992
 
6981
 
    /* This is where things get tricky ... it is possible
6982
 
     * to receive a ConfigureNotify relative to a frame window
6983
 
     * for a destroyed window in case we process a ConfigureRequest
6984
 
     * for the destroyed window and then a DestroyNotify for it directly
6985
 
     * afterwards. In that case, we will receive the ConfigureNotify
6986
 
     * for the XConfigureWindow request we made relative to that frame
6987
 
     * window. Because of this, we must keep the frame window in the stack
6988
 
     * as a new toplevel window so that the ConfigureNotify will be processed
6989
 
     * properly until it too receives a DestroyNotify */
6990
 
 
6991
 
    if (serverFrame)
6992
 
    {
6993
 
        XWindowAttributes attrib;
6994
 
 
6995
 
        /* It's possible that the frame window was already destroyed because
6996
 
         * the client was unreparented before it was destroyed (eg
6997
 
         * UnmapNotify before DestroyNotify). In that case the frame window
6998
 
         * is going to be an invalid window but since we haven't received
6999
 
         * a DestroyNotify for it yet, it is possible that restacking
7000
 
         * operations could occurr relative to it so we need to hold it
7001
 
         * in the stack for now. Ensure that it is marked override redirect */
7002
 
        window->priv->queryFrameAttributes (attrib);
7003
 
 
7004
 
        /* Put the frame window "above" the client window
7005
 
         * in the stack */
7006
 
        PrivateWindow::createCompWindow (id, id, attrib, serverFrame);
7007
 
    }
 
6993
    manageFrameWindowSeparately ();
7008
6994
 
7009
6995
    /* Issue a DestroyNotify */
7010
6996
    XDestroyWindow (screen->dpy (), serverFrame);