Merge lp:~compiz-team/compiz-core/compiz-core.fix_863328 into lp:compiz-core/0.9.5
- compiz-core.fix_863328
- Merge into 0.9.5
Proposed by
Sam Spilsbury
Status: | Merged |
---|---|
Merged at revision: | 2859 |
Proposed branch: | lp:~compiz-team/compiz-core/compiz-core.fix_863328 |
Merge into: | lp:compiz-core/0.9.5 |
Diff against target: |
667 lines (+327/-96) 5 files modified
plugins/scale/src/privates.h (+1/-0) plugins/scale/src/scale.cpp (+15/-0) src/privatescreen.h (+65/-0) src/privatewindow.h (+1/-1) src/window.cpp (+245/-95) |
To merge this branch: | bzr merge lp:~compiz-team/compiz-core/compiz-core.fix_863328 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Robert Carr (community) | Approve | ||
Review via email: mp+78293@code.launchpad.net |
Commit message
Description of the change
Fix bug 863328
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'plugins/scale/src/privates.h' |
2 | --- plugins/scale/src/privates.h 2010-12-07 10:14:32 +0000 |
3 | +++ plugins/scale/src/privates.h 2011-10-05 17:44:25 +0000 |
4 | @@ -176,6 +176,7 @@ |
5 | |
6 | GLfloat xVelocity, yVelocity, scaleVelocity; |
7 | GLfloat scale; |
8 | + GLfloat lastTargetScale; |
9 | GLfloat tx, ty; |
10 | float delta; |
11 | bool adjust; |
12 | |
13 | === modified file 'plugins/scale/src/scale.cpp' |
14 | --- plugins/scale/src/scale.cpp 2011-09-19 13:00:51 +0000 |
15 | +++ plugins/scale/src/scale.cpp 2011-10-05 17:44:25 +0000 |
16 | @@ -261,6 +261,17 @@ |
17 | |
18 | bool drawScaled = false; |
19 | |
20 | + /* Windows that wouldn't be visible before and after entering |
21 | + * scale mode (because some plugin modified CompWindow::focus) |
22 | + * should be faded in and out */ |
23 | + if (window->state () & CompWindowStateHiddenMask) |
24 | + { |
25 | + if (priv->slot) |
26 | + attrib.opacity *= (1.0f - priv->scale) / (1.0f - priv->slot->scale); |
27 | + else |
28 | + attrib.opacity *= (1.0f - priv->scale) / (1.0f - priv->lastTargetScale); |
29 | + } |
30 | + |
31 | if (priv->adjust || priv->slot) |
32 | { |
33 | if (priv->window->id () != priv->spScreen->selectedWindow && |
34 | @@ -940,9 +951,12 @@ |
35 | |
36 | if (sw->priv->slot) |
37 | { |
38 | + sw->priv->lastTargetScale = sw->priv->slot->scale; |
39 | sw->priv->slot = NULL; |
40 | sw->priv->adjust = true; |
41 | } |
42 | + else |
43 | + sw->priv->lastTargetScale = 1.0f; |
44 | } |
45 | |
46 | if (state & CompAction::StateCancel) |
47 | @@ -1759,6 +1773,7 @@ |
48 | yVelocity (0.0), |
49 | scaleVelocity (0.0), |
50 | scale (1.0), |
51 | + lastTargetScale (1.0f), |
52 | tx (0.0), |
53 | ty (0.0), |
54 | delta (1.0), |
55 | |
56 | === modified file 'src/privatescreen.h' |
57 | --- src/privatescreen.h 2011-09-19 12:54:22 +0000 |
58 | +++ src/privatescreen.h 2011-10-05 17:44:25 +0000 |
59 | @@ -35,6 +35,7 @@ |
60 | #include <core/timer.h> |
61 | #include <core/plugin.h> |
62 | #include <time.h> |
63 | +#include <boost/shared_ptr.hpp> |
64 | |
65 | #include <glibmm/main.h> |
66 | |
67 | @@ -100,6 +101,70 @@ |
68 | unsigned int viewportY; |
69 | }; |
70 | |
71 | +namespace compiz |
72 | +{ |
73 | +namespace X11 |
74 | +{ |
75 | +class PendingEvent { |
76 | +public: |
77 | + PendingEvent (Display *, Window); |
78 | + virtual ~PendingEvent (); |
79 | + |
80 | + virtual bool match (XEvent *); |
81 | + |
82 | + typedef boost::shared_ptr<PendingEvent> Ptr; |
83 | + |
84 | +protected: |
85 | + |
86 | + virtual Window getEventWindow (XEvent *); |
87 | + |
88 | + unsigned int mSerial; |
89 | + Window mWindow; |
90 | +}; |
91 | + |
92 | +class PendingConfigureEvent : |
93 | + public PendingEvent |
94 | +{ |
95 | +public: |
96 | + PendingConfigureEvent (Display *, Window, unsigned int, XWindowChanges *); |
97 | + virtual ~PendingConfigureEvent (); |
98 | + |
99 | + virtual bool match (XEvent *); |
100 | + bool matchVM (unsigned int valueMask); |
101 | + |
102 | + typedef boost::shared_ptr<PendingConfigureEvent> Ptr; |
103 | + |
104 | +protected: |
105 | + |
106 | + virtual Window getEventWindow (XEvent *); |
107 | + |
108 | +private: |
109 | + unsigned int mValueMask; |
110 | + XWindowChanges mXwc; |
111 | +}; |
112 | + |
113 | +class PendingEventQueue |
114 | +{ |
115 | +public: |
116 | + |
117 | + PendingEventQueue (Display *); |
118 | + virtual ~PendingEventQueue (); |
119 | + |
120 | + void add (PendingEvent::Ptr p); |
121 | + bool match (XEvent *); |
122 | + bool pending (); |
123 | + bool forEachIf (boost::function <bool (compiz::X11::PendingEvent::Ptr)>); |
124 | + |
125 | +protected: |
126 | + bool removeIfMatching (const PendingEvent::Ptr &p, XEvent *); |
127 | + |
128 | +private: |
129 | + std::list <PendingEvent::Ptr> mEvents; |
130 | +}; |
131 | + |
132 | +} |
133 | +} |
134 | + |
135 | class PrivateScreen : |
136 | public ValueHolder, |
137 | public CoreOptions |
138 | |
139 | === modified file 'src/privatewindow.h' |
140 | --- src/privatewindow.h 2011-09-29 03:29:41 +0000 |
141 | +++ src/privatewindow.h 2011-10-05 17:44:25 +0000 |
142 | @@ -292,7 +292,7 @@ |
143 | |
144 | typedef std::pair <XWindowChanges, unsigned int> XWCValueMask; |
145 | |
146 | - std::list <XWCValueMask> pendingConfigures; |
147 | + compiz::X11::PendingEventQueue pendingConfigures; |
148 | bool pendingPositionUpdates; |
149 | |
150 | char *startupId; |
151 | |
152 | === modified file 'src/window.cpp' |
153 | --- src/window.cpp 2011-10-03 12:58:36 +0000 |
154 | +++ src/window.cpp 2011-10-05 17:44:25 +0000 |
155 | @@ -841,9 +841,6 @@ |
156 | else |
157 | serverFrameGeometry.setHeight (xwc.height); |
158 | |
159 | - addPendingConfigure (xwc, valueMask); |
160 | - |
161 | - |
162 | /* Geometry is the same, so we're not going to get a ConfigureNotify |
163 | * event when the window is configured, which means that other plugins |
164 | * won't know that the client, frame and wrapper windows got shifted |
165 | @@ -900,6 +897,14 @@ |
166 | |
167 | } |
168 | |
169 | + gettimeofday (&lastConfigureRequest, NULL); |
170 | + compiz::X11::PendingEvent::Ptr pc = |
171 | + boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
172 | + new compiz::X11::PendingConfigureEvent ( |
173 | + screen->dpy (), serverFrame, valueMask, &xwc))); |
174 | + |
175 | + pendingConfigures.add (pc); |
176 | + |
177 | XSendEvent (screen->dpy (), screen->root (), false, |
178 | SubstructureNotifyMask, (XEvent *) &xev); |
179 | |
180 | @@ -907,7 +912,16 @@ |
181 | XSync (screen->dpy (), false); |
182 | } |
183 | else |
184 | + { |
185 | + gettimeofday (&lastConfigureRequest, NULL); |
186 | + compiz::X11::PendingEvent::Ptr pc = |
187 | + boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
188 | + new compiz::X11::PendingConfigureEvent ( |
189 | + screen->dpy (), serverFrame, valueMask, &xwc))); |
190 | + |
191 | + pendingConfigures.add (pc); |
192 | XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc); |
193 | + } |
194 | |
195 | if (shaded) |
196 | { |
197 | @@ -962,9 +976,6 @@ |
198 | else |
199 | serverFrameGeometry.setHeight (xwc.height); |
200 | |
201 | - addPendingConfigure (xwc, valueMask); |
202 | - |
203 | - |
204 | /* Geometry is the same, so we're not going to get a ConfigureNotify |
205 | * event when the window is configured, which means that other plugins |
206 | * won't know that the client, frame and wrapper windows got shifted |
207 | @@ -1021,6 +1032,14 @@ |
208 | |
209 | } |
210 | |
211 | + gettimeofday (&lastConfigureRequest, NULL); |
212 | + compiz::X11::PendingEvent::Ptr pc = |
213 | + boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
214 | + new compiz::X11::PendingConfigureEvent ( |
215 | + screen->dpy (), serverFrame, valueMask, &xwc))); |
216 | + |
217 | + pendingConfigures.add (pc); |
218 | + |
219 | XSendEvent (screen->dpy (), screen->root (), false, |
220 | SubstructureNotifyMask, (XEvent *) &xev); |
221 | |
222 | @@ -1028,7 +1047,17 @@ |
223 | XSync (screen->dpy (), false); |
224 | } |
225 | else |
226 | + { |
227 | + gettimeofday (&lastConfigureRequest, NULL); |
228 | + compiz::X11::PendingEvent::Ptr pc = |
229 | + boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
230 | + new compiz::X11::PendingConfigureEvent ( |
231 | + screen->dpy (), serverFrame, valueMask, &xwc))); |
232 | + |
233 | + pendingConfigures.add (pc); |
234 | + |
235 | XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc); |
236 | + } |
237 | |
238 | if (shaded) |
239 | { |
240 | @@ -2020,7 +2049,6 @@ |
241 | int x, y, width, height; |
242 | CompWindow *above; |
243 | unsigned int valueMask = 0; |
244 | - bool handled = false; |
245 | |
246 | if (!priv->frame) |
247 | return; |
248 | @@ -2052,61 +2080,15 @@ |
249 | valueMask |= CWSibling | CWStackMode; |
250 | } |
251 | |
252 | - for (std::list <XWCValueMask>::iterator it = pendingConfigures.begin (); |
253 | - it != pendingConfigures.end (); it++) |
254 | - { |
255 | - XWCValueMask &xwcvm = (*it); |
256 | - |
257 | - |
258 | - if (xwcvm.second != valueMask) |
259 | - { |
260 | - /* For stacking cases, if a client wants to raise or lower a window |
261 | - * then they don't need to specify CWSibling, so allow that to be |
262 | - * excluded in those cases */ |
263 | - |
264 | - if (ce->above == ROOTPARENT (screen->windows ().back ()) || |
265 | - ce->above == 0) |
266 | - { |
267 | - if ((xwcvm.second & ~(CWSibling) != valueMask)) |
268 | - continue; |
269 | - } |
270 | - else |
271 | - continue; |
272 | - } |
273 | - |
274 | - if (xwcvm.second & CWX && xwcvm.first.x != ce->x) |
275 | - continue; |
276 | - |
277 | - if (xwcvm.second & CWY && xwcvm.first.y != ce->y) |
278 | - continue; |
279 | - |
280 | - if (xwcvm.second & CWWidth && xwcvm.first.width != ce->width) |
281 | - continue; |
282 | - |
283 | - if (xwcvm.second & CWHeight && xwcvm.first.height != ce->height) |
284 | - continue; |
285 | - |
286 | - if (xwcvm.second & (CWStackMode | CWSibling) && xwcvm.first.sibling != ce->above) |
287 | - continue; |
288 | - |
289 | - /* Matched ConfigureWindow request to ConfigureNotify event |
290 | - * remove it from the list */ |
291 | - |
292 | - handled = true; |
293 | - |
294 | - pendingConfigures.erase (it); |
295 | - break; |
296 | - } |
297 | - |
298 | - if (!handled) |
299 | + if (!pendingConfigures.match ((XEvent *) ce)) |
300 | { |
301 | compLogMessage ("core", CompLogLevelWarn, "unhandled ConfigureNotify on 0x%x!", serverFrame); |
302 | - compLogMessage ("core", CompLogLevelWarn, "this should never happen. you should"\ |
303 | + compLogMessage ("core", CompLogLevelWarn, "this should never happen. you should "\ |
304 | "probably file a bug about this."); |
305 | #ifdef DEBUG |
306 | abort (); |
307 | #else |
308 | - pendingConfigures.clear (); |
309 | + pendingConfigures = compiz::X11::PendingEventQueue (screen->dpy ()); |
310 | #endif |
311 | } |
312 | |
313 | @@ -2145,7 +2127,7 @@ |
314 | if (above) |
315 | above->priv->updatePassiveButtonGrabs (); |
316 | |
317 | - if (pendingConfigures.empty ()) |
318 | + if (!pendingConfigures.pending ()) |
319 | { |
320 | /* Tell plugins its ok to start doing stupid things again but |
321 | * obviously FIXME */ |
322 | @@ -2195,7 +2177,7 @@ |
323 | * and a FIXME in any case, however, until we can break the API |
324 | * and remove CompWindow::move, this will need to be the case */ |
325 | |
326 | - if (!priv->pendingConfigures.size ()) |
327 | + if (!priv->pendingConfigures.pending ()) |
328 | { |
329 | priv->geometry.setX (priv->geometry.x () + dx); |
330 | priv->geometry.setY (priv->geometry.y () + dy); |
331 | @@ -2237,34 +2219,194 @@ |
332 | { |
333 | compLogMessage ("core", CompLogLevelWarn, "failed to receive ConfigureNotify event from request at %i (now: %i)\n", |
334 | priv->lastConfigureRequest.tv_usec, tv.tv_usec); |
335 | - priv->pendingConfigures.clear (); |
336 | + priv->pendingConfigures = compiz::X11::PendingEventQueue (screen->dpy ()); |
337 | } |
338 | } |
339 | } |
340 | } |
341 | |
342 | +bool |
343 | +compiz::X11::PendingEventQueue::pending () |
344 | +{ |
345 | + return !mEvents.empty (); |
346 | +} |
347 | + |
348 | void |
349 | -PrivateWindow::addPendingConfigure (XWindowChanges &xwc, unsigned int valueMask) |
350 | +compiz::X11::PendingEventQueue::add (PendingEvent::Ptr p) |
351 | +{ |
352 | + mEvents.push_back (p); |
353 | +} |
354 | + |
355 | +bool |
356 | +compiz::X11::PendingEventQueue::removeIfMatching (const PendingEvent::Ptr &p, XEvent *event) |
357 | +{ |
358 | + return p->match (event); |
359 | +} |
360 | + |
361 | +bool |
362 | +compiz::X11::PendingEventQueue::match (XEvent *event) |
363 | +{ |
364 | + unsigned int lastSize = mEvents.size (); |
365 | + |
366 | + mEvents.erase (std::remove_if (mEvents.begin (), mEvents.end (), |
367 | + boost::bind (&compiz::X11::PendingEventQueue::removeIfMatching, this, _1, event)), mEvents.end ()); |
368 | + |
369 | + return lastSize != mEvents.size (); |
370 | +} |
371 | + |
372 | +bool |
373 | +compiz::X11::PendingEventQueue::forEachIf (boost::function<bool (compiz::X11::PendingEvent::Ptr)> f) |
374 | +{ |
375 | + foreach (compiz::X11::PendingEvent::Ptr p, mEvents) |
376 | + { |
377 | + if (f (p)) |
378 | + return true; |
379 | + } |
380 | + |
381 | + return false; |
382 | +} |
383 | + |
384 | +compiz::X11::PendingEventQueue::PendingEventQueue (Display *d) |
385 | +{ |
386 | +} |
387 | + |
388 | +compiz::X11::PendingEventQueue::~PendingEventQueue () |
389 | +{ |
390 | +} |
391 | + |
392 | +Window |
393 | +compiz::X11::PendingEvent::getEventWindow (XEvent *event) |
394 | +{ |
395 | + return event->xany.window; |
396 | +} |
397 | + |
398 | +bool |
399 | +compiz::X11::PendingEvent::match (XEvent *event) |
400 | +{ |
401 | + if (event->xany.serial != mSerial) |
402 | + return false; |
403 | + if (getEventWindow (event)!= mWindow) |
404 | + return false; |
405 | + |
406 | + return true; |
407 | +} |
408 | + |
409 | +compiz::X11::PendingEvent::PendingEvent (Display *d, Window w) : |
410 | + mSerial (XNextRequest (d)), |
411 | + mWindow (w) |
412 | +{ |
413 | +} |
414 | + |
415 | +compiz::X11::PendingEvent::~PendingEvent () |
416 | +{ |
417 | +} |
418 | + |
419 | +Window |
420 | +compiz::X11::PendingConfigureEvent::getEventWindow (XEvent *event) |
421 | +{ |
422 | + return event->xconfigure.window; |
423 | +} |
424 | + |
425 | +bool |
426 | +compiz::X11::PendingConfigureEvent::matchVM (unsigned int valueMask) |
427 | +{ |
428 | + return valueMask & mValueMask; |
429 | +} |
430 | + |
431 | +bool |
432 | +compiz::X11::PendingConfigureEvent::match (XEvent *event) |
433 | +{ |
434 | + XConfigureEvent *ce = (XConfigureEvent *) event; |
435 | + bool matched = true; |
436 | + |
437 | + if (!compiz::X11::PendingEvent::match (event)) |
438 | + return false; |
439 | + |
440 | + if (mValueMask & CWX) |
441 | + if (ce->x != mXwc.x) |
442 | + matched = false; |
443 | + |
444 | + if (mValueMask & CWY) |
445 | + if (ce->y != mXwc.y) |
446 | + matched = false; |
447 | + |
448 | + if (mValueMask & CWWidth) |
449 | + if (ce->width != mXwc.width) |
450 | + matched = false; |
451 | + |
452 | + if (mValueMask & CWHeight) |
453 | + if (ce->height != mXwc.height) |
454 | + matched = false; |
455 | + |
456 | + if (mValueMask & CWBorderWidth) |
457 | + if (ce->border_width != mXwc.border_width) |
458 | + matched = false; |
459 | + |
460 | + if (mValueMask & (CWStackMode | CWSibling)) |
461 | + if (ce->above != mXwc.sibling) |
462 | + matched = false; |
463 | + |
464 | + /* Remove events from the queue |
465 | + * even if they didn't match what |
466 | + * we expected them to be, but still |
467 | + * complain about it */ |
468 | + if (!matched) |
469 | + { |
470 | + compLogMessage ("core", CompLogLevelWarn, "no exact match for ConfigureNotify on 0x%x!", mWindow); |
471 | + compLogMessage ("core", CompLogLevelWarn, "expected the following changes:"); |
472 | + if (mValueMask & CWX) |
473 | + compLogMessage ("core", CompLogLevelWarn, "x: %i", mXwc.x); |
474 | + if (mValueMask & CWY) |
475 | + compLogMessage ("core", CompLogLevelWarn, "y: %i", mXwc.y); |
476 | + if (mValueMask & CWWidth) |
477 | + compLogMessage ("core", CompLogLevelWarn, "width: %i", mXwc.width); |
478 | + if (mValueMask & CWHeight) |
479 | + compLogMessage ("core", CompLogLevelWarn, "height: %i", mXwc.height); |
480 | + if (mValueMask & CWBorderWidth) |
481 | + compLogMessage ("core", CompLogLevelWarn, "border: %i", mXwc.border_width); |
482 | + if (mValueMask & (CWStackMode | CWSibling)) |
483 | + compLogMessage ("core", CompLogLevelWarn, "sibling: 0x%x", mXwc.sibling); |
484 | + |
485 | + compLogMessage ("core", CompLogLevelWarn, "instead got:"); |
486 | + compLogMessage ("core", CompLogLevelWarn, "x: %i", ce->x); |
487 | + compLogMessage ("core", CompLogLevelWarn, "y: %i", ce->y); |
488 | + compLogMessage ("core", CompLogLevelWarn, "width: %i", ce->width); |
489 | + compLogMessage ("core", CompLogLevelWarn, "height: %i", ce->height); |
490 | + compLogMessage ("core", CompLogLevelWarn, "above: %i", ce->above); |
491 | + compLogMessage ("core", CompLogLevelWarn, "this should never happen. you should "\ |
492 | + "probably file a bug about this."); |
493 | + } |
494 | + |
495 | + return true; |
496 | +} |
497 | + |
498 | +compiz::X11::PendingConfigureEvent::PendingConfigureEvent (Display *d, |
499 | + Window w, |
500 | + unsigned int valueMask, |
501 | + XWindowChanges *xwc) : |
502 | + compiz::X11::PendingEvent::PendingEvent (d, w), |
503 | + mValueMask (valueMask), |
504 | + mXwc (*xwc) |
505 | { |
506 | CompOption::Vector options; |
507 | CompOption::Value v; |
508 | |
509 | options.push_back (CompOption ("window", CompOption::TypeInt)); |
510 | - v.set ((int) id); |
511 | + v.set ((int) w); |
512 | options.back ().set (v); |
513 | options.push_back (CompOption ("active", CompOption::TypeInt)); |
514 | v.set ((int) 1); |
515 | options.back ().set (v); |
516 | |
517 | - gettimeofday (&lastConfigureRequest, NULL); |
518 | - |
519 | /* Notify other plugins that it is unsafe to change geometry or serverGeometry |
520 | * FIXME: That API should not be accessible to plugins, this is a hack to avoid |
521 | * breaking ABI */ |
522 | |
523 | screen->handleCompizEvent ("core", "lock_position", options); |
524 | +} |
525 | |
526 | - priv->pendingConfigures.push_back (XWCValueMask (xwc, valueMask)); |
527 | +compiz::X11::PendingConfigureEvent::~PendingConfigureEvent () |
528 | +{ |
529 | } |
530 | |
531 | void |
532 | @@ -2275,7 +2417,7 @@ |
533 | unsigned int valueMask = CWX | CWY; |
534 | XWindowChanges xwc; |
535 | |
536 | - if (priv->pendingPositionUpdates && priv->pendingConfigures.empty ()) |
537 | + if (priv->pendingPositionUpdates && !priv->pendingConfigures.pending ()) |
538 | { |
539 | if (priv->serverFrameGeometry.x () == priv->frameGeometry.x ()) |
540 | valueMask &= ~(CWX); |
541 | @@ -2290,8 +2432,6 @@ |
542 | * larger changes to the window movement system. */ |
543 | if (valueMask) |
544 | { |
545 | - priv->addPendingConfigure (xwc, 0); |
546 | - |
547 | priv->serverGeometry.setX (priv->geometry.x ()); |
548 | priv->serverGeometry.setY (priv->geometry.y ()); |
549 | priv->serverFrameGeometry.setX (priv->frameGeometry.x ()); |
550 | @@ -2300,6 +2440,14 @@ |
551 | xwc.x = priv->serverFrameGeometry.x (); |
552 | xwc.y = priv->serverFrameGeometry.y (); |
553 | |
554 | + gettimeofday (&priv->lastConfigureRequest, NULL); |
555 | + compiz::X11::PendingEvent::Ptr pc = |
556 | + boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
557 | + new compiz::X11::PendingConfigureEvent ( |
558 | + screen->dpy (), priv->serverFrame, 0, &xwc))); |
559 | + |
560 | + priv->pendingConfigures.add (pc); |
561 | + |
562 | XConfigureWindow (screen->dpy (), ROOTPARENT (this), valueMask, &xwc); |
563 | |
564 | if (priv->serverFrame) |
565 | @@ -3103,6 +3251,13 @@ |
566 | return m; |
567 | } |
568 | |
569 | +static bool isPendingRestack (compiz::X11::PendingEvent::Ptr p) |
570 | +{ |
571 | + compiz::X11::PendingConfigureEvent::Ptr pc = boost::shared_static_cast <compiz::X11::PendingConfigureEvent> (p); |
572 | + |
573 | + return pc->matchVM (CWStackMode | CWSibling); |
574 | +} |
575 | + |
576 | void |
577 | PrivateWindow::reconfigureXWindow (unsigned int valueMask, |
578 | XWindowChanges *xwc) |
579 | @@ -3137,18 +3292,7 @@ |
580 | /* check if the sibling is also pending a restack, |
581 | * if not, then setting this bit is useless */ |
582 | |
583 | - bool pendingRestack = false; |
584 | - |
585 | - foreach (XWCValueMask &xwcvm, window->serverPrev->priv->pendingConfigures) |
586 | - { |
587 | - if (xwcvm.second & (CWSibling | CWStackMode)) |
588 | - { |
589 | - pendingRestack = true; |
590 | - break; |
591 | - } |
592 | - } |
593 | - |
594 | - if (!pendingRestack) |
595 | + if (window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1))) |
596 | valueMask &= ~(CWSibling | CWStackMode); |
597 | } |
598 | |
599 | @@ -3252,7 +3396,14 @@ |
600 | wc.width = serverFrameGeometry.width (); |
601 | wc.height = serverFrameGeometry.height (); |
602 | |
603 | - addPendingConfigure (wc, frameValueMask); |
604 | + gettimeofday (&lastConfigureRequest, NULL); |
605 | + |
606 | + compiz::X11::PendingEvent::Ptr pc = |
607 | + boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
608 | + new compiz::X11::PendingConfigureEvent ( |
609 | + screen->dpy (), priv->serverFrame, frameValueMask, &wc))); |
610 | + |
611 | + pendingConfigures.add (pc); |
612 | |
613 | XConfigureWindow (screen->dpy (), serverFrame, frameValueMask, &wc); |
614 | } |
615 | @@ -4041,31 +4192,29 @@ |
616 | |
617 | lxwc.stack_mode = Below; |
618 | |
619 | + if (serverFrame) |
620 | + { |
621 | + gettimeofday (&lastConfigureRequest, NULL); |
622 | + compiz::X11::PendingEvent::Ptr pc = |
623 | + boost::shared_static_cast<compiz::X11::PendingEvent> (compiz::X11::PendingConfigureEvent::Ptr ( |
624 | + new compiz::X11::PendingConfigureEvent ( |
625 | + screen->dpy (), serverFrame, valueMask, &lxwc))); |
626 | + |
627 | + pendingConfigures.add (pc); |
628 | + } |
629 | + |
630 | /* Below with no sibling puts the window at the bottom |
631 | * of the stack */ |
632 | XConfigureWindow (screen->dpy (), ROOTPARENT (window), valueMask, &lxwc); |
633 | |
634 | - if (serverFrame) |
635 | - priv->addPendingConfigure (lxwc, CWStackMode); |
636 | - |
637 | /* Update the list of windows last sent to the server */ |
638 | screen->unhookServerWindow (window); |
639 | screen->insertServerWindow (window, 0); |
640 | } |
641 | else if (sibling) |
642 | { |
643 | - bool pendingRestacks = false; |
644 | - |
645 | - foreach (XWCValueMask &xwcvm, sibling->priv->pendingConfigures) |
646 | - { |
647 | - if (xwcvm.second & (CWSibling | CWStackMode)) |
648 | - { |
649 | - pendingRestacks = true; |
650 | - break; |
651 | - } |
652 | - } |
653 | - |
654 | - if (sibling->priv->id != window->serverPrev->priv->id || pendingRestacks) |
655 | + if (sibling->priv->id != window->serverPrev->priv->id || |
656 | + window->serverPrev->priv->pendingConfigures.forEachIf (boost::bind (isPendingRestack, _1))) |
657 | { |
658 | mask |= CWSibling | CWStackMode; |
659 | |
660 | @@ -6447,6 +6596,7 @@ |
661 | |
662 | pendingUnmaps (0), |
663 | pendingMaps (0), |
664 | + pendingConfigures (screen->dpy ()), |
665 | pendingPositionUpdates (false), |
666 | |
667 | startupId (0), |
+1