~compiz-team/compiz/compiz.fix_1063617.6

« back to all changes in this revision

Viewing changes to src/window.cpp

  • Committer: Sam Spilsbury
  • Date: 2012-12-07 06:09:18 UTC
  • mfrom: (3480.6.33 0.9.9)
  • Revision ID: sam.spilsbury@canonical.com-20121207060918-3xoqgnnhcx6rz2gb
MergeĀ lp:compiz

Show diffs side-by-side

added added

removed removed

Lines of Context:
504
504
void
505
505
CompWindow::changeState (unsigned int newState)
506
506
{
507
 
    unsigned int oldState;
508
 
 
509
507
    if (priv->state == newState)
510
508
        return;
511
509
 
512
 
    oldState = priv->state;
 
510
    unsigned int oldState = priv->state;
513
511
    priv->state = newState;
514
512
 
515
513
    recalcType ();
807
805
void
808
806
PrivateWindow::updateFrameWindow ()
809
807
{
 
808
    if (!serverFrame)
 
809
        return;
 
810
 
810
811
    XWindowChanges xwc = XWINDOWCHANGES_INIT;
811
812
    unsigned int   valueMask = CWX | CWY | CWWidth | CWHeight;
812
813
 
813
 
    if (!serverFrame)
814
 
        return;
815
 
 
816
814
    xwc.x = serverGeometry.x ();
817
815
    xwc.y = serverGeometry.y ();
818
816
    xwc.width = serverGeometry.width ();
934
932
    if (nInput < 1)
935
933
    {
936
934
        inputShapeRects = &r;
937
 
        nBounding = 1;
 
935
        nInput = 1;
938
936
    }
939
937
 
940
938
    priv->region += rectsToRegion (nBounding, boundingShapeRects);
1270
1268
CompWindow::sendConfigureNotify ()
1271
1269
{
1272
1270
    XConfigureEvent xev;
1273
 
    XWindowAttributes attrib;
1274
 
    unsigned int      nchildren;
1275
 
    Window            rootRet, parentRet = 0;
1276
 
    Window            *children;
1277
1271
 
1278
1272
    xev.type   = ConfigureNotify;
1279
1273
    xev.event  = priv->id;
1280
1274
    xev.window = priv->id;
1281
1275
 
1282
 
    /* in order to avoid race conditions we must use the current
1283
 
     * server configuration */
1284
 
 
1285
 
    XGrabServer (screen->dpy ());
1286
 
    XSync (screen->dpy (), false);
1287
 
 
1288
 
    if (XGetWindowAttributes (screen->dpy (), priv->id, &attrib))
1289
 
    {
1290
 
        xev.x        = attrib.x;
1291
 
        xev.y        = attrib.y;
1292
 
        xev.width            = attrib.width;
1293
 
        xev.height           = attrib.height;
1294
 
        xev.border_width = attrib.border_width;
1295
 
        xev.above = None;
1296
 
 
1297
 
        /* Translate co-ordinates to root space */
1298
 
        XTranslateCoordinates (screen->dpy (), priv->id, screen->root (), 0, 0,
1299
 
                               &xev.x, &xev.y, &parentRet);
1300
 
 
1301
 
        /* We need to ensure that the stacking order is
1302
 
         * based on the current server stacking order so
1303
 
         * find the sibling to this window's frame in the
1304
 
         * server side stack and stack above that */
1305
 
        XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
1306
 
 
1307
 
        if (nchildren)
1308
 
        {
1309
 
            for (unsigned int i = 0; i < nchildren; i++)
1310
 
            {
1311
 
                if (i + 1 == nchildren ||
1312
 
                    children[i + 1] == ROOTPARENT (this))
1313
 
                {
1314
 
                    xev.above = children[i];
1315
 
                    break;
1316
 
                }
1317
 
            }
1318
 
        }
1319
 
 
1320
 
        if (children)
1321
 
            XFree (children);
1322
 
 
1323
 
        if (!xev.above)
1324
 
            xev.above             = (serverPrev) ? ROOTPARENT (serverPrev) : None;
1325
 
        xev.override_redirect = priv->attrib.override_redirect;
1326
 
 
1327
 
        XSendEvent (screen->dpy (), priv->id, false,
1328
 
                    StructureNotifyMask, (XEvent *) &xev);
1329
 
    }
1330
 
 
1331
 
    XUngrabServer (screen->dpy ());
1332
 
    XSync (screen->dpy (), false);
 
1276
    xev.x            = priv->serverGeometry.x ();
 
1277
    xev.y            = priv->serverGeometry.y ();
 
1278
    xev.width        = priv->serverGeometry.width ();
 
1279
    xev.height       = priv->serverGeometry.height ();
 
1280
    xev.border_width = priv->serverGeometry.border ();
 
1281
    xev.override_redirect = priv->attrib.override_redirect;
 
1282
 
 
1283
    /* These used to be based on the actual sibling of the window
 
1284
     * (eg, obtained using XQueryTree), but they are now zeroed out.
 
1285
     *
 
1286
     * The ICCCM is a big unclear on what these should be - it
 
1287
     * requires that after the client attempts to configure a window
 
1288
     * we should issue a synthetic ConfigureNotify to work around
 
1289
     * the change of co-ordinates due to reparenting:
 
1290
     *
 
1291
     * "A client will receive a synthetic ConfigureNotify event
 
1292
     *  following the change that describes the new geometry of the window"
 
1293
     *
 
1294
     * However there is an acknowledgement on stacking order:
 
1295
     *
 
1296
     * "Not changing the size, location, border width,
 
1297
     *  or stacking order of the window at all."
 
1298
     *
 
1299
     * Since there isn't any advice as to what to set the above and
 
1300
     * detail members, the only choices are to either grab the server
 
1301
     * and query it for the sibling to the window's parent, or to just
 
1302
     * set them to zero.
 
1303
     *
 
1304
     * An evaluation of other window managers showed that they just set
 
1305
     * these fields to zero. This is probably a safe option and justifies
 
1306
     * the potential performance tradeoff that we get out of not having
 
1307
     * to grab the server, query window attributes and children and
 
1308
     * translate co-ordinates every time a window is moved
 
1309
     */
 
1310
 
 
1311
    xev.above = None;
 
1312
 
 
1313
    XSendEvent (screen->dpy (), priv->id, false,
 
1314
                StructureNotifyMask, (XEvent *) &xev);
1333
1315
}
1334
1316
 
1335
1317
void
1716
1698
void
1717
1699
CompWindow::sendSyncRequest ()
1718
1700
{
 
1701
    if (priv->syncWait)
 
1702
        return;
 
1703
 
 
1704
    if (!priv->initializeSyncCounter ())
 
1705
        return;
 
1706
 
1719
1707
    XClientMessageEvent xev;
1720
1708
 
1721
 
    if (priv->syncWait)
1722
 
        return;
1723
 
 
1724
 
    if (!priv->initializeSyncCounter ())
1725
 
        return;
1726
 
 
1727
1709
    xev.type         = ClientMessage;
1728
1710
    xev.window       = priv->id;
1729
1711
    xev.message_type = Atoms::wmProtocols;
1748
1730
void
1749
1731
PrivateWindow::configure (XConfigureEvent *ce)
1750
1732
{
 
1733
    if (priv->frame)
 
1734
        return;
 
1735
 
1751
1736
    unsigned int valueMask = 0;
1752
1737
 
1753
 
    if (priv->frame)
1754
 
        return;
1755
 
 
1756
1738
    /* remove configure event from pending configures */
1757
1739
    if (priv->geometry.x () != ce->x)
1758
1740
        valueMask |= CWX;
1800
1782
void
1801
1783
PrivateWindow::configureFrame (XConfigureEvent *ce)
1802
1784
{
 
1785
    if (!priv->frame)
 
1786
        return;
 
1787
 
1803
1788
    int x, y, width, height;
1804
1789
    CompWindow       *above;
1805
1790
    unsigned int     valueMask = 0;
1806
1791
 
1807
 
    if (!priv->frame)
1808
 
        return;
1809
 
 
1810
1792
    /* remove configure event from pending configures */
1811
1793
    if (priv->frameGeometry.x () != ce->x)
1812
1794
        valueMask |= CWX;
2506
2488
    if (priv->id == screen->activeWindow () ||
2507
2489
        priv->id == screen->getNextActiveWindow())
2508
2490
    {
2509
 
        CompWindow *ancestor;
2510
2491
        CompWindow *nextActive = screen->findWindow (screen->getNextActiveWindow());
2511
2492
 
2512
2493
        /* Window pending focus */
2518
2499
        }
2519
2500
        else if (priv->transientFor && priv->transientFor != screen->root ())
2520
2501
        {
 
2502
            CompWindow *ancestor;
2521
2503
            ancestor = screen->findWindow (priv->transientFor);
2522
2504
            if (ancestor &&
2523
2505
                ancestor->focus () &&
2891
2873
void
2892
2874
PrivateWindow::saveGeometry (int mask)
2893
2875
{
2894
 
    int m = mask & ~saveMask;
2895
 
 
2896
2876
    /* only save geometry if window has been placed */
2897
2877
    if (!placed)
2898
2878
        return;
2899
2879
 
 
2880
    int m = mask & ~saveMask;
 
2881
 
2900
2882
    if (m & CWX)
2901
2883
        saveWc.x = serverGeometry.x ();
2902
2884
 
2983
2965
PrivateWindow::reconfigureXWindow (unsigned int   valueMask,
2984
2966
                                   XWindowChanges *xwc)
2985
2967
{
2986
 
    unsigned int frameValueMask = 0;
2987
 
 
2988
2968
    if (id == screen->root ())
2989
2969
    {
2990
2970
        compLogMessage ("core", CompLogLevelWarn, "attempted to reconfigure root window");
2991
2971
        return;
2992
2972
    }
2993
2973
 
 
2974
    unsigned int frameValueMask = 0;
 
2975
 
2994
2976
    /* Remove redundant bits */
2995
2977
 
2996
2978
    xwc->x = valueMask & CWX ? xwc->x : serverGeometry.x ();
3228
3210
            xwc->x = 0;
3229
3211
            xwc->y = 0;
3230
3212
        }
3231
 
 
3232
 
        window->sendConfigureNotify ();
3233
3213
    }
3234
3214
 
3235
3215
    if (valueMask)
3236
3216
        XConfigureWindow (screen->dpy (), id, valueMask, xwc);
3237
3217
 
 
3218
    /* Send the synthetic configure notify
 
3219
     * after the real configure notify arrives
 
3220
     * (ICCCM s4.1.5) */
 
3221
    if (serverFrame)
 
3222
        window->sendConfigureNotify ();
 
3223
 
3238
3224
    /* When updating plugins we care about
3239
3225
     * the absolute position */
3240
3226
    if (dx)
3950
3936
void
3951
3937
PrivateWindow::updateSize ()
3952
3938
{
3953
 
    XWindowChanges xwc = XWINDOWCHANGES_INIT;
3954
 
    int            mask;
3955
 
 
3956
3939
    if (window->overrideRedirect () || !managed)
3957
3940
        return;
3958
3941
 
3959
 
    mask = priv->addWindowSizeChanges (&xwc, priv->serverGeometry);
 
3942
    XWindowChanges xwc = XWINDOWCHANGES_INIT;
 
3943
 
 
3944
    int mask = priv->addWindowSizeChanges (&xwc, priv->serverGeometry);
3960
3945
    if (mask)
3961
3946
    {
3962
3947
        if (priv->mapNum && (mask & (CWWidth | CWHeight)))
4214
4199
void
4215
4200
CompWindow::updateAttributes (CompStackingUpdateMode stackingMode)
4216
4201
{
 
4202
    if (overrideRedirect () || !priv->managed)
 
4203
        return;
 
4204
 
4217
4205
    XWindowChanges xwc = XWINDOWCHANGES_INIT;
4218
4206
    int            mask = 0;
4219
4207
 
4220
 
    if (overrideRedirect () || !priv->managed)
4221
 
        return;
4222
 
 
4223
4208
    if (priv->state & CompWindowStateShadedMask && !priv->shaded)
4224
4209
    {
4225
4210
        windowNotify (CompWindowNotifyShade);
4297
4282
void
4298
4283
PrivateWindow::ensureWindowVisibility ()
4299
4284
{
4300
 
    int x1, y1, x2, y2;
4301
 
    int width = serverGeometry.widthIncBorders ();
4302
 
    int height = serverGeometry.heightIncBorders ();
4303
 
    int dx = 0;
4304
 
    int dy = 0;
4305
 
 
4306
4285
    if (struts || attrib.override_redirect)
4307
4286
        return;
4308
4287
 
4311
4290
                CompWindowTypeUnknownMask))
4312
4291
        return;
4313
4292
 
4314
 
    x1 = screen->workArea ().x () - screen->width () * screen->vp ().x ();
4315
 
    y1 = screen->workArea ().y () - screen->height () * screen->vp ().y ();
4316
 
    x2 = x1 + screen->workArea ().width () + screen->vpSize ().width () *
 
4293
    int x1 = screen->workArea ().x () - screen->width () * screen->vp ().x ();
 
4294
    int y1 = screen->workArea ().y () - screen->height () * screen->vp ().y ();
 
4295
    int x2 = x1 + screen->workArea ().width () + screen->vpSize ().width () *
4317
4296
         screen->width ();
4318
 
    y2 = y1 + screen->workArea ().height () + screen->vpSize ().height () *
 
4297
    int y2 = y1 + screen->workArea ().height () + screen->vpSize ().height () *
4319
4298
         screen->height ();
4320
4299
 
 
4300
    int dx = 0;
 
4301
    int width = serverGeometry.widthIncBorders ();
 
4302
 
4321
4303
    if (serverGeometry.x () - serverInput.left >= x2)
4322
4304
        dx = (x2 - 25) - serverGeometry.x ();
4323
4305
    else if (serverGeometry.x () + width + serverInput.right <= x1)
4324
4306
        dx = (x1 + 25) - (serverGeometry.x () + width);
4325
4307
 
 
4308
    int dy = 0;
 
4309
    int height = serverGeometry.heightIncBorders ();
 
4310
 
4326
4311
    if (serverGeometry.y () - serverInput.top >= y2)
4327
4312
        dy = (y2 - 25) - serverGeometry.y ();
4328
4313
    else if (serverGeometry.y () + height + serverInput.bottom <= y1)
4440
4425
void
4441
4426
PrivateWindow::hide ()
4442
4427
{
4443
 
    bool onDesktop = window->onCurrentDesktop ();
4444
 
 
4445
4428
    if (!managed)
4446
4429
        return;
4447
4430
 
 
4431
    bool onDesktop = window->onCurrentDesktop ();
 
4432
 
4448
4433
    if (!window->minimized () && !inShowDesktopMode &&
4449
4434
        !hidden && onDesktop)
4450
4435
    {
4487
4472
void
4488
4473
PrivateWindow::show ()
4489
4474
{
4490
 
    bool onDesktop = window->onCurrentDesktop ();
4491
 
 
4492
4475
    if (!managed)
4493
4476
        return;
4494
4477
 
 
4478
    bool onDesktop = window->onCurrentDesktop ();
 
4479
 
4495
4480
    if (minimized || inShowDesktopMode ||
4496
4481
        hidden    || !onDesktop)
4497
4482
    {
4959
4944
 
4960
4945
                if (iw && ih)
4961
4946
                {
4962
 
                    unsigned long j;
4963
4947
                    icon = new CompIcon (iw, ih);
4964
4948
                    if (!icon)
4965
4949
                        continue;
4971
4955
                    /* EWMH doesn't say if icon data is premultiplied or
4972
4956
                       not but most applications seem to assume data should
4973
4957
                       be unpremultiplied. */
4974
 
                    for (j = 0; j < iw * ih; j++)
 
4958
                    for (unsigned long j = 0; j < iw * ih; j++)
4975
4959
                    {
4976
4960
                        alpha = (idata[i + j + 2] >> 24) & 0xff;
4977
4961
                        red   = (idata[i + j + 2] >> 16) & 0xff;
5527
5511
void
5528
5512
PrivateWindow::updatePassiveButtonGrabs ()
5529
5513
{
 
5514
    if (!priv->frame)
 
5515
        return;
 
5516
 
5530
5517
    bool onlyActions = (priv->id == screen->activeWindow() ||
5531
5518
                        !screen->getCoreOptions().optionGetClickToFocus ());
5532
5519
 
5533
 
    if (!priv->frame)
5534
 
        return;
5535
 
 
5536
5520
    /* Ungrab everything */
5537
5521
    XUngrabButton (screen->dpy(), AnyButton, AnyModifier, frame);
5538
5522
 
5713
5697
    {
5714
5698
        unsigned int   valueMask = CWX | CWY;
5715
5699
        XWindowChanges xwc = XWINDOWCHANGES_INIT;
5716
 
        int m, wx, wy;
5717
5700
 
5718
5701
        if (!priv->managed)
5719
5702
            return;
5724
5707
        if (priv->state & CompWindowStateStickyMask)
5725
5708
            return;
5726
5709
 
5727
 
        wx = tx;
5728
 
        wy = ty;
 
5710
        int wx = tx;
 
5711
        int wy = ty;
 
5712
        int m;
5729
5713
 
5730
5714
        if (screen->vpSize ().width ()!= 1)
5731
5715
        {