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

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 2827
Proposed branch: lp:~compiz-team/compiz-core/compiz-core.fix_853734
Merge into: lp:compiz-core/0.9.5
Diff against target: 501 lines (+204/-53) (has conflicts)
3 files modified
src/privatewindow.h (+1/-0)
src/window.cpp (+195/-45)
src/windowgeometry.cpp (+8/-8)
Text conflict in src/window.cpp
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+76020@code.launchpad.net

This proposal supersedes a proposal from 2011-09-19.

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 : Posted in a previous version of this proposal

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 : Posted in a previous version of this proposal

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

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

Subscribers

People subscribed via source and target branches