900
gettimeofday (&lastConfigureRequest, NULL);
901
900
compiz::X11::PendingEvent::Ptr pc =
902
901
boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
903
902
new compiz::X11::PendingConfigureEvent (
904
903
screen->dpy (), serverFrame, valueMask, &xwc)));
906
905
pendingConfigures.add (pc);
906
if (priv->mClearCheckTimeout.active ())
907
priv->mClearCheckTimeout.stop ();
908
priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
908
911
XSendEvent (screen->dpy (), screen->root (), false,
909
912
SubstructureNotifyMask, (XEvent *) &xev);
916
gettimeofday (&lastConfigureRequest, NULL);
917
919
compiz::X11::PendingEvent::Ptr pc =
918
920
boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
919
921
new compiz::X11::PendingConfigureEvent (
920
922
screen->dpy (), serverFrame, valueMask, &xwc)));
922
924
pendingConfigures.add (pc);
925
if (priv->mClearCheckTimeout.active ())
926
priv->mClearCheckTimeout.stop ();
927
priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
923
929
XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
1035
gettimeofday (&lastConfigureRequest, NULL);
1036
1038
compiz::X11::PendingEvent::Ptr pc =
1037
1039
boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1038
1040
new compiz::X11::PendingConfigureEvent (
1039
1041
screen->dpy (), serverFrame, valueMask, &xwc)));
1041
1043
pendingConfigures.add (pc);
1044
if (priv->mClearCheckTimeout.active ())
1045
priv->mClearCheckTimeout.stop ();
1046
priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1043
1049
XSendEvent (screen->dpy (), screen->root (), false,
1044
1050
SubstructureNotifyMask, (XEvent *) &xev);
1051
gettimeofday (&lastConfigureRequest, NULL);
1052
1057
compiz::X11::PendingEvent::Ptr pc =
1053
1058
boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1054
1059
new compiz::X11::PendingConfigureEvent (
1055
1060
screen->dpy (), serverFrame, valueMask, &xwc)));
1057
1062
pendingConfigures.add (pc);
1063
if (priv->mClearCheckTimeout.active ())
1064
priv->mClearCheckTimeout.stop ();
1065
priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1059
1068
XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
2200
2209
XWindowChanges xwc;
2201
2210
unsigned int valueMask = CWX | CWY;
2202
struct timeval tv, old;
2203
compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x,"\
2211
compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
2204
2212
"moving window asyncrhonously!", (unsigned int) priv->serverId);
2206
old = priv->lastConfigureRequest;
2207
gettimeofday (&tv, NULL);
2209
2214
xwc.x = priv->serverGeometry.x () + dx;
2210
2215
xwc.y = priv->serverGeometry.y () + dy;
2212
2217
configureXWindow (valueMask, &xwc);
2214
priv->lastConfigureRequest = old;
2216
/* FIXME: This is a hack to avoid performance regressions
2217
* and must be removed in 0.9.6 */
2218
if (tv.tv_usec - priv->lastConfigureRequest.tv_usec > 30000)
2220
compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event from request at %i (now: %i)\n",
2221
priv->lastConfigureRequest.tv_usec, tv.tv_usec);
2222
priv->pendingConfigures = compiz::X11::PendingEventQueue (screen->dpy ());
2231
2225
return !mEvents.empty ();
2229
PrivateWindow::checkClear ()
2231
if (pendingConfigures.pending ())
2233
/* FIXME: This is a hack to avoid performance regressions
2234
* and must be removed in 0.9.6 */
2235
compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event on 0x%x\n",
2237
pendingConfigures.dump ();
2238
pendingConfigures.clear ();
2235
2245
compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
2247
compLogMessage ("core", CompLogLevelDebug, "pending request:");
2237
2250
mEvents.push_back (p);
2241
2254
compiz::X11::PendingEventQueue::removeIfMatching (const PendingEvent::Ptr &p, XEvent *event)
2243
return p->match (event);
2256
if (p->match (event))
2258
compLogMessage ("core", CompLogLevelDebug, "received event:");
2267
compiz::X11::PendingEvent::dump ()
2269
compLogMessage ("core", CompLogLevelDebug, "- event serial: %i", mSerial);
2270
compLogMessage ("core", CompLogLevelDebug, "- event window 0x%x", mWindow);
2274
compiz::X11::PendingConfigureEvent::dump ()
2276
compiz::X11::PendingEvent::dump ();
2278
compLogMessage ("core", CompLogLevelDebug, "- x: %i y: %i width: %i height: %i "\
2279
"border: %i, sibling: 0x%x",
2280
mXwc.x, mXwc.y, mXwc.width, mXwc.height, mXwc.border_width, mXwc.sibling);
2307
compiz::X11::PendingEventQueue::dump ()
2309
foreach (compiz::X11::PendingEvent::Ptr p, mEvents)
2269
2313
compiz::X11::PendingEventQueue::PendingEventQueue (Display *d)
2315
/* mClearCheckTimeout.setTimes (0, 0)
2317
* XXX: For whatever reason, calling setTimes (0, 0) here causes
2318
* the destructor of the timer object to be called twice later on
2319
* in execution and the stack gets smashed. This could be a
2320
* compiler bug, but requires further investigation */
2273
2323
compiz::X11::PendingEventQueue::~PendingEventQueue ()
2311
2361
compiz::X11::PendingConfigureEvent::matchVM (unsigned int valueMask)
2313
return valueMask & mValueMask;
2363
unsigned int result = mValueMask != 0 ? valueMask & mValueMask : 1;
2369
compiz::X11::PendingConfigureEvent::matchRequest (XWindowChanges &xwc, unsigned int valueMask)
2371
if (matchVM (valueMask))
2373
if (valueMask & CWX)
2374
if (xwc.x != mXwc.x)
2377
if (valueMask & CWY)
2378
if (xwc.y != mXwc.y)
2381
if (valueMask & CWWidth)
2382
if (xwc.width != mXwc.width)
2385
if (valueMask & CWHeight)
2386
if (xwc.height != mXwc.height)
2389
if (valueMask & CWBorderWidth)
2390
if (xwc.border_width != mXwc.border_width)
2393
if (valueMask & (CWStackMode | CWSibling))
2394
if (xwc.sibling != mXwc.sibling)
2322
2409
if (!compiz::X11::PendingEvent::match (event))
2325
if (mValueMask & CWX)
2326
if (ce->x != mXwc.x)
2329
if (mValueMask & CWY)
2330
if (ce->y != mXwc.y)
2333
if (mValueMask & CWWidth)
2334
if (ce->width != mXwc.width)
2337
if (mValueMask & CWHeight)
2338
if (ce->height != mXwc.height)
2341
if (mValueMask & CWBorderWidth)
2342
if (ce->border_width != mXwc.border_width)
2345
if (mValueMask & (CWStackMode | CWSibling))
2346
if (ce->above != mXwc.sibling)
2416
xwc.width = ce->width;
2417
xwc.height = ce->height;
2418
xwc.border_width = ce->border_width;
2419
xwc.sibling = ce->above;
2421
matched = matchRequest (xwc, mValueMask);
2349
2423
/* Remove events from the queue
2350
2424
* even if they didn't match what
2440
2514
xwc.x = priv->serverFrameGeometry.x ();
2441
2515
xwc.y = priv->serverFrameGeometry.y ();
2443
gettimeofday (&priv->lastConfigureRequest, NULL);
2444
2517
compiz::X11::PendingEvent::Ptr pc =
2445
2518
boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
2446
2519
new compiz::X11::PendingConfigureEvent (
2449
2522
priv->pendingConfigures.add (pc);
2524
/* Got 3 seconds to get its stuff together */
2525
if (priv->mClearCheckTimeout.active ())
2526
priv->mClearCheckTimeout.stop ();
2527
priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
2451
2529
XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
2453
2531
if (priv->serverFrame)
3259
3337
return pc->matchVM (CWStackMode | CWSibling);
3340
static bool isExistingRequest (compiz::X11::PendingEvent::Ptr p, XWindowChanges &xwc, unsigned int valueMask)
3342
compiz::X11::PendingConfigureEvent::Ptr pc = boost::shared_static_cast <compiz::X11::PendingConfigureEvent> (p);
3344
return pc->matchRequest (xwc, valueMask);
3263
3348
PrivateWindow::reconfigureXWindow (unsigned int valueMask,
3264
3349
XWindowChanges *xwc)
3266
unsigned int frameValueMask = valueMask;
3351
unsigned int frameValueMask = 0;
3268
3353
/* Immediately sync window position
3269
3354
* if plugins were updating w->geometry () directly
3274
3359
/* Remove redundant bits */
3276
if (serverGeometry.x () == xwc->x)
3361
if (valueMask & CWX && serverGeometry.x () == xwc->x)
3277
3362
valueMask &= ~(CWX);
3279
if (serverGeometry.y () == xwc->y)
3364
if (valueMask & CWY && serverGeometry.y () == xwc->y)
3280
3365
valueMask &= ~(CWY);
3282
if (serverGeometry.width () == xwc->width)
3367
if (valueMask & CWWidth && serverGeometry.width () == xwc->width)
3283
3368
valueMask &= ~(CWWidth);
3285
if (serverGeometry.height () == xwc->height)
3370
if (valueMask & CWHeight && serverGeometry.height () == xwc->height)
3286
3371
valueMask &= ~(CWHeight);
3288
if (serverGeometry.border () == xwc->border_width)
3373
if (valueMask & CWBorderWidth && serverGeometry.border () == xwc->border_width)
3289
3374
valueMask &= ~(CWBorderWidth);
3291
if (window->serverPrev && ROOTPARENT (window->serverPrev) == xwc->sibling)
3376
if (valueMask & CWSibling && window->serverPrev)
3293
3378
/* check if the sibling is also pending a restack,
3294
3379
* if not, then setting this bit is useless */
3296
if (window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1)))
3297
valueMask &= ~(CWSibling | CWStackMode);
3380
if (ROOTPARENT (window->serverPrev) == xwc->sibling)
3382
bool matchingRequest = priv->pendingConfigures.forEachIf (boost::bind (isExistingRequest, _1, *xwc, valueMask));
3383
bool restackPending = window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1));
3384
bool remove = matchingRequest;
3387
remove = !restackPending;
3390
valueMask &= ~(CWSibling | CWStackMode);
3300
3394
if (valueMask & CWBorderWidth)
3330
3424
compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
3333
if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3427
frameValueMask = valueMask;
3429
if (frameValueMask & CWX &&
3430
serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3334
3431
frameValueMask &= ~(CWX);
3336
if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3433
if (frameValueMask & CWY &&
3434
serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3337
3435
frameValueMask &= ~(CWY);
3339
if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3437
if (frameValueMask & CWWidth &&
3438
serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3340
3439
+ serverInput.left + serverInput.right)
3341
3440
frameValueMask &= ~(CWWidth);
3349
if (serverFrameGeometry.height () == serverGeometry.border () * 2
3448
if (frameValueMask & CWHeight &&
3449
serverFrameGeometry.height () == serverGeometry.border () * 2
3350
3450
+ serverInput.top + serverInput.bottom)
3351
3451
frameValueMask &= ~(CWHeight);
3355
if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3455
if (frameValueMask & CWHeight &&
3456
serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3356
3457
+ serverInput.top + serverInput.bottom)
3357
3458
frameValueMask &= ~(CWHeight);
3397
3498
wc.width = serverFrameGeometry.width ();
3398
3499
wc.height = serverFrameGeometry.height ();
3400
gettimeofday (&lastConfigureRequest, NULL);
3402
3501
compiz::X11::PendingEvent::Ptr pc =
3403
3502
boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
3404
3503
new compiz::X11::PendingConfigureEvent (
3405
3504
screen->dpy (), priv->serverFrame, frameValueMask, &wc)));
3407
3506
pendingConfigures.add (pc);
3507
if (priv->mClearCheckTimeout.active ())
3508
priv->mClearCheckTimeout.stop ();
3509
priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
3409
3512
XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
4197
4300
if (serverFrame)
4199
gettimeofday (&lastConfigureRequest, NULL);
4200
4302
compiz::X11::PendingEvent::Ptr pc =
4201
4303
boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
4202
4304
new compiz::X11::PendingConfigureEvent (
4203
4305
screen->dpy (), serverFrame, valueMask, &lxwc)));
4205
4307
pendingConfigures.add (pc);
4308
if (priv->mClearCheckTimeout.active ())
4309
priv->mClearCheckTimeout.stop ();
4310
priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
4208
4314
/* Below with no sibling puts the window at the bottom
4216
4322
else if (sibling)
4324
bool matchingRequest = priv->pendingConfigures.forEachIf (boost::bind (isExistingRequest, _1, *xwc, (CWStackMode | CWSibling)));
4325
bool restackPending = window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1));
4326
bool processAnyways = restackPending;
4328
if (matchingRequest)
4329
processAnyways = false;
4218
4331
if (sibling->priv->id != window->serverPrev->priv->id ||
4219
window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1)))
4221
4334
mask |= CWSibling | CWStackMode;
6296
6409
dbg->overrideRedirectRestack (priv->id, aboveId);
6298
gettimeofday (&priv->lastConfigureRequest, NULL);
6300
6411
priv->attrib = wa;
6301
6412
priv->serverGeometry.set (priv->attrib.x, priv->attrib.y,
6302
6413
priv->attrib.width, priv->attrib.height,
7229
7340
XDestroyWindow (screen->dpy (), wrapper);
7231
7342
window->windowNotify (CompWindowNotifyUnreparent);
7343
/* This window is no longer "managed" in the
7344
* reparenting sense so clear its pending event
7345
* queue ... though maybe in future it would
7346
* be better to bookeep these events too and
7347
* handle the ReparentNotify */
7348
pendingConfigures.clear ();
7234
7351
wrapper = None;