~ubuntu-branches/ubuntu/oneiric/compiz/oneiric

« back to all changes in this revision

Viewing changes to src/window.cpp

  • Committer: Package Import Robot
  • Author(s): Didier Roche
  • Date: 2011-09-28 14:15:21 UTC
  • mfrom: (0.168.12 upstream)
  • Revision ID: package-import@ubuntu.com-20110928141521-sf8s523pqyptq61f
Tags: 1:0.9.6-0ubuntu1
* New upstream release 0.9.6:
 - Windows which are marked transients of docks should be treated like docks (LP: #860397)
 - Applications which create multiple windows that are transients of each other can be given invalid stack positions (LP: #858625)
 - race condition in configureXWindow causes unpredicatable window geometry changes (LP: #860304)
 - invisible window when a window is mapped but not yet drawn on by the process mapping it (LP: #860286)
 - resizing bugs with xterm (LP: #854725)
 - Cannot open a window that starts iconified (LP: #732997)
 - maximized windows fail to update their input extents when undecorated (LP: #853734)
 - Clicking on a tweet/message link sometimes does not work (LP: #790565)
 - crash on closing a window (LP: #856015)
 - Windows move to 0,0 on compiz restarts (LP: #858629)
 - windows that are decorated while resizing can cause incorrect resize results (LP: #860306)
 - remove transient window handling from unity-window-decorator (LP: #856096)

Show diffs side-by-side

added added

removed removed

Lines of Context:
766
766
void
767
767
PrivateWindow::updateFrameWindow ()
768
768
{
 
769
    XWindowChanges xwc;
 
770
    unsigned int   valueMask = CWX | CWY | CWWidth | CWHeight;
 
771
 
769
772
    if (!serverFrame)
770
773
        return;
771
774
 
 
775
    /* Flush any changes made to serverFrameGeometry or serverGeometry to the server
 
776
     * since there is a race condition where geometries will go out-of-sync with
 
777
     * window movement */
 
778
 
 
779
    window->syncPosition ();
772
780
    if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
773
781
    {
774
 
        int        x, y, width, height;
775
782
        int        bw = serverGeometry.border () * 2;
776
783
 
777
 
        x      = serverGeometry.x () - serverInput.left;
778
 
        y      = serverGeometry.y () - serverInput.top;
779
 
        width  = serverGeometry.width () + serverInput.left + serverInput.right + bw;
780
 
        height = serverGeometry.height () + serverInput.top  + serverInput.bottom + bw;
 
784
        xwc.x      = serverGeometry.x () - serverInput.left;
 
785
        xwc.y      = serverGeometry.y () - serverInput.top;
 
786
        xwc.width  = serverGeometry.width () + serverInput.left + serverInput.right + bw;
 
787
        xwc.height = serverGeometry.height () + serverInput.top  + serverInput.bottom + bw;
781
788
 
782
789
        if (shaded)
783
790
            height = serverInput.top + serverInput.bottom;
784
791
 
 
792
        if (serverFrameGeometry.x () == xwc.x)
 
793
            valueMask &= ~(CWX);
 
794
        else
 
795
            serverFrameGeometry.setX (xwc.x);
 
796
 
 
797
        if (serverFrameGeometry.y ()  == xwc.y)
 
798
            valueMask &= ~(CWY);
 
799
        else
 
800
            serverFrameGeometry.setY (xwc.y);
 
801
 
 
802
        if (serverFrameGeometry.width () == xwc.width)
 
803
            valueMask &= ~(CWWidth);
 
804
        else
 
805
            serverFrameGeometry.setWidth (xwc.width);
 
806
 
 
807
        if (serverFrameGeometry.height () == xwc.height)
 
808
            valueMask &= ~(CWHeight);
 
809
        else
 
810
            serverFrameGeometry.setHeight (xwc.height);
 
811
 
 
812
        addPendingConfigure (xwc, valueMask);
 
813
 
 
814
 
785
815
        /* Geometry is the same, so we're not going to get a ConfigureNotify
786
816
         * event when the window is configured, which means that other plugins
787
817
         * won't know that the client, frame and wrapper windows got shifted
788
818
         * around (and might result in display corruption, eg in OpenGL */
789
 
        if (geometry.x () - input.left == x &&
790
 
            geometry.y () - input.top  == y &&
791
 
            geometry.width () + input.left + input.right + bw == width &&
792
 
            geometry.height () + input.top + input.bottom + bw == height)
 
819
        if (valueMask == 0)
793
820
        {
794
821
            XConfigureEvent xev;
795
822
            XWindowAttributes attrib;
848
875
            XSync (screen->dpy (), false);
849
876
        }
850
877
        else
851
 
            XMoveResizeWindow (screen->dpy (), serverFrame, x, y, width, height);
852
 
 
 
878
            XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
853
879
        if (shaded)
854
880
        {
855
881
            XUnmapWindow (screen->dpy (), wrapper);
867
893
    }
868
894
    else
869
895
    {
870
 
        int        x, y, width, height;
871
896
        int        bw = serverGeometry.border () * 2;
872
897
 
873
 
        x      = serverGeometry.x ();
874
 
        y      = serverGeometry.y ();
875
 
        width  = serverGeometry.width () + bw;
876
 
        height = serverGeometry.height () + bw;
 
898
        xwc.x      = serverGeometry.x ();
 
899
        xwc.y      = serverGeometry.y ();
 
900
        xwc.width  = serverGeometry.width () + bw;
 
901
        xwc.height = serverGeometry.height () + bw;
877
902
 
878
903
        if (shaded)
879
904
            height = 0;
880
905
 
 
906
        if (serverFrameGeometry.x () == xwc.x)
 
907
            valueMask &= ~(CWX);
 
908
        else
 
909
            serverFrameGeometry.setX (xwc.x);
 
910
 
 
911
        if (serverFrameGeometry.y ()  == xwc.y)
 
912
            valueMask &= ~(CWY);
 
913
        else
 
914
            serverFrameGeometry.setY (xwc.y);
 
915
 
 
916
        if (serverFrameGeometry.width () == xwc.width)
 
917
            valueMask &= ~(CWWidth);
 
918
        else
 
919
            serverFrameGeometry.setWidth (xwc.width);
 
920
 
 
921
        if (serverFrameGeometry.height () == xwc.height)
 
922
            valueMask &= ~(CWHeight);
 
923
        else
 
924
            serverFrameGeometry.setHeight (xwc.height);
 
925
 
 
926
        addPendingConfigure (xwc, valueMask);
 
927
 
 
928
 
881
929
        /* Geometry is the same, so we're not going to get a ConfigureNotify
882
930
         * event when the window is configured, which means that other plugins
883
931
         * won't know that the client, frame and wrapper windows got shifted
884
932
         * around (and might result in display corruption, eg in OpenGL */
885
 
        if (geometry.x () - input.left == x &&
886
 
            geometry.y () - input.top  == y &&
887
 
            geometry.width () + input.left + input.right + bw == width &&
888
 
            geometry.height () + input.top + input.bottom + bw == height)
 
933
        if (valueMask == 0)
889
934
        {
890
935
            XConfigureEvent xev;
891
936
            XWindowAttributes attrib;
944
989
            XSync (screen->dpy (), false);
945
990
        }
946
991
        else
947
 
            XMoveResizeWindow (screen->dpy (), serverFrame, x, y, width, height);
 
992
            XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
948
993
 
949
994
        if (shaded)
950
995
        {
1746
1791
        dx = gm.x () - priv->geometry.x ();
1747
1792
        dy = gm.y () - priv->geometry.y ();
1748
1793
 
1749
 
        move (dx, dy);
 
1794
        priv->geometry.setX (gm.x ());
 
1795
        priv->geometry.setY (gm.y ());
 
1796
 
 
1797
        priv->region.translate (dx, dy);
 
1798
        priv->inputRegion.translate (dx, dy);
 
1799
        if (!priv->frameRegion.isEmpty ())
 
1800
            priv->frameRegion.translate (dx, dy);
 
1801
 
 
1802
        priv->invisible = WINDOW_INVISIBLE (priv);
 
1803
 
 
1804
        moveNotify (dx, dy, true);
1750
1805
    }
1751
1806
 
1752
1807
    updateFrameRegion ();
1875
1930
void
1876
1931
PrivateWindow::configure (XConfigureEvent *ce)
1877
1932
{
 
1933
    unsigned int valueMask = 0;
 
1934
 
1878
1935
    if (priv->frame)
1879
1936
        return;
1880
1937
 
 
1938
    /* remove configure event from pending configures */
 
1939
    if (priv->geometry.x () != ce->x)
 
1940
        valueMask |= CWX;
 
1941
 
 
1942
    if (priv->geometry.y () != ce->y)
 
1943
        valueMask |= CWY;
 
1944
 
 
1945
    if (priv->geometry.width () != ce->width)
 
1946
        valueMask |= CWWidth;
 
1947
 
 
1948
    if (priv->geometry.height () != ce->height)
 
1949
        valueMask |= CWHeight;
 
1950
 
 
1951
    if (priv->geometry.border () != ce->border_width)
 
1952
        valueMask |= CWBorderWidth;
 
1953
 
 
1954
    if (ROOTPARENT (window->prev) != ce->above)
 
1955
        valueMask |= CWSibling | CWStackMode;
 
1956
 
1881
1957
    priv->attrib.override_redirect = ce->override_redirect;
1882
1958
 
 
1959
    priv->frameGeometry.set (ce->x, ce->y, ce->width,
 
1960
                             ce->height, ce->border_width);
 
1961
 
1883
1962
    if (priv->syncWait)
1884
1963
        priv->syncGeometry.set (ce->x, ce->y, ce->width, ce->height,
1885
1964
                                ce->border_width);
1903
1982
{
1904
1983
    int x, y, width, height;
1905
1984
    CompWindow       *above;
 
1985
    unsigned int     valueMask = 0;
 
1986
    bool             handled = false;
1906
1987
 
1907
1988
    if (!priv->frame)
1908
1989
        return;
1909
1990
 
 
1991
    /* remove configure event from pending configures */
 
1992
    if (priv->frameGeometry.x () != ce->x)
 
1993
        valueMask |= CWX;
 
1994
 
 
1995
    if (priv->frameGeometry.y () != ce->y)
 
1996
        valueMask |= CWY;
 
1997
 
 
1998
    if (priv->frameGeometry.width () != ce->width)
 
1999
        valueMask |= CWWidth;
 
2000
 
 
2001
    if (priv->frameGeometry.height () != ce->height)
 
2002
        valueMask |= CWHeight;
 
2003
 
 
2004
    if (priv->frameGeometry.border () != ce->border_width)
 
2005
        valueMask |= CWBorderWidth;
 
2006
 
 
2007
    if (ROOTPARENT (window->prev) != ce->above)
 
2008
        valueMask |= CWSibling | CWStackMode;
 
2009
 
 
2010
    for (std::list <XWCValueMask>::iterator it = pendingConfigures.begin ();
 
2011
         it != pendingConfigures.end (); it++)
 
2012
    {
 
2013
        XWCValueMask &xwcvm = (*it);
 
2014
 
 
2015
 
 
2016
        if (xwcvm.second != valueMask)
 
2017
        {
 
2018
            /* For stacking cases, if a client wants to raise or lower a window
 
2019
             * then they don't need to specify CWSibling, so allow that to be
 
2020
             * excluded in those cases */
 
2021
 
 
2022
            if (ce->above == ROOTPARENT (screen->windows ().back ()) ||
 
2023
                ce->above == 0)
 
2024
            {
 
2025
                if ((xwcvm.second & ~(CWSibling)) != valueMask)
 
2026
                    continue;
 
2027
            }
 
2028
            else
 
2029
                continue;
 
2030
        }
 
2031
 
 
2032
        if (xwcvm.second & CWX && xwcvm.first.x != ce->x)
 
2033
            continue;
 
2034
 
 
2035
        if (xwcvm.second & CWY && xwcvm.first.y != ce->y)
 
2036
            continue;
 
2037
 
 
2038
        if (xwcvm.second & CWWidth && xwcvm.first.width != ce->width)
 
2039
            continue;
 
2040
 
 
2041
        if (xwcvm.second & CWHeight && xwcvm.first.height != ce->height)
 
2042
            continue;
 
2043
 
 
2044
        if (xwcvm.second & (CWStackMode | CWSibling) && xwcvm.first.sibling != ce->above)
 
2045
            continue;
 
2046
 
 
2047
        /* Matched ConfigureWindow request to ConfigureNotify event
 
2048
         * remove it from the list */
 
2049
 
 
2050
        handled = true;
 
2051
 
 
2052
        pendingConfigures.erase (it);
 
2053
        break;
 
2054
    }
 
2055
 
 
2056
    if (!handled)
 
2057
    {
 
2058
        compLogMessage ("core", CompLogLevelWarn, "unhandled ConfigureNotify on 0x%x!", serverFrame);
 
2059
        compLogMessage ("core", CompLogLevelWarn, "this should never happen. you should"\
 
2060
                                                  "probably file a bug about this.");
 
2061
#ifdef DEBUG
 
2062
        abort ();
 
2063
#else
 
2064
        pendingConfigures.clear ();
 
2065
#endif
 
2066
    }
 
2067
 
1910
2068
    /* subtract the input extents last sent to the
1911
2069
     * server to calculate the client size and then
1912
2070
     * re-sync the input extents and extents last
1917
2075
    width  = ce->width - priv->serverGeometry.border () * 2 - priv->serverInput.left - priv->serverInput.right;
1918
2076
    height = ce->height - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
1919
2077
 
 
2078
    /* set the frame geometry */
 
2079
    priv->frameGeometry.set (ce->x, ce->y, ce->width, ce->height, ce->border_width);
 
2080
 
 
2081
 
1920
2082
    if (priv->syncWait)
1921
 
    {
1922
2083
        priv->syncGeometry.set (x, y, width, height, ce->border_width);
1923
 
    }
1924
2084
    else
1925
 
    {
1926
 
        if (ce->override_redirect)
1927
 
        {
1928
 
            priv->serverGeometry.set (x, y, width, height, ce->border_width);
1929
 
        }
1930
 
 
1931
2085
        window->resize (x, y, width, height, ce->border_width);
1932
 
    }
1933
2086
 
1934
2087
    if (priv->restack (ce->above))
1935
2088
        priv->updatePassiveButtonGrabs ();
1938
2091
 
1939
2092
    if (above)
1940
2093
        above->priv->updatePassiveButtonGrabs ();
 
2094
 
 
2095
    if (pendingConfigures.empty ())
 
2096
    {
 
2097
        /* Tell plugins its ok to start doing stupid things again but
 
2098
         * obviously FIXME */
 
2099
        CompOption::Vector options;
 
2100
        CompOption::Value  v;
 
2101
 
 
2102
        options.push_back (CompOption ("window", CompOption::TypeInt));
 
2103
        v.set ((int) id);
 
2104
        options.back ().set (v);
 
2105
        options.push_back (CompOption ("active", CompOption::TypeInt));
 
2106
        v.set ((int) 0);
 
2107
        options.back ().set (v);
 
2108
 
 
2109
        /* Notify other plugins that it is unsafe to change geometry or serverGeometry
 
2110
         * FIXME: That API should not be accessible to plugins, this is a hack to avoid
 
2111
         * breaking ABI */
 
2112
 
 
2113
        screen->handleCompizEvent ("core", "lock_position", options);
 
2114
    }
1941
2115
}
1942
2116
 
1943
2117
void
1960
2134
{
1961
2135
    if (dx || dy)
1962
2136
    {
1963
 
        /*
1964
 
        priv->attrib.x += dx;
1965
 
        priv->attrib.y += dy;
1966
 
        */
1967
 
        priv->geometry.setX (priv->geometry.x () + dx);
1968
 
        priv->geometry.setY (priv->geometry.y () + dy);
1969
 
 
1970
 
        priv->region.translate (dx, dy);
1971
 
        priv->inputRegion.translate (dx, dy);
1972
 
        if (!priv->frameRegion.isEmpty ())
1973
 
            priv->frameRegion.translate (dx, dy);
1974
 
 
1975
 
        priv->invisible = WINDOW_INVISIBLE (priv);
1976
 
 
1977
 
        moveNotify (dx, dy, immediate);
 
2137
        /* Don't allow window movement to overwrite working geometries
 
2138
         * last received from the server if we know there are pending
 
2139
         * ConfigureNotify events on this window. That's a clunky workaround
 
2140
         * and a FIXME in any case, however, until we can break the API
 
2141
         * and remove CompWindow::move, this will need to be the case */
 
2142
 
 
2143
        if (!priv->pendingConfigures.size ())
 
2144
        {
 
2145
            priv->geometry.setX (priv->geometry.x () + dx);
 
2146
            priv->geometry.setY (priv->geometry.y () + dy);
 
2147
            priv->frameGeometry.setX (priv->frameGeometry.x () + dx);
 
2148
            priv->frameGeometry.setY (priv->frameGeometry.y () + dy);
 
2149
 
 
2150
            priv->pendingPositionUpdates = true;
 
2151
 
 
2152
            priv->region.translate (dx, dy);
 
2153
            priv->inputRegion.translate (dx, dy);
 
2154
            if (!priv->frameRegion.isEmpty ())
 
2155
                priv->frameRegion.translate (dx, dy);
 
2156
 
 
2157
            priv->invisible = WINDOW_INVISIBLE (priv);
 
2158
 
 
2159
            moveNotify (dx, dy, immediate);
 
2160
        }
 
2161
        else
 
2162
        {
 
2163
            XWindowChanges xwc;
 
2164
            unsigned int   valueMask = CWX | CWY;
 
2165
            struct timeval tv, old;
 
2166
            compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x,"\
 
2167
                            "moving window asyncrhonously!", (unsigned int) priv->serverId);
 
2168
 
 
2169
            old = priv->lastConfigureRequest;
 
2170
            gettimeofday (&tv, NULL);
 
2171
 
 
2172
            xwc.x = priv->serverGeometry.x () + dx;
 
2173
            xwc.y = priv->serverGeometry.y () + dy;
 
2174
 
 
2175
            configureXWindow (valueMask, &xwc);
 
2176
 
 
2177
            priv->lastConfigureRequest = old;
 
2178
 
 
2179
            /* FIXME: This is a hack to avoid performance regressions
 
2180
             * and must be removed in 0.9.6 */
 
2181
            if (tv.tv_usec - priv->lastConfigureRequest.tv_usec > 30000)
 
2182
            {
 
2183
                compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event from request at %i (now: %i)\n",
 
2184
                                priv->lastConfigureRequest.tv_usec, tv.tv_usec);
 
2185
                priv->pendingConfigures.clear ();
 
2186
            }
 
2187
        }
1978
2188
    }
1979
2189
}
1980
2190
 
1981
2191
void
 
2192
PrivateWindow::addPendingConfigure (XWindowChanges &xwc, unsigned int valueMask)
 
2193
{
 
2194
    CompOption::Vector options;
 
2195
    CompOption::Value  v;
 
2196
 
 
2197
    options.push_back (CompOption ("window", CompOption::TypeInt));
 
2198
    v.set ((int) id);
 
2199
    options.back ().set (v);
 
2200
    options.push_back (CompOption ("active", CompOption::TypeInt));
 
2201
    v.set ((int) 1);
 
2202
    options.back ().set (v);
 
2203
 
 
2204
    gettimeofday (&lastConfigureRequest, NULL);
 
2205
 
 
2206
    /* Notify other plugins that it is unsafe to change geometry or serverGeometry
 
2207
     * FIXME: That API should not be accessible to plugins, this is a hack to avoid
 
2208
     * breaking ABI */
 
2209
 
 
2210
    screen->handleCompizEvent ("core", "lock_position", options);
 
2211
 
 
2212
    priv->pendingConfigures.push_back (XWCValueMask (xwc, valueMask));
 
2213
}
 
2214
 
 
2215
void
1982
2216
CompWindow::syncPosition ()
1983
2217
{
1984
 
    priv->serverGeometry.setX (priv->geometry.x ());
1985
 
    priv->serverGeometry.setY (priv->geometry.y ());
1986
 
 
1987
 
    XMoveWindow (screen->dpy (), ROOTPARENT (this),
1988
 
                 priv->serverGeometry.x () - priv->serverInput.left,
1989
 
                 priv->serverGeometry.y () - priv->serverInput.top);
1990
 
 
1991
 
    if (priv->serverFrame)
 
2218
    unsigned int   valueMask = CWX | CWY;
 
2219
    XWindowChanges xwc;
 
2220
 
 
2221
    if (priv->pendingPositionUpdates && priv->pendingConfigures.empty ())
1992
2222
    {
1993
 
        XMoveWindow (screen->dpy (), priv->wrapper,
1994
 
                     priv->serverInput.left, priv->serverInput.top);
1995
 
        sendConfigureNotify ();
 
2223
        if (priv->serverFrameGeometry.x () == priv->frameGeometry.x ())
 
2224
            valueMask &= ~(CWX);
 
2225
        if (priv->serverFrameGeometry.y () == priv->frameGeometry.y ())
 
2226
            valueMask &= ~(CWY);
 
2227
 
 
2228
        /* Because CompWindow::move can update the geometry last
 
2229
         * received from the server, we must indicate that no values
 
2230
         * changed, because when the ConfigureNotify comes around
 
2231
         * the values are going to be the same. That's obviously
 
2232
         * broken behaviour and worthy of a FIXME, but requires
 
2233
         * larger changes to the window movement system. */
 
2234
        if (valueMask)
 
2235
        {
 
2236
            priv->addPendingConfigure (xwc, 0);
 
2237
 
 
2238
            priv->serverGeometry.setX (priv->geometry.x ());
 
2239
            priv->serverGeometry.setY (priv->geometry.y ());
 
2240
            priv->serverFrameGeometry.setX (priv->frameGeometry.x ());
 
2241
            priv->serverFrameGeometry.setY (priv->frameGeometry.y ());
 
2242
 
 
2243
            xwc.x = priv->serverFrameGeometry.x ();
 
2244
            xwc.y = priv->serverFrameGeometry.y ();
 
2245
 
 
2246
            XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
 
2247
 
 
2248
            if (priv->serverFrame)
 
2249
            {
 
2250
                XMoveWindow (screen->dpy (), priv->wrapper,
 
2251
                             priv->serverInput.left, priv->serverInput.top);
 
2252
                sendConfigureNotify ();
 
2253
            }
 
2254
        }
 
2255
        priv->pendingPositionUpdates = false;
1996
2256
    }
1997
2257
}
1998
2258
 
2145
2405
        vp = defaultViewport ();
2146
2406
        if (screen->vp () != vp)
2147
2407
        {
2148
 
            int moveX = (screen->vp ().x () - vp.x ()) * screen->width ();
2149
 
            int moveY = (screen->vp ().y () - vp.y ()) * screen->height ();
2150
 
 
2151
 
            move (moveX, moveY, TRUE);
2152
 
            syncPosition ();
 
2408
            unsigned int valueMask = CWX | CWY;
 
2409
            XWindowChanges xwc;
 
2410
 
 
2411
            xwc.x = serverGeometry ().x () +  (screen->vp ().x () - vp.x ()) * screen->width ();
 
2412
            xwc.y = serverGeometry ().y () +  (screen->vp ().y () - vp.y ()) * screen->height ();
 
2413
 
 
2414
            configureXWindow (valueMask, &xwc);
2153
2415
        }
2154
2416
    }
2155
2417
}
2450
2712
                                 bool       aboveFs)
2451
2713
{
2452
2714
    CompWindow   *below;
 
2715
    CompWindow   *t = screen->findWindow (w->transientFor ());
2453
2716
    Window       clientLeader = w->priv->clientLeader;
2454
2717
    unsigned int type = w->priv->type;
2455
2718
    unsigned int belowMask;
2464
2727
        (w->priv->state & CompWindowStateBelowMask))
2465
2728
        type = CompWindowTypeNormalMask;
2466
2729
 
 
2730
    while (t && type != CompWindowTypeDockMask)
 
2731
    {
 
2732
        /* dock stacking of transients for docks */
 
2733
        if (t->type () & CompWindowTypeDockMask)
 
2734
            type = CompWindowTypeDockMask;
 
2735
 
 
2736
        t = screen->findWindow (t->transientFor ());
 
2737
    }
 
2738
 
2467
2739
    if (w->priv->transientFor || w->priv->isGroupTransient (clientLeader))
2468
2740
        clientLeader = None;
2469
2741
 
2499
2771
            }
2500
2772
            break;
2501
2773
        default:
 
2774
        {
 
2775
            bool allowedRelativeToLayer = !(below->priv->type & belowMask);
 
2776
 
 
2777
            t = screen->findWindow (below->transientFor ());
 
2778
 
 
2779
            while (t && allowedRelativeToLayer)
 
2780
            {
 
2781
                /* dock stacking of transients for docks */
 
2782
                allowedRelativeToLayer = !(t->priv->type & belowMask);
 
2783
 
 
2784
                t = screen->findWindow (t->transientFor ());
 
2785
            }
 
2786
 
2502
2787
            /* fullscreen and normal layer */
2503
 
            if (!(below->priv->type & belowMask))
 
2788
            if (allowedRelativeToLayer)
2504
2789
            {
2505
2790
                if (stackLayerCheck (w, clientLeader, below))
2506
2791
                    return below;
2507
2792
            }
2508
2793
            break;
2509
2794
        }
 
2795
        }
2510
2796
    }
2511
2797
 
2512
2798
    return NULL;
2518
2804
PrivateWindow::findLowestSiblingBelow (CompWindow *w)
2519
2805
{
2520
2806
    CompWindow   *below, *lowest = screen->serverWindows ().back ();
 
2807
    CompWindow   *t = screen->findWindow (w->transientFor ());
2521
2808
    Window       clientLeader = w->priv->clientLeader;
2522
2809
    unsigned int type = w->priv->type;
2523
2810
 
2526
2813
        (w->priv->state & CompWindowStateBelowMask))
2527
2814
        type = CompWindowTypeNormalMask;
2528
2815
 
 
2816
    while (t && type != CompWindowTypeDockMask)
 
2817
    {
 
2818
        /* dock stacking of transients for docks */
 
2819
        if (t->type () & CompWindowTypeDockMask)
 
2820
            type = CompWindowTypeDockMask;
 
2821
 
 
2822
        t = screen->findWindow (t->transientFor ());
 
2823
    }
 
2824
 
 
2825
 
2529
2826
    if (w->priv->transientFor || w->priv->isGroupTransient (clientLeader))
2530
2827
        clientLeader = None;
2531
2828
 
2560
2857
            }
2561
2858
            break;
2562
2859
        default:
 
2860
        {
 
2861
            bool allowedRelativeToLayer = !(below->priv->type & CompWindowTypeDockMask);
 
2862
 
 
2863
            t = screen->findWindow (below->transientFor ());
 
2864
 
 
2865
            while (t && allowedRelativeToLayer)
 
2866
            {
 
2867
                /* dock stacking of transients for docks */
 
2868
                allowedRelativeToLayer = !(t->priv->type & CompWindowTypeDockMask);
 
2869
 
 
2870
                t = screen->findWindow (t->transientFor ());
 
2871
            }
 
2872
 
2563
2873
            /* fullscreen and normal layer */
2564
 
            if (!(below->priv->type & CompWindowTypeDockMask))
 
2874
            if (allowedRelativeToLayer)
2565
2875
            {
2566
2876
                if (!stackLayerCheck (below, clientLeader, w))
2567
2877
                    return lowest;
2568
2878
            }
2569
2879
            break;
2570
2880
        }
 
2881
        }
2571
2882
 
2572
2883
        lowest = below;
2573
2884
    }
2579
2890
PrivateWindow::validSiblingBelow (CompWindow *w,
2580
2891
                                  CompWindow *sibling)
2581
2892
{
 
2893
    CompWindow   *t = screen->findWindow (w->transientFor ());
2582
2894
    Window       clientLeader = w->priv->clientLeader;
2583
2895
    unsigned int type = w->priv->type;
2584
2896
 
2587
2899
        (w->priv->state & CompWindowStateBelowMask))
2588
2900
        type = CompWindowTypeNormalMask;
2589
2901
 
 
2902
    while (t && type != CompWindowTypeDockMask)
 
2903
    {
 
2904
        /* dock stacking of transients for docks */
 
2905
        if (t->type () & CompWindowTypeDockMask)
 
2906
            type = CompWindowTypeDockMask;
 
2907
 
 
2908
        t = screen->findWindow (t->transientFor ());
 
2909
    }
 
2910
 
 
2911
 
2590
2912
    if (w->priv->transientFor || w->priv->isGroupTransient (clientLeader))
2591
2913
        clientLeader = None;
2592
2914
 
2616
2938
        }
2617
2939
        break;
2618
2940
    default:
 
2941
    {
 
2942
        bool allowedRelativeToLayer = !(sibling->priv->type & CompWindowTypeDockMask);
 
2943
 
 
2944
        t = screen->findWindow (sibling->transientFor ());
 
2945
 
 
2946
        while (t && allowedRelativeToLayer)
 
2947
        {
 
2948
            /* dock stacking of transients for docks */
 
2949
            allowedRelativeToLayer = !(t->priv->type & CompWindowTypeDockMask);
 
2950
 
 
2951
            t = screen->findWindow (t->transientFor ());
 
2952
        }
 
2953
 
2619
2954
        /* fullscreen and normal layer */
2620
 
        if (!(sibling->priv->type & CompWindowTypeDockMask))
 
2955
        if (allowedRelativeToLayer)
2621
2956
        {
2622
2957
            if (stackLayerCheck (w, clientLeader, sibling))
2623
2958
                return true;
2624
2959
        }
2625
2960
        break;
2626
2961
    }
 
2962
    }
2627
2963
 
2628
2964
    return false;
2629
2965
}
2709
3045
PrivateWindow::reconfigureXWindow (unsigned int   valueMask,
2710
3046
                                   XWindowChanges *xwc)
2711
3047
{
 
3048
    unsigned int frameValueMask = valueMask;
 
3049
 
 
3050
    /* Immediately sync window position
 
3051
     * if plugins were updating w->geometry () directly
 
3052
     * in order to avoid a race condition */
 
3053
 
 
3054
    window->syncPosition ();
 
3055
 
 
3056
    /* Remove redundant bits */
 
3057
 
 
3058
    if (serverGeometry.x () == xwc->x)
 
3059
        valueMask &= ~(CWX);
 
3060
 
 
3061
    if (serverGeometry.y () == xwc->y)
 
3062
        valueMask &= ~(CWY);
 
3063
 
 
3064
    if (serverGeometry.width () == xwc->width)
 
3065
        valueMask &= ~(CWWidth);
 
3066
 
 
3067
    if (serverGeometry.height () == xwc->height)
 
3068
        valueMask &= ~(CWHeight);
 
3069
 
 
3070
    if (serverGeometry.border () == xwc->border_width)
 
3071
        valueMask &= ~(CWBorderWidth);
 
3072
 
 
3073
    if (window->serverPrev && ROOTPARENT (window->serverPrev) == xwc->sibling)
 
3074
    {
 
3075
        /* check if the sibling is also pending a restack,
 
3076
         * if not, then setting this bit is useless */
 
3077
 
 
3078
        bool pendingRestack = false;
 
3079
 
 
3080
        foreach (XWCValueMask &xwcvm, window->serverPrev->priv->pendingConfigures)
 
3081
        {
 
3082
            if (xwcvm.second & (CWSibling | CWStackMode))
 
3083
            {
 
3084
                pendingRestack = true;
 
3085
                break;
 
3086
            }
 
3087
        }
 
3088
 
 
3089
        if (!pendingRestack)
 
3090
            valueMask &= ~(CWSibling | CWStackMode);
 
3091
    }
 
3092
 
 
3093
    if (valueMask & CWBorderWidth)
 
3094
        serverGeometry.setBorder (xwc->border_width);
 
3095
 
2712
3096
    if (valueMask & CWX)
2713
3097
        serverGeometry.setX (xwc->x);
2714
3098
 
2721
3105
    if (valueMask & CWHeight)
2722
3106
        serverGeometry.setHeight (xwc->height);
2723
3107
 
2724
 
    if (valueMask & CWBorderWidth)
2725
 
        serverGeometry.setBorder (xwc->border_width);
2726
 
 
2727
3108
    /* Update the server side window list on raise, lower and restack functions.
2728
3109
     * This function should only recieve stack_mode == Above
2729
3110
     * but warn incase something else does get through, to make the cause
2734
3115
        {
2735
3116
            if (xwc->sibling)
2736
3117
            {
2737
 
                CompWindow *w = screen->findWindow (id);
2738
 
 
2739
 
                screen->unhookServerWindow (w);
2740
 
                screen->insertServerWindow (w, xwc->sibling);
 
3118
                screen->unhookServerWindow (window);
 
3119
                screen->insertServerWindow (window, xwc->sibling);
2741
3120
            }
2742
3121
        }
2743
3122
        else
2744
3123
            compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
2745
3124
    }
2746
3125
 
 
3126
    if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
 
3127
        frameValueMask &= ~(CWX);
 
3128
 
 
3129
    if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
 
3130
        frameValueMask &= ~(CWY);
 
3131
 
 
3132
   if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
 
3133
                                      + serverInput.left + serverInput.right)
 
3134
        frameValueMask &= ~(CWWidth);
 
3135
 
 
3136
    if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
 
3137
                                      + serverInput.top + serverInput.bottom)
 
3138
        frameValueMask &= ~(CWHeight);
 
3139
 
 
3140
    /* Can't set the border width of frame windows */
 
3141
    frameValueMask &= ~(CWBorderWidth);
 
3142
 
 
3143
    if (frameValueMask & CWX)
 
3144
        serverFrameGeometry.setX (xwc->x - serverGeometry.border () - serverInput.left);
 
3145
 
 
3146
    if (frameValueMask & CWY)
 
3147
        serverFrameGeometry.setY (xwc->y -serverGeometry.border () - serverInput.top);
 
3148
 
 
3149
    if (frameValueMask & CWWidth)
 
3150
        serverFrameGeometry.setWidth (xwc->width + serverGeometry.border () * 2
 
3151
                                      + serverInput.left + serverInput.right);
 
3152
 
 
3153
    if (frameValueMask & CWHeight)
 
3154
        serverFrameGeometry.setHeight (xwc->height + serverGeometry.border () * 2
 
3155
                                      + serverInput.top + serverInput.bottom);
 
3156
 
 
3157
 
2747
3158
    if (serverFrame)
2748
3159
    {
2749
 
        XWindowChanges wc = *xwc;
2750
 
 
2751
 
        wc.x      -= serverInput.left - serverGeometry.border ();
2752
 
        wc.y      -= serverInput.top - serverGeometry.border ();
2753
 
        wc.width  += serverInput.left + serverInput.right + serverGeometry.border ();
2754
 
        wc.height += serverInput.top + serverInput.bottom + serverGeometry.border ();
2755
 
 
2756
 
        XConfigureWindow (screen->dpy (), serverFrame, valueMask, &wc);
 
3160
        if (frameValueMask)
 
3161
        {
 
3162
            XWindowChanges wc = *xwc;
 
3163
 
 
3164
            wc.x      = serverFrameGeometry.x ();
 
3165
            wc.y      = serverFrameGeometry.y ();
 
3166
            wc.width  = serverFrameGeometry.width ();
 
3167
            wc.height = serverFrameGeometry.height ();
 
3168
 
 
3169
            addPendingConfigure (wc, frameValueMask);
 
3170
 
 
3171
            XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
 
3172
        }
2757
3173
        valueMask &= ~(CWSibling | CWStackMode);
2758
3174
 
2759
 
        xwc->x = serverInput.left;
2760
 
        xwc->y = serverInput.top;
2761
 
        XConfigureWindow (screen->dpy (), wrapper, valueMask, xwc);
 
3175
        if (valueMask)
 
3176
        {
 
3177
            xwc->x = serverInput.left;
 
3178
            xwc->y = serverInput.top;
 
3179
            XConfigureWindow (screen->dpy (), wrapper, valueMask, xwc);
2762
3180
 
2763
 
        xwc->x = 0;
2764
 
        xwc->y = 0;
 
3181
            xwc->x = 0;
 
3182
            xwc->y = 0;
 
3183
        }
2765
3184
 
2766
3185
        window->sendConfigureNotify ();
2767
3186
    }
2768
3187
 
2769
 
    XConfigureWindow (screen->dpy (), id, valueMask, xwc);
 
3188
    if (valueMask)
 
3189
        XConfigureWindow (screen->dpy (), id, valueMask, xwc);
2770
3190
}
2771
3191
 
2772
3192
bool
2853
3273
        if (t->priv->transientFor == w->priv->id ||
2854
3274
            t->priv->isGroupTransient (clientLeader))
2855
3275
        {
2856
 
            if (w->priv->type & CompWindowTypeDockMask)
2857
 
                if (!(t->priv->type & CompWindowTypeDockMask))
2858
 
                    return false;
2859
 
 
2860
3276
            if (!stackTransients (t, avoid, xwc, updateList))
2861
3277
                return false;
2862
3278
 
3432
3848
         * if serverPrev was recently restacked */
3433
3849
        if (window->serverPrev)
3434
3850
        {
3435
 
            if (!sibling)
3436
 
            {
3437
 
                XLowerWindow (screen->dpy (), ROOTPARENT (window));
 
3851
            bool pendingRestacks = false;
 
3852
 
 
3853
            foreach (XWCValueMask &xwcvm, sibling->priv->pendingConfigures)
 
3854
            {
 
3855
                if (xwcvm.second & (CWSibling | CWStackMode))
 
3856
                {
 
3857
                    pendingRestacks = true;
 
3858
                    break;
 
3859
                }
 
3860
            }
 
3861
 
 
3862
            if (!sibling && window->serverPrev)
 
3863
            {
 
3864
                XWindowChanges xwc;
 
3865
                unsigned int   valueMask = CWStackMode;
 
3866
 
 
3867
                xwc.stack_mode = Below;
 
3868
 
 
3869
                /* Below with no sibling puts the window at the bottom
 
3870
                 * of the stack */
 
3871
                XConfigureWindow (screen->dpy (), ROOTPARENT (window), valueMask, &xwc);
 
3872
 
 
3873
                if (serverFrame)
 
3874
                    priv->addPendingConfigure (xwc, CWStackMode);
3438
3875
 
3439
3876
                /* Update the list of windows last sent to the server */
3440
3877
                screen->unhookServerWindow (window);
3441
3878
                screen->insertServerWindow (window, 0);
3442
3879
            }
3443
3880
            else if (sibling->priv->id != window->serverPrev->priv->id ||
3444
 
                     (window->serverPrev->serverPrev != window->serverPrev->prev ||
3445
 
                      window->serverPrev->serverNext != window->serverPrev->next))
 
3881
                     pendingRestacks)
3446
3882
            {
3447
3883
                mask |= CWSibling | CWStackMode;
3448
3884
 
4961
5397
 
4962
5398
    screen->priv->applyStartupProperties (window);
4963
5399
 
4964
 
    if (!serverFrame)
 
5400
    initiallyMinimized = (priv->hints &&
 
5401
                          priv->hints->initial_state == IconicState &&
 
5402
                          !window->minimized ());
 
5403
 
 
5404
    if (!serverFrame && !initiallyMinimized)
4965
5405
        reparent ();
4966
5406
 
4967
5407
    priv->managed = true;
4996
5436
        priv->placed = true;
4997
5437
    }
4998
5438
 
4999
 
    initiallyMinimized = (priv->hints &&
5000
 
                          priv->hints->initial_state == IconicState &&
5001
 
                          !window->minimized ());
5002
5439
    allowFocus = allowWindowFocus (NO_FOCUS_MASK, 0);
5003
5440
 
5004
5441
    if (!allowFocus && (priv->type & ~NO_FOCUS_MASK))
5011
5448
    if (window->minimized () && !initiallyMinimized)
5012
5449
        window->unminimize ();
5013
5450
 
 
5451
    screen->leaveShowDesktopMode (window);
 
5452
 
5014
5453
    if (!initiallyMinimized)
5015
5454
    {
5016
5455
        if (allowFocus && !window->onCurrentDesktop ());
5030
5469
    {
5031
5470
        window->minimize ();
5032
5471
        window->changeState (window->state () | CompWindowStateHiddenMask);
5033
 
        screen->priv->updateClientList ();
5034
5472
    }
5035
5473
 
5036
 
    screen->leaveShowDesktopMode (window);
5037
 
 
5038
 
    if (!(priv->state & CompWindowStateHiddenMask))
5039
 
        show ();
 
5474
    screen->priv->updateClientList ();
5040
5475
}
5041
5476
 
5042
5477
/*
5083
5518
    {
5084
5519
        if (screen->priv->optionGetRaiseOnClick ())
5085
5520
        {
5086
 
            for (CompWindow *above = window->next;
5087
 
                above != NULL; above = above->next)
 
5521
            CompWindow *highestSibling =
 
5522
                    PrivateWindow::findSiblingBelow (window, true);
 
5523
 
 
5524
            /* Check if this window is permitted to be raised */
 
5525
            for (CompWindow *above = window->serverNext;
 
5526
                above != NULL; above = above->serverNext)
5088
5527
            {
5089
 
                if (above->priv->attrib.map_state != IsViewable)
5090
 
                    continue;
5091
 
 
5092
 
                if (above->type () & CompWindowTypeDockMask)
5093
 
                    continue;
5094
 
 
5095
 
                if (above->region ().intersects (region))
 
5528
                if (highestSibling == above)
5096
5529
                {
5097
5530
                    onlyActions = false;
5098
5531
                    break;
5120
5553
                XGrabButton (screen->priv->dpy,
5121
5554
                             bind.button,
5122
5555
                             mods | ignore,
5123
 
                             frame,
 
5556
                             serverFrame,
5124
5557
                             false,
5125
5558
                             ButtonPressMask | ButtonReleaseMask |
5126
5559
                                ButtonMotionMask,
5137
5570
        XGrabButton (screen->priv->dpy,
5138
5571
                     AnyButton,
5139
5572
                     AnyModifier,
5140
 
                     frame, false,
 
5573
                     serverFrame, false,
5141
5574
                     ButtonPressMask | ButtonReleaseMask | ButtonMotionMask,
5142
5575
                     GrabModeSync,
5143
5576
                     GrabModeAsync,
5269
5702
 
5270
5703
    if (tx || ty)
5271
5704
    {
 
5705
        unsigned int   valueMask = CWX | CWY;
 
5706
        XWindowChanges xwc;
5272
5707
        int m, wx, wy;
5273
5708
 
5274
5709
        if (!priv->managed)
5309
5744
        if (priv->saveMask & CWY)
5310
5745
            priv->saveWc.y += wy;
5311
5746
 
5312
 
        move (wx, wy);
 
5747
        xwc.x = serverGeometry ().x () + wx;
 
5748
        xwc.y = serverGeometry ().y () + wy;
5313
5749
 
5314
 
        if (sync)
5315
 
            syncPosition ();
 
5750
        configureXWindow (valueMask, &xwc);
5316
5751
    }
5317
5752
}
5318
5753
 
5518
5953
    if (dbg)
5519
5954
        dbg->overrideRedirectRestack (priv->id, aboveId);
5520
5955
 
 
5956
    gettimeofday (&priv->lastConfigureRequest, NULL);
 
5957
 
5521
5958
    priv->attrib = wa;
5522
5959
    priv->serverGeometry.set (priv->attrib.x, priv->attrib.y,
5523
5960
                              priv->attrib.width, priv->attrib.height,
5524
5961
                              priv->attrib.border_width);
5525
 
    priv->syncGeometry.set (priv->attrib.x, priv->attrib.y,
5526
 
                            priv->attrib.width, priv->attrib.height,
5527
 
                            priv->attrib.border_width);
5528
 
    priv->geometry.set (priv->attrib.x, priv->attrib.y,
5529
 
                        priv->attrib.width, priv->attrib.height,
5530
 
                        priv->attrib.border_width);
 
5962
    priv->serverFrameGeometry = priv->frameGeometry = priv->syncGeometry
 
5963
            = priv->geometry = priv->serverGeometry;
5531
5964
 
5532
5965
    priv->width  = priv->attrib.width  + priv->attrib.border_width * 2;
5533
5966
    priv->height = priv->attrib.height + priv->attrib.border_width * 2;
5839
6272
 
5840
6273
    pendingUnmaps (0),
5841
6274
    pendingMaps (0),
 
6275
    pendingPositionUpdates (false),
5842
6276
 
5843
6277
    startupId (0),
5844
6278
    resName (0),
6139
6573
    if (wa.override_redirect)
6140
6574
        return false;
6141
6575
 
 
6576
    XSelectInput (dpy, id, NoEventMask);
 
6577
 
6142
6578
    /* Don't ever reparent windows which have ended up
6143
6579
     * reparented themselves on the server side but not
6144
6580
     * on the client side */
6163
6599
    xwc.border_width = 0;
6164
6600
    XConfigureWindow (dpy, id, CWBorderWidth, &xwc);
6165
6601
 
6166
 
    mask = CWBorderPixel | CWColormap | CWBackPixmap;
 
6602
    priv->serverGeometry.setBorder (0);
 
6603
 
 
6604
    mask = CWBorderPixel | CWColormap | CWBackPixmap | CWOverrideRedirect;
6167
6605
 
6168
6606
    if (wa.depth == 32)
6169
6607
    {
6189
6627
         * problems with that */
6190
6628
 
6191
6629
        XDestroyWindow (dpy, (it->second)->id ());
6192
 
 
 
6630
        screen->priv->detachedFrameWindows.erase (it);
6193
6631
    }
6194
6632
 
6195
6633
    /* We need to know when the frame window is created
6281
6719
                      SubstructureNotifyMask | EnterWindowMask |
6282
6720
                      LeaveWindowMask;
6283
6721
 
 
6722
    serverFrameGeometry = serverGeometry;
 
6723
 
 
6724
    XMoveResizeWindow (dpy, serverFrame, serverFrameGeometry.x (), serverFrameGeometry.y (),
 
6725
                       serverFrameGeometry.width (), serverFrameGeometry.height ());
 
6726
 
 
6727
    XSelectInput (dpy, screen->root (),
 
6728
                  SubstructureRedirectMask |
 
6729
                  SubstructureNotifyMask   |
 
6730
                  StructureNotifyMask      |
 
6731
                  PropertyChangeMask       |
 
6732
                  LeaveWindowMask          |
 
6733
                  EnterWindowMask          |
 
6734
                  KeyPressMask             |
 
6735
                  KeyReleaseMask           |
 
6736
                  ButtonPressMask          |
 
6737
                  ButtonReleaseMask        |
 
6738
                  FocusChangeMask          |
 
6739
                  ExposureMask);
 
6740
 
6284
6741
    XChangeWindowAttributes (dpy, serverFrame, CWEventMask, &attr);
6285
6742
    XChangeWindowAttributes (dpy, wrapper, CWEventMask, &attr);
6286
6743
 
6287
 
    XSelectInput (dpy, screen->root (),
6288
 
                  SubstructureRedirectMask |
6289
 
                  SubstructureNotifyMask   |
6290
 
                  StructureNotifyMask      |
6291
 
                  PropertyChangeMask       |
6292
 
                  LeaveWindowMask          |
6293
 
                  EnterWindowMask          |
6294
 
                  KeyPressMask             |
6295
 
                  KeyReleaseMask           |
6296
 
                  ButtonPressMask          |
6297
 
                  ButtonReleaseMask        |
6298
 
                  FocusChangeMask          |
6299
 
                  ExposureMask);
6300
 
 
6301
6744
    XUngrabServer (dpy);
6302
6745
    XSync (dpy, false);
6303
6746
 
6304
 
    XMoveResizeWindow (dpy, serverFrame, wa.x, wa.y,
6305
 
                       wa.width, wa.height);
6306
 
 
6307
6747
    window->windowNotify (CompWindowNotifyReparent);
6308
6748
 
6309
6749
    return true;
6362
6802
        /* Wait for the reparent to finish */
6363
6803
        XSync (dpy, false);
6364
6804
 
 
6805
        xwc.x = serverGeometry.x () - serverGeometry.border ();
 
6806
        xwc.y = serverGeometry.y () - serverGeometry.border ();
 
6807
        xwc.width = serverGeometry.width () + serverGeometry.border () * 2;
 
6808
        xwc.height = serverGeometry.height () + serverGeometry.border () * 2;
 
6809
 
 
6810
        XConfigureWindow (dpy, serverFrame, CWX | CWY | CWWidth | CWHeight, &xwc);
 
6811
 
 
6812
 
6365
6813
        xwc.stack_mode = Below;
6366
6814
        xwc.sibling    = serverFrame;
6367
6815
        XConfigureWindow (dpy, id, CWSibling | CWStackMode, &xwc);
6440
6888
    XUnmapWindow (screen->dpy (), serverFrame);
6441
6889
    XDestroyWindow (screen->dpy (), wrapper);
6442
6890
 
6443
 
    window->windowNotify (CompWindowNotifyUnreparent);
6444
 
 
6445
6891
    frame = None;
6446
6892
    wrapper = None;
6447
6893
    serverFrame = None;
 
6894
 
 
6895
    window->windowNotify (CompWindowNotifyUnreparent);
6448
6896
}