Merge lp:~compiz-team/compiz-core/compiz-core.fix_864330 into lp:compiz-core/0.9.5

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 2877
Proposed branch: lp:~compiz-team/compiz-core/compiz-core.fix_864330
Merge into: lp:compiz-core/0.9.5
Diff against target: 563 lines (+198/-74)
4 files modified
plugins/move/src/move.cpp (+1/-1)
src/privatescreen.h (+6/-0)
src/privatewindow.h (+2/-1)
src/window.cpp (+189/-72)
To merge this branch: bzr merge lp:~compiz-team/compiz-core/compiz-core.fix_864330
Reviewer Review Type Date Requested Status
Jason Smith (community) Approve
Review via email: mp+78935@code.launchpad.net

Description of the change

Rework the event tracking system slightly to cover more cases where events would
not be recorded properly:

1. When determining restack requests relative to another window which is pending
   a restack, check to see if we already requested to restack relative to it
   after it was pending the restack, rather than unconditionally submitting
   the restack and risking that being a no-op
2. When a window gets closed, its frame window is marked "None" immediately
   so we must discard tracking of any remaining pending configure events
   as they wont come to the frame window as we know it
3. Remove the static timeout and replace it with a timer object that clears up
   any stale configure requests which didn't get matched to events (note that
   this will be removed, but exists only to safeguard against performance regressions
   with the current API)
4. Make the move plugin lock down server geometry updates whenever it receives the
   "lock_position" signal on either the frame or the client window
5. Fix a problem with maximizing undecorated windows (resized to height = 0)

To post a comment you must log in.
Revision history for this message
Jason Smith (jassmith) wrote :

code looks good, testing hasn't yet revealed any issues

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'plugins/move/src/move.cpp'
--- plugins/move/src/move.cpp 2011-09-29 03:29:41 +0000
+++ plugins/move/src/move.cpp 2011-10-11 09:53:25 +0000
@@ -525,7 +525,7 @@
525 Window xid = CompOption::getIntOptionNamed (options, "window", 0);525 Window xid = CompOption::getIntOptionNamed (options, "window", 0);
526 int lock = CompOption::getIntOptionNamed (options, "active", 0);526 int lock = CompOption::getIntOptionNamed (options, "active", 0);
527527
528 if (xid == w->id ())528 if (xid == ROOTPARENT (w))
529 MoveWindow::get (w)->mLocked = lock ? true : false;529 MoveWindow::get (w)->mLocked = lock ? true : false;
530 }530 }
531 }531 }
532532
=== modified file 'src/privatescreen.h'
--- src/privatescreen.h 2011-10-04 11:28:15 +0000
+++ src/privatescreen.h 2011-10-11 09:53:25 +0000
@@ -111,6 +111,8 @@
111 virtual ~PendingEvent ();111 virtual ~PendingEvent ();
112112
113 virtual bool match (XEvent *);113 virtual bool match (XEvent *);
114 unsigned int serial () { return mSerial; } // HACK: will be removed
115 virtual void dump ();
114116
115 typedef boost::shared_ptr<PendingEvent> Ptr;117 typedef boost::shared_ptr<PendingEvent> Ptr;
116118
@@ -131,6 +133,8 @@
131133
132 virtual bool match (XEvent *);134 virtual bool match (XEvent *);
133 bool matchVM (unsigned int valueMask);135 bool matchVM (unsigned int valueMask);
136 bool matchRequest (XWindowChanges &xwc, unsigned int);
137 virtual void dump ();
134138
135 typedef boost::shared_ptr<PendingConfigureEvent> Ptr;139 typedef boost::shared_ptr<PendingConfigureEvent> Ptr;
136140
@@ -154,6 +158,8 @@
154 bool match (XEvent *);158 bool match (XEvent *);
155 bool pending ();159 bool pending ();
156 bool forEachIf (boost::function <bool (compiz::X11::PendingEvent::Ptr)>);160 bool forEachIf (boost::function <bool (compiz::X11::PendingEvent::Ptr)>);
161 void clear () { mEvents.clear (); } // HACK will be removed
162 void dump ();
157163
158protected:164protected:
159 bool removeIfMatching (const PendingEvent::Ptr &p, XEvent *);165 bool removeIfMatching (const PendingEvent::Ptr &p, XEvent *);
160166
=== modified file 'src/privatewindow.h'
--- src/privatewindow.h 2011-10-04 11:28:15 +0000
+++ src/privatewindow.h 2011-10-11 09:53:25 +0000
@@ -211,7 +211,7 @@
211211
212 void readIconHint ();212 void readIconHint ();
213213
214 void addPendingConfigure (XWindowChanges &, unsigned int);214 bool checkClear ();
215215
216 public:216 public:
217217
@@ -293,6 +293,7 @@
293 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;293 typedef std::pair <XWindowChanges, unsigned int> XWCValueMask;
294294
295 compiz::X11::PendingEventQueue pendingConfigures;295 compiz::X11::PendingEventQueue pendingConfigures;
296 CompTimer mClearCheckTimeout;
296 bool pendingPositionUpdates;297 bool pendingPositionUpdates;
297298
298 char *startupId;299 char *startupId;
299300
=== modified file 'src/window.cpp'
--- src/window.cpp 2011-10-08 11:38:21 +0000
+++ src/window.cpp 2011-10-11 09:53:25 +0000
@@ -897,13 +897,16 @@
897897
898 }898 }
899899
900 gettimeofday (&lastConfigureRequest, NULL);
901 compiz::X11::PendingEvent::Ptr pc =900 compiz::X11::PendingEvent::Ptr pc =
902 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (901 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
903 new compiz::X11::PendingConfigureEvent (902 new compiz::X11::PendingConfigureEvent (
904 screen->dpy (), serverFrame, valueMask, &xwc)));903 screen->dpy (), serverFrame, valueMask, &xwc)));
905904
906 pendingConfigures.add (pc);905 pendingConfigures.add (pc);
906 if (priv->mClearCheckTimeout.active ())
907 priv->mClearCheckTimeout.stop ();
908 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
909 2000, 2500);
907910
908 XSendEvent (screen->dpy (), screen->root (), false,911 XSendEvent (screen->dpy (), screen->root (), false,
909 SubstructureNotifyMask, (XEvent *) &xev);912 SubstructureNotifyMask, (XEvent *) &xev);
@@ -913,13 +916,16 @@
913 }916 }
914 else917 else
915 {918 {
916 gettimeofday (&lastConfigureRequest, NULL);
917 compiz::X11::PendingEvent::Ptr pc =919 compiz::X11::PendingEvent::Ptr pc =
918 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (920 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
919 new compiz::X11::PendingConfigureEvent (921 new compiz::X11::PendingConfigureEvent (
920 screen->dpy (), serverFrame, valueMask, &xwc)));922 screen->dpy (), serverFrame, valueMask, &xwc)));
921923
922 pendingConfigures.add (pc);924 pendingConfigures.add (pc);
925 if (priv->mClearCheckTimeout.active ())
926 priv->mClearCheckTimeout.stop ();
927 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
928 2000, 2500);
923 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);929 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
924 }930 }
925931
@@ -951,10 +957,7 @@
951 if (shaded)957 if (shaded)
952 xwc.height = bw;958 xwc.height = bw;
953 else959 else
954 xwc.height = bw;960 xwc.height = serverGeometry.height () + bw;
955
956 if (shaded)
957 height = 0;
958961
959 if (serverFrameGeometry.x () == xwc.x)962 if (serverFrameGeometry.x () == xwc.x)
960 valueMask &= ~(CWX);963 valueMask &= ~(CWX);
@@ -1032,13 +1035,16 @@
10321035
1033 }1036 }
10341037
1035 gettimeofday (&lastConfigureRequest, NULL);
1036 compiz::X11::PendingEvent::Ptr pc =1038 compiz::X11::PendingEvent::Ptr pc =
1037 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (1039 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1038 new compiz::X11::PendingConfigureEvent (1040 new compiz::X11::PendingConfigureEvent (
1039 screen->dpy (), serverFrame, valueMask, &xwc)));1041 screen->dpy (), serverFrame, valueMask, &xwc)));
10401042
1041 pendingConfigures.add (pc);1043 pendingConfigures.add (pc);
1044 if (priv->mClearCheckTimeout.active ())
1045 priv->mClearCheckTimeout.stop ();
1046 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1047 2000, 2500);
10421048
1043 XSendEvent (screen->dpy (), screen->root (), false,1049 XSendEvent (screen->dpy (), screen->root (), false,
1044 SubstructureNotifyMask, (XEvent *) &xev);1050 SubstructureNotifyMask, (XEvent *) &xev);
@@ -1048,13 +1054,16 @@
1048 }1054 }
1049 else1055 else
1050 {1056 {
1051 gettimeofday (&lastConfigureRequest, NULL);
1052 compiz::X11::PendingEvent::Ptr pc =1057 compiz::X11::PendingEvent::Ptr pc =
1053 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (1058 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
1054 new compiz::X11::PendingConfigureEvent (1059 new compiz::X11::PendingConfigureEvent (
1055 screen->dpy (), serverFrame, valueMask, &xwc)));1060 screen->dpy (), serverFrame, valueMask, &xwc)));
10561061
1057 pendingConfigures.add (pc);1062 pendingConfigures.add (pc);
1063 if (priv->mClearCheckTimeout.active ())
1064 priv->mClearCheckTimeout.stop ();
1065 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
1066 2000, 2500);
10581067
1059 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);1068 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
1060 }1069 }
@@ -2088,7 +2097,7 @@
2088#ifdef DEBUG2097#ifdef DEBUG
2089 abort ();2098 abort ();
2090#else2099#else
2091 pendingConfigures = compiz::X11::PendingEventQueue (screen->dpy ());2100 pendingConfigures.clear ();
2092#endif2101#endif
2093 }2102 }
20942103
@@ -2199,28 +2208,13 @@
2199 {2208 {
2200 XWindowChanges xwc;2209 XWindowChanges xwc;
2201 unsigned int valueMask = CWX | CWY;2210 unsigned int valueMask = CWX | CWY;
2202 struct timeval tv, old;2211 compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x, "\
2203 compLogMessage ("core", CompLogLevelDebug, "pending configure notifies on 0x%x,"\
2204 "moving window asyncrhonously!", (unsigned int) priv->serverId);2212 "moving window asyncrhonously!", (unsigned int) priv->serverId);
22052213
2206 old = priv->lastConfigureRequest;
2207 gettimeofday (&tv, NULL);
2208
2209 xwc.x = priv->serverGeometry.x () + dx;2214 xwc.x = priv->serverGeometry.x () + dx;
2210 xwc.y = priv->serverGeometry.y () + dy;2215 xwc.y = priv->serverGeometry.y () + dy;
22112216
2212 configureXWindow (valueMask, &xwc);2217 configureXWindow (valueMask, &xwc);
2213
2214 priv->lastConfigureRequest = old;
2215
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)
2219 {
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 ());
2223 }
2224 }2218 }
2225 }2219 }
2226}2220}
@@ -2231,16 +2225,59 @@
2231 return !mEvents.empty ();2225 return !mEvents.empty ();
2232}2226}
22332227
2228bool
2229PrivateWindow::checkClear ()
2230{
2231 if (pendingConfigures.pending ())
2232 {
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",
2236 id);
2237 pendingConfigures.dump ();
2238 pendingConfigures.clear ();
2239 }
2240
2241 return false;
2242}
2243
2234void2244void
2235compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)2245compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p)
2236{2246{
2247 compLogMessage ("core", CompLogLevelDebug, "pending request:");
2248 p->dump ();
2249
2237 mEvents.push_back (p);2250 mEvents.push_back (p);
2238}2251}
22392252
2240bool2253bool
2241compiz::X11::PendingEventQueue::removeIfMatching (const PendingEvent::Ptr &p, XEvent *event)2254compiz::X11::PendingEventQueue::removeIfMatching (const PendingEvent::Ptr &p, XEvent *event)
2242{2255{
2243 return p->match (event);2256 if (p->match (event))
2257 {
2258 compLogMessage ("core", CompLogLevelDebug, "received event:");
2259 p->dump ();
2260 return true;
2261 }
2262
2263 return false;
2264}
2265
2266void
2267compiz::X11::PendingEvent::dump ()
2268{
2269 compLogMessage ("core", CompLogLevelDebug, "- event serial: %i", mSerial);
2270 compLogMessage ("core", CompLogLevelDebug, "- event window 0x%x", mWindow);
2271}
2272
2273void
2274compiz::X11::PendingConfigureEvent::dump ()
2275{
2276 compiz::X11::PendingEvent::dump ();
2277
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);
2244}2281}
22452282
2246bool2283bool
@@ -2266,8 +2303,21 @@
2266 return false;2303 return false;
2267}2304}
22682305
2306void
2307compiz::X11::PendingEventQueue::dump ()
2308{
2309 foreach (compiz::X11::PendingEvent::Ptr p, mEvents)
2310 p->dump ();
2311}
2312
2269compiz::X11::PendingEventQueue::PendingEventQueue (Display *d)2313compiz::X11::PendingEventQueue::PendingEventQueue (Display *d)
2270{2314{
2315 /* mClearCheckTimeout.setTimes (0, 0)
2316 *
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 */
2271}2321}
22722322
2273compiz::X11::PendingEventQueue::~PendingEventQueue ()2323compiz::X11::PendingEventQueue::~PendingEventQueue ()
@@ -2310,7 +2360,44 @@
2310bool2360bool
2311compiz::X11::PendingConfigureEvent::matchVM (unsigned int valueMask)2361compiz::X11::PendingConfigureEvent::matchVM (unsigned int valueMask)
2312{2362{
2313 return valueMask & mValueMask;2363 unsigned int result = mValueMask != 0 ? valueMask & mValueMask : 1;
2364
2365 return result != 0;
2366}
2367
2368bool
2369compiz::X11::PendingConfigureEvent::matchRequest (XWindowChanges &xwc, unsigned int valueMask)
2370{
2371 if (matchVM (valueMask))
2372 {
2373 if (valueMask & CWX)
2374 if (xwc.x != mXwc.x)
2375 return false;
2376
2377 if (valueMask & CWY)
2378 if (xwc.y != mXwc.y)
2379 return false;
2380
2381 if (valueMask & CWWidth)
2382 if (xwc.width != mXwc.width)
2383 return false;
2384
2385 if (valueMask & CWHeight)
2386 if (xwc.height != mXwc.height)
2387 return false;
2388
2389 if (valueMask & CWBorderWidth)
2390 if (xwc.border_width != mXwc.border_width)
2391 return false;
2392
2393 if (valueMask & (CWStackMode | CWSibling))
2394 if (xwc.sibling != mXwc.sibling)
2395 return false;
2396
2397 return true;
2398 }
2399
2400 return false;
2314}2401}
23152402
2316bool2403bool
@@ -2322,29 +2409,16 @@
2322 if (!compiz::X11::PendingEvent::match (event))2409 if (!compiz::X11::PendingEvent::match (event))
2323 return false;2410 return false;
23242411
2325 if (mValueMask & CWX)2412 XWindowChanges xwc;
2326 if (ce->x != mXwc.x)2413
2327 matched = false;2414 xwc.x = ce->x;
23282415 xwc.y = ce->y;
2329 if (mValueMask & CWY)2416 xwc.width = ce->width;
2330 if (ce->y != mXwc.y)2417 xwc.height = ce->height;
2331 matched = false;2418 xwc.border_width = ce->border_width;
23322419 xwc.sibling = ce->above;
2333 if (mValueMask & CWWidth)2420
2334 if (ce->width != mXwc.width)2421 matched = matchRequest (xwc, mValueMask);
2335 matched = false;
2336
2337 if (mValueMask & CWHeight)
2338 if (ce->height != mXwc.height)
2339 matched = false;
2340
2341 if (mValueMask & CWBorderWidth)
2342 if (ce->border_width != mXwc.border_width)
2343 matched = false;
2344
2345 if (mValueMask & (CWStackMode | CWSibling))
2346 if (ce->above != mXwc.sibling)
2347 matched = false;
23482422
2349 /* Remove events from the queue2423 /* Remove events from the queue
2350 * even if they didn't match what2424 * even if they didn't match what
@@ -2440,7 +2514,6 @@
2440 xwc.x = priv->serverFrameGeometry.x ();2514 xwc.x = priv->serverFrameGeometry.x ();
2441 xwc.y = priv->serverFrameGeometry.y ();2515 xwc.y = priv->serverFrameGeometry.y ();
24422516
2443 gettimeofday (&priv->lastConfigureRequest, NULL);
2444 compiz::X11::PendingEvent::Ptr pc =2517 compiz::X11::PendingEvent::Ptr pc =
2445 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (2518 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
2446 new compiz::X11::PendingConfigureEvent (2519 new compiz::X11::PendingConfigureEvent (
@@ -2448,6 +2521,11 @@
24482521
2449 priv->pendingConfigures.add (pc);2522 priv->pendingConfigures.add (pc);
24502523
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),
2528 2000, 2500);
2451 XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);2529 XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc);
24522530
2453 if (priv->serverFrame)2531 if (priv->serverFrame)
@@ -3259,11 +3337,18 @@
3259 return pc->matchVM (CWStackMode | CWSibling);3337 return pc->matchVM (CWStackMode | CWSibling);
3260}3338}
32613339
3340static bool isExistingRequest (compiz::X11::PendingEvent::Ptr p, XWindowChanges &xwc, unsigned int valueMask)
3341{
3342 compiz::X11::PendingConfigureEvent::Ptr pc = boost::shared_static_cast <compiz::X11::PendingConfigureEvent> (p);
3343
3344 return pc->matchRequest (xwc, valueMask);
3345}
3346
3262void3347void
3263PrivateWindow::reconfigureXWindow (unsigned int valueMask,3348PrivateWindow::reconfigureXWindow (unsigned int valueMask,
3264 XWindowChanges *xwc)3349 XWindowChanges *xwc)
3265{3350{
3266 unsigned int frameValueMask = valueMask;3351 unsigned int frameValueMask = 0;
32673352
3268 /* Immediately sync window position3353 /* Immediately sync window position
3269 * if plugins were updating w->geometry () directly3354 * if plugins were updating w->geometry () directly
@@ -3273,28 +3358,37 @@
32733358
3274 /* Remove redundant bits */3359 /* Remove redundant bits */
32753360
3276 if (serverGeometry.x () == xwc->x)3361 if (valueMask & CWX && serverGeometry.x () == xwc->x)
3277 valueMask &= ~(CWX);3362 valueMask &= ~(CWX);
32783363
3279 if (serverGeometry.y () == xwc->y)3364 if (valueMask & CWY && serverGeometry.y () == xwc->y)
3280 valueMask &= ~(CWY);3365 valueMask &= ~(CWY);
32813366
3282 if (serverGeometry.width () == xwc->width)3367 if (valueMask & CWWidth && serverGeometry.width () == xwc->width)
3283 valueMask &= ~(CWWidth);3368 valueMask &= ~(CWWidth);
32843369
3285 if (serverGeometry.height () == xwc->height)3370 if (valueMask & CWHeight && serverGeometry.height () == xwc->height)
3286 valueMask &= ~(CWHeight);3371 valueMask &= ~(CWHeight);
32873372
3288 if (serverGeometry.border () == xwc->border_width)3373 if (valueMask & CWBorderWidth && serverGeometry.border () == xwc->border_width)
3289 valueMask &= ~(CWBorderWidth);3374 valueMask &= ~(CWBorderWidth);
32903375
3291 if (window->serverPrev && ROOTPARENT (window->serverPrev) == xwc->sibling)3376 if (valueMask & CWSibling && window->serverPrev)
3292 {3377 {
3293 /* check if the sibling is also pending a restack,3378 /* check if the sibling is also pending a restack,
3294 * if not, then setting this bit is useless */3379 * if not, then setting this bit is useless */
32953380 if (ROOTPARENT (window->serverPrev) == xwc->sibling)
3296 if (window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1)))3381 {
3297 valueMask &= ~(CWSibling | CWStackMode);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;
3385
3386 if (!remove)
3387 remove = !restackPending;
3388
3389 if (remove)
3390 valueMask &= ~(CWSibling | CWStackMode);
3391 }
3298 }3392 }
32993393
3300 if (valueMask & CWBorderWidth)3394 if (valueMask & CWBorderWidth)
@@ -3330,13 +3424,18 @@
3330 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");3424 compLogMessage ("core", CompLogLevelWarn, "restack_mode not Above");
3331 }3425 }
33323426
3333 if (serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)3427 frameValueMask = valueMask;
3428
3429 if (frameValueMask & CWX &&
3430 serverFrameGeometry.x () == xwc->x - serverGeometry.border () - serverInput.left)
3334 frameValueMask &= ~(CWX);3431 frameValueMask &= ~(CWX);
33353432
3336 if (serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)3433 if (frameValueMask & CWY &&
3434 serverFrameGeometry.y () == xwc->y - serverGeometry.border () - serverInput.top)
3337 frameValueMask &= ~(CWY);3435 frameValueMask &= ~(CWY);
33383436
3339 if (serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 23437 if (frameValueMask & CWWidth &&
3438 serverFrameGeometry.width () == xwc->width + serverGeometry.border () * 2
3340 + serverInput.left + serverInput.right)3439 + serverInput.left + serverInput.right)
3341 frameValueMask &= ~(CWWidth);3440 frameValueMask &= ~(CWWidth);
33423441
@@ -3346,13 +3445,15 @@
33463445
3347 if (shaded)3446 if (shaded)
3348 {3447 {
3349 if (serverFrameGeometry.height () == serverGeometry.border () * 23448 if (frameValueMask & CWHeight &&
3449 serverFrameGeometry.height () == serverGeometry.border () * 2
3350 + serverInput.top + serverInput.bottom)3450 + serverInput.top + serverInput.bottom)
3351 frameValueMask &= ~(CWHeight);3451 frameValueMask &= ~(CWHeight);
3352 }3452 }
3353 else3453 else
3354 {3454 {
3355 if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 23455 if (frameValueMask & CWHeight &&
3456 serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
3356 + serverInput.top + serverInput.bottom)3457 + serverInput.top + serverInput.bottom)
3357 frameValueMask &= ~(CWHeight);3458 frameValueMask &= ~(CWHeight);
3358 }3459 }
@@ -3397,14 +3498,16 @@
3397 wc.width = serverFrameGeometry.width ();3498 wc.width = serverFrameGeometry.width ();
3398 wc.height = serverFrameGeometry.height ();3499 wc.height = serverFrameGeometry.height ();
33993500
3400 gettimeofday (&lastConfigureRequest, NULL);
3401
3402 compiz::X11::PendingEvent::Ptr pc =3501 compiz::X11::PendingEvent::Ptr pc =
3403 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (3502 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
3404 new compiz::X11::PendingConfigureEvent (3503 new compiz::X11::PendingConfigureEvent (
3405 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));3504 screen->dpy (), priv->serverFrame, frameValueMask, &wc)));
34063505
3407 pendingConfigures.add (pc);3506 pendingConfigures.add (pc);
3507 if (priv->mClearCheckTimeout.active ())
3508 priv->mClearCheckTimeout.stop ();
3509 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
3510 2000, 2500);
34083511
3409 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);3512 XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc);
3410 }3513 }
@@ -4196,13 +4299,16 @@
41964299
4197 if (serverFrame)4300 if (serverFrame)
4198 {4301 {
4199 gettimeofday (&lastConfigureRequest, NULL);
4200 compiz::X11::PendingEvent::Ptr pc =4302 compiz::X11::PendingEvent::Ptr pc =
4201 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (4303 boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr (
4202 new compiz::X11::PendingConfigureEvent (4304 new compiz::X11::PendingConfigureEvent (
4203 screen->dpy (), serverFrame, valueMask, &lxwc)));4305 screen->dpy (), serverFrame, valueMask, &lxwc)));
42044306
4205 pendingConfigures.add (pc);4307 pendingConfigures.add (pc);
4308 if (priv->mClearCheckTimeout.active ())
4309 priv->mClearCheckTimeout.stop ();
4310 priv->mClearCheckTimeout.start (boost::bind (&PrivateWindow::checkClear, priv),
4311 2000, 2500);
4206 }4312 }
42074313
4208 /* Below with no sibling puts the window at the bottom4314 /* Below with no sibling puts the window at the bottom
@@ -4215,8 +4321,15 @@
4215 }4321 }
4216 else if (sibling)4322 else if (sibling)
4217 {4323 {
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;
4327
4328 if (matchingRequest)
4329 processAnyways = false;
4330
4218 if (sibling->priv->id != window->serverPrev->priv->id ||4331 if (sibling->priv->id != window->serverPrev->priv->id ||
4219 window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1)))4332 processAnyways)
4220 {4333 {
4221 mask |= CWSibling | CWStackMode;4334 mask |= CWSibling | CWStackMode;
42224335
@@ -6295,8 +6408,6 @@
6295 if (dbg)6408 if (dbg)
6296 dbg->overrideRedirectRestack (priv->id, aboveId);6409 dbg->overrideRedirectRestack (priv->id, aboveId);
62976410
6298 gettimeofday (&priv->lastConfigureRequest, NULL);
6299
6300 priv->attrib = wa;6411 priv->attrib = wa;
6301 priv->serverGeometry.set (priv->attrib.x, priv->attrib.y,6412 priv->serverGeometry.set (priv->attrib.x, priv->attrib.y,
6302 priv->attrib.width, priv->attrib.height,6413 priv->attrib.width, priv->attrib.height,
@@ -7229,6 +7340,12 @@
7229 XDestroyWindow (screen->dpy (), wrapper);7340 XDestroyWindow (screen->dpy (), wrapper);
72307341
7231 window->windowNotify (CompWindowNotifyUnreparent);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 ();
72327349
7233 frame = None;7350 frame = None;
7234 wrapper = None;7351 wrapper = None;

Subscribers

People subscribed via source and target branches