Merge lp:~compiz-team/compiz-core/compiz-core.fix_853734 into lp:~compiz-team/compiz-core/compiz-core.stack_sync_fix

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz-core/compiz-core.fix_853734
Merge into: lp:~compiz-team/compiz-core/compiz-core.stack_sync_fix
Diff against target: 483 lines (+162/-72)
3 files modified
src/privatewindow.h (+1/-0)
src/window.cpp (+153/-64)
src/windowgeometry.cpp (+8/-8)
To merge this branch: bzr merge lp:~compiz-team/compiz-core/compiz-core.fix_853734
Reviewer Review Type Date Requested Status
Compiz Maintainers Pending
Review via email: mp+75992@code.launchpad.net

This proposal has been superseded by a proposal from 2011-09-19.

Commit message

Ensure that we update frame regions correctly by doing the following:
 * Only update frame regions when we get an event that something changed
   server side (eg don't immediately update the region once we issue
   a ConfigureWindow request)
 * Keep track of the changes in the input extents
 * Ensure that a synthetic ConfigureNotify is sent in cases where the resized
   frame window will exactly match its last size such that the client is
   positioned correctly inside the frame

Description of the change

  Ensure that we update frame regions correctly by doing the following:
   * Only update frame regions when we get an event that something changed
     server side (eg don't immediately update the region once we issue
     a ConfigureWindow request)
   * Keep track of the changes in the input extents
   * Ensure that a synthetic ConfigureNotify is sent in cases where the resized
     frame window will exactly match its last size such that the client is
     positioned correctly inside the frame

To post a comment you must log in.
Revision history for this message
Mirco Müller (macslow) wrote :

I'm not able to compile compiz here atm. But what I suggest is to initialize all declared variables.

Revision history for this message
Mikkel Kamstrup Erlandsen (kamstrup) wrote :

I can confirm that maximize->minimize works fine here. And generally everything seems to work fine. Haven't had time to do code review.

2818. By Sam Spilsbury

Merge lp:~compiz-team/compiz-core/compiz-core.fix_853734

Unmerged revisions

2818. By Sam Spilsbury

Merge lp:~compiz-team/compiz-core/compiz-core.fix_853734

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/privatewindow.h'
2--- src/privatewindow.h 2011-09-14 14:53:49 +0000
3+++ src/privatewindow.h 2011-09-19 12:50:38 +0000
4@@ -293,6 +293,7 @@
5 bool alive;
6
7 CompWindowExtents input;
8+ CompWindowExtents serverInput;
9 CompWindowExtents border;
10 CompWindowExtents output;
11
12
13=== modified file 'src/window.cpp'
14--- src/window.cpp 2011-09-15 09:17:57 +0000
15+++ src/window.cpp 2011-09-19 12:50:38 +0000
16@@ -769,18 +769,18 @@
17 if (!serverFrame)
18 return;
19
20- if (input.left || input.right || input.top || input.bottom)
21+ if (serverInput.left || serverInput.right || serverInput.top || serverInput.bottom)
22 {
23 int x, y, width, height;
24 int bw = serverGeometry.border () * 2;
25
26- x = serverGeometry.x () - input.left;
27- y = serverGeometry.y () - input.top;
28- width = serverGeometry.width () + input.left + input.right + bw;
29- height = serverGeometry.height () + input.top + input.bottom + bw;
30+ x = serverGeometry.x () - serverInput.left;
31+ y = serverGeometry.y () - serverInput.top;
32+ width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
33+ height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
34
35 if (shaded)
36- height = input.top + input.bottom;
37+ height = serverInput.top + serverInput.bottom;
38
39 /* Geometry is the same, so we're not going to get a ConfigureNotify
40 * event when the window is configured, which means that other plugins
41@@ -793,9 +793,9 @@
42 {
43 XConfigureEvent xev;
44 XWindowAttributes attrib;
45- unsigned int nchildren;
46- Window rootRet, parentRet;
47- Window *children;
48+ unsigned int nchildren = 0;
49+ Window rootRet = 0, parentRet = 0;
50+ Window *children = NULL;
51
52 xev.type = ConfigureNotify;
53 xev.event = screen->root ();
54@@ -857,14 +857,12 @@
55 else
56 {
57 XMapWindow (screen->dpy (), wrapper);
58- XMoveResizeWindow (screen->dpy (), wrapper, input.left, input.top,
59+ XMoveResizeWindow (screen->dpy (), wrapper, serverInput.left, serverInput.top,
60 serverGeometry.width (), serverGeometry.height ());
61 }
62- XMoveResizeWindow (screen->dpy (), id, 0, 0,
63+ XMoveResizeWindow (screen->dpy (), id, 0, 0,
64 serverGeometry.width (), serverGeometry.height ());
65- window->sendConfigureNotify ();
66-
67- window->updateFrameRegion ();
68+ window->sendConfigureNotify ();
69 window->windowNotify (CompWindowNotifyFrameUpdate);
70 }
71 else
72@@ -880,7 +878,74 @@
73 if (shaded)
74 height = 0;
75
76- XMoveResizeWindow (screen->dpy (), serverFrame, x, y, width, height);
77+ /* Geometry is the same, so we're not going to get a ConfigureNotify
78+ * event when the window is configured, which means that other plugins
79+ * won't know that the client, frame and wrapper windows got shifted
80+ * around (and might result in display corruption, eg in OpenGL */
81+ if (geometry.x () - input.left == x &&
82+ geometry.y () - input.top == y &&
83+ geometry.width () + input.left + input.right + bw == width &&
84+ geometry.height () + input.top + input.bottom + bw == height)
85+ {
86+ XConfigureEvent xev;
87+ XWindowAttributes attrib;
88+ unsigned int nchildren = 0;
89+ Window rootRet = 0, parentRet = 0;
90+ Window *children = NULL;
91+
92+ xev.type = ConfigureNotify;
93+ xev.event = screen->root ();
94+ xev.window = priv->serverFrame;
95+
96+ XGrabServer (screen->dpy ());
97+
98+ if (XGetWindowAttributes (screen->dpy (), priv->serverFrame, &attrib))
99+ {
100+ xev.x = attrib.x;
101+ xev.y = attrib.y;
102+ xev.width = attrib.width;
103+ xev.height = attrib.height;
104+ xev.border_width = attrib.border_width;
105+ xev.above = None;
106+
107+ /* We need to ensure that the stacking order is
108+ * based on the current server stacking order so
109+ * find the sibling to this window's frame in the
110+ * server side stack and stack above that */
111+ XQueryTree (screen->dpy (), screen->root (), &rootRet, &parentRet, &children, &nchildren);
112+
113+ if (nchildren)
114+ {
115+ for (unsigned int i = 0; i < nchildren; i++)
116+ {
117+ if (i + 1 == nchildren ||
118+ children[i + 1] == ROOTPARENT (window))
119+ {
120+ xev.above = children[i];
121+ break;
122+ }
123+ }
124+ }
125+
126+ if (children)
127+ XFree (children);
128+
129+ if (!xev.above)
130+ xev.above = (window->serverPrev) ? ROOTPARENT (window->serverPrev) : None;
131+
132+ xev.override_redirect = priv->attrib.override_redirect;
133+
134+ }
135+
136+ XSendEvent (screen->dpy (), screen->root (), false,
137+ SubstructureNotifyMask, (XEvent *) &xev);
138+
139+ XUngrabServer (screen->dpy ());
140+ XSync (screen->dpy (), false);
141+ }
142+ else
143+ XMoveResizeWindow (screen->dpy (), serverFrame, x, y, width, height);
144+
145 if (shaded)
146 {
147 XUnmapWindow (screen->dpy (), wrapper);
148@@ -892,10 +957,9 @@
149 serverGeometry.width (), serverGeometry.height ());
150 }
151
152- XMoveResizeWindow (screen->dpy (), id, 0, 0,
153+ XMoveResizeWindow (screen->dpy (), id, 0, 0,
154 serverGeometry.width (), serverGeometry.height ());
155- window->sendConfigureNotify ();
156- frameRegion = CompRegion ();
157+ window->sendConfigureNotify ();
158 window->windowNotify (CompWindowNotifyFrameUpdate);
159 }
160 window->recalcActions ();
161@@ -1356,6 +1420,7 @@
162 * server configuration */
163
164 XGrabServer (screen->dpy ());
165+ XSync (screen->dpy (), false);
166
167 if (XGetWindowAttributes (screen->dpy (), priv->id, &attrib))
168 {
169@@ -1631,6 +1696,17 @@
170 bool
171 CompWindow::resize (CompWindow::Geometry gm)
172 {
173+ /* Input extents are now the last thing sent
174+ * from the server. This might not work in some
175+ * cases though because setWindowFrameExtents may
176+ * be called more than once in an event processing
177+ * cycle so every set of input extents up until the
178+ * last one will be invalid. The real solution
179+ * here is to handle ConfigureNotify events on
180+ * frame windows and client windows separately */
181+
182+ priv->input = priv->serverInput;
183+
184 if (priv->geometry.width () != gm.width () ||
185 priv->geometry.height () != gm.height () ||
186 priv->geometry.border () != gm.border ())
187@@ -1662,7 +1738,6 @@
188 resizeNotify (dx, dy, dwidth, dheight);
189
190 priv->invisible = WINDOW_INVISIBLE (priv);
191- priv->updateFrameWindow ();
192 }
193 else if (priv->geometry.x () != gm.x () || priv->geometry.y () != gm.y ())
194 {
195@@ -1674,6 +1749,8 @@
196 move (dx, dy);
197 }
198
199+ updateFrameRegion ();
200+
201 return true;
202 }
203
204@@ -1830,10 +1907,15 @@
205 if (!priv->frame)
206 return;
207
208- x = ce->x + priv->input.left;
209- y = ce->y + priv->input.top;
210- width = ce->width - priv->serverGeometry.border () * 2 - priv->input.left - priv->input.right;
211- height = ce->height - priv->serverGeometry.border () * 2 - priv->input.top - priv->input.bottom;
212+ /* subtract the input extents last sent to the
213+ * server to calculate the client size and then
214+ * re-sync the input extents and extents last
215+ * sent to server on resize () */
216+
217+ x = ce->x + priv->serverInput.left;
218+ y = ce->y + priv->serverInput.top;
219+ width = ce->width - priv->serverGeometry.border () * 2 - priv->serverInput.left - priv->serverInput.right;
220+ height = ce->height - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
221
222 if (priv->syncWait)
223 {
224@@ -1903,13 +1985,13 @@
225 priv->serverGeometry.setY (priv->geometry.y ());
226
227 XMoveWindow (screen->dpy (), ROOTPARENT (this),
228- priv->geometry.x () - priv->input.left,
229- priv->geometry.y () - priv->input.top);
230+ priv->serverGeometry.x () - priv->serverInput.left,
231+ priv->serverGeometry.y () - priv->serverInput.top);
232
233 if (priv->serverFrame)
234 {
235 XMoveWindow (screen->dpy (), priv->wrapper,
236- priv->input.left, priv->input.top);
237+ priv->serverInput.left, priv->serverInput.top);
238 sendConfigureNotify ();
239 }
240 }
241@@ -2666,20 +2748,22 @@
242 {
243 XWindowChanges wc = *xwc;
244
245- wc.x -= input.left - serverGeometry.border ();
246- wc.y -= input.top - serverGeometry.border ();
247- wc.width += input.left + input.right + serverGeometry.border ();
248- wc.height += input.top + input.bottom + serverGeometry.border ();
249+ wc.x -= serverInput.left - serverGeometry.border ();
250+ wc.y -= serverInput.top - serverGeometry.border ();
251+ wc.width += serverInput.left + serverInput.right + serverGeometry.border ();
252+ wc.height += serverInput.top + serverInput.bottom + serverGeometry.border ();
253
254 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &wc);
255 valueMask &= ~(CWSibling | CWStackMode);
256
257- xwc->x = input.left;
258- xwc->y = input.top;
259+ xwc->x = serverInput.left;
260+ xwc->y = serverInput.top;
261 XConfigureWindow (screen->dpy (), wrapper, valueMask, xwc);
262
263 xwc->x = 0;
264 xwc->y = 0;
265+
266+ window->sendConfigureNotify ();
267 }
268
269 XConfigureWindow (screen->dpy (), id, valueMask, xwc);
270@@ -2963,8 +3047,8 @@
271 {
272 saveGeometry (CWY | CWHeight);
273
274- xwc->height = workArea.height () - input.top -
275- input.bottom - old.border () * 2;
276+ xwc->height = workArea.height () - serverInput.top -
277+ serverInput.bottom - old.border () * 2;
278
279 mask |= CWHeight;
280 }
281@@ -2977,8 +3061,8 @@
282 {
283 saveGeometry (CWX | CWWidth);
284
285- xwc->width = workArea.width () - input.left -
286- input.right - old.border () * 2;
287+ xwc->width = workArea.width () - serverInput.left -
288+ serverInput.right - old.border () * 2;
289
290 mask |= CWWidth;
291 }
292@@ -3045,9 +3129,9 @@
293
294 if (state & CompWindowStateMaximizedVertMask)
295 {
296- if (old.y () < y + workArea.y () + input.top)
297+ if (old.y () < y + workArea.y () + serverInput.top)
298 {
299- xwc->y = y + workArea.y () + input.top;
300+ xwc->y = y + workArea.y () + serverInput.top;
301 mask |= CWY;
302 }
303 else
304@@ -3055,16 +3139,16 @@
305 height = xwc->height + old.border () * 2;
306
307 max = y + workArea.bottom ();
308- if (old.y () + (int) old.height () + input.bottom > max)
309+ if (old.y () + (int) old.height () + serverInput.bottom > max)
310 {
311- xwc->y = max - height - input.bottom;
312+ xwc->y = max - height - serverInput.bottom;
313 mask |= CWY;
314 }
315- else if (old.y () + height + input.bottom > max)
316+ else if (old.y () + height + serverInput.bottom > max)
317 {
318 xwc->y = y + workArea.y () +
319- (workArea.height () - input.top - height -
320- input.bottom) / 2 + input.top;
321+ (workArea.height () - serverInput.top - height -
322+ serverInput.bottom) / 2 + serverInput.top;
323 mask |= CWY;
324 }
325 }
326@@ -3072,9 +3156,9 @@
327
328 if (state & CompWindowStateMaximizedHorzMask)
329 {
330- if (old.x () < x + workArea.x () + input.left)
331+ if (old.x () < x + workArea.x () + serverInput.left)
332 {
333- xwc->x = x + workArea.x () + input.left;
334+ xwc->x = x + workArea.x () + serverInput.left;
335 mask |= CWX;
336 }
337 else
338@@ -3082,16 +3166,16 @@
339 width = xwc->width + old.border () * 2;
340
341 max = x + workArea.right ();
342- if (old.x () + (int) old.width () + input.right > max)
343+ if (old.x () + (int) old.width () + serverInput.right > max)
344 {
345- xwc->x = max - width - input.right;
346+ xwc->x = max - width - serverInput.right;
347 mask |= CWX;
348 }
349- else if (old.x () + width + input.right > max)
350+ else if (old.x () + width + serverInput.right > max)
351 {
352 xwc->x = x + workArea.x () +
353- (workArea.width () - input.left - width -
354- input.right) / 2 + input.left;
355+ (workArea.width () - serverInput.left - width -
356+ serverInput.right) / 2 + serverInput.left;
357 mask |= CWX;
358 }
359 }
360@@ -3168,15 +3252,15 @@
361 case NorthGravity:
362 case NorthEastGravity:
363 if (xwcm & CWY)
364- newY = xwc->y + priv->input.top * direction;
365+ newY = xwc->y + priv->serverInput.top * direction;
366 break;
367
368 case WestGravity:
369 case CenterGravity:
370 case EastGravity:
371 if (xwcm & CWY)
372- newY -= (xwc->height / 2 - priv->input.top +
373- (priv->input.top + priv->input.bottom) / 2) * direction;
374+ newY -= (xwc->height / 2 - priv->serverInput.top +
375+ (priv->serverInput.top + priv->serverInput.bottom) / 2) * direction;
376 else
377 newY -= ((xwc->height - priv->serverGeometry.height ()) / 2) * direction;
378 break;
379@@ -3185,7 +3269,7 @@
380 case SouthGravity:
381 case SouthEastGravity:
382 if (xwcm & CWY)
383- newY -= xwc->height + priv->input.bottom * direction;
384+ newY -= xwc->height + priv->serverInput.bottom * direction;
385 else
386 newY -= (xwc->height - priv->serverGeometry.height ()) * direction;
387 break;
388@@ -3650,14 +3734,14 @@
389 y2 = y1 + screen->workArea ().height () + screen->vpSize ().height () *
390 screen->height ();
391
392- if (serverGeometry.x () - input.left >= x2)
393+ if (serverGeometry.x () - serverInput.left >= x2)
394 dx = (x2 - 25) - serverGeometry.x ();
395- else if (serverGeometry.x () + width + input.right <= x1)
396+ else if (serverGeometry.x () + width + serverInput.right <= x1)
397 dx = (x1 + 25) - (serverGeometry.x () + width);
398
399- if (serverGeometry.y () - input.top >= y2)
400+ if (serverGeometry.y () - serverInput.top >= y2)
401 dy = (y2 - 25) - serverGeometry.y ();
402- else if (serverGeometry.y () + height + input.bottom <= y1)
403+ else if (serverGeometry.y () + height + serverInput.bottom <= y1)
404 dy = (y1 + 25) - (serverGeometry.y () + height);
405
406 if (dx || dy)
407@@ -5315,7 +5399,7 @@
408 CompWindowExtents &
409 CompWindow::input () const
410 {
411- return priv->input;
412+ return priv->serverInput;
413 }
414
415 CompWindowExtents &
416@@ -5786,6 +5870,11 @@
417 input.top = 0;
418 input.bottom = 0;
419
420+ serverInput.left = 0;
421+ serverInput.right = 0;
422+ serverInput.top = 0;
423+ serverInput.bottom = 0;
424+
425 border.top = 0;
426 border.bottom = 0;
427 border.left = 0;
428@@ -5979,14 +6068,14 @@
429 if (!i)
430 i = b;
431
432- if (priv->input.left != i->left ||
433- priv->input.right != i->right ||
434- priv->input.top != i->top ||
435- priv->input.bottom != i->bottom)
436+ if (priv->serverInput.left != i->left ||
437+ priv->serverInput.right != i->right ||
438+ priv->serverInput.top != i->top ||
439+ priv->serverInput.bottom != i->bottom)
440 {
441 unsigned long data[4];
442
443- priv->input = *i;
444+ priv->serverInput = *i;
445 priv->border = *b;
446
447 recalcActions ();
448
449=== modified file 'src/windowgeometry.cpp'
450--- src/windowgeometry.cpp 2011-04-30 13:40:41 +0000
451+++ src/windowgeometry.cpp 2011-09-19 12:50:38 +0000
452@@ -189,23 +189,23 @@
453 CompRect
454 CompWindow::inputRect () const
455 {
456- return CompRect (priv->geometry.x () - priv->geometry.border () - priv->input.left,
457- priv->geometry.y () - priv->geometry.border () - priv->input.top,
458+ return CompRect (priv->geometry.x () - priv->geometry.border () - priv->serverInput.left,
459+ priv->geometry.y () - priv->geometry.border () - priv->serverInput.top,
460 priv->geometry.width () + priv->geometry.border () * 2 +
461- priv->input.left + priv->input.right,
462+ priv->serverInput.left + priv->serverInput.right,
463 priv->geometry.height () +priv->geometry.border () * 2 +
464- priv->input.top + priv->input.bottom);
465+ priv->serverInput.top + priv->serverInput.bottom);
466 }
467
468 CompRect
469 CompWindow::serverInputRect () const
470 {
471- return CompRect (priv->serverGeometry.x () - priv->serverGeometry.border () - priv->input.left,
472- priv->serverGeometry.y () - priv->serverGeometry.border () - priv->input.top,
473+ return CompRect (priv->serverGeometry.x () - priv->serverGeometry.border () - priv->serverInput.left,
474+ priv->serverGeometry.y () - priv->serverGeometry.border () - priv->serverInput.top,
475 priv->serverGeometry.width () + priv->serverGeometry.border () * 2 +
476- priv->input.left + priv->input.right,
477+ priv->serverInput.left + priv->serverInput.right,
478 priv->serverGeometry.height () + priv->serverGeometry.border () * 2 +
479- priv->input.top + priv->input.bottom);
480+ priv->serverInput.top + priv->serverInput.bottom);
481 }
482
483 CompRect

Subscribers

People subscribed via source and target branches

to all changes: