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

Proposed by Sam Spilsbury
Status: Superseded
Proposed branch: lp:~compiz-team/compiz-core/compiz-core.fix_865863
Merge into: lp:compiz-core/0.9.5
Diff against target: 429 lines (+140/-104)
3 files modified
plugins/decor/src/decor.cpp (+7/-6)
src/event.cpp (+59/-51)
src/window.cpp (+74/-47)
To merge this branch: bzr merge lp:~compiz-team/compiz-core/compiz-core.fix_865863
Reviewer Review Type Date Requested Status
Compiz Maintainers Pending
Review via email: mp+78031@code.launchpad.net

This proposal has been superseded by a proposal from 2011-10-04.

Description of the change

Fixes Bug 865863

Handle windows that reparent into the root window correclty

To post a comment you must log in.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/decor/src/decor.cpp'
2--- plugins/decor/src/decor.cpp 2011-09-30 04:54:21 +0000
3+++ plugins/decor/src/decor.cpp 2011-10-04 03:31:23 +0000
4@@ -259,8 +259,6 @@
5 if (wd &&
6 wd->decor->type == WINDOW_DECORATION_TYPE_PIXMAP)
7 {
8-
9-
10 CompRect box;
11 GLTexture::MatrixList ml (1);
12 mask |= PAINT_WINDOW_BLEND_MASK;
13@@ -1019,10 +1017,13 @@
14 for (i = 0; i < wd->nQuad; i++)
15 {
16 int x, y;
17-
18- /* Recompute scaled quad box */
19- computeQuadBox (&wd->decor->quad[i], window->size ().width (),
20- window->size ().height (),
21+ unsigned int width = window->size ().width ();
22+ unsigned int height = window->size ().height ();
23+
24+ if (window->shaded ())
25+ height = 0;
26+
27+ computeQuadBox (&wd->decor->quad[i], width, height,
28 &x1, &y1, &x2, &y2, &sx, &sy);
29
30 /* Translate by x and y points of this window */
31
32=== modified file 'src/event.cpp'
33--- src/event.cpp 2011-09-19 13:00:51 +0000
34+++ src/event.cpp 2011-10-04 03:31:23 +0000
35@@ -1240,59 +1240,66 @@
36 }
37 break;
38 case ReparentNotify:
39+
40 w = findWindow (event->xreparent.window);
41
42- /* It is possible that some plugin might call
43- * w->destroy () before the window actually receives
44- * its first ReparentNotify event which would mean
45- * that it is already in the list of destroyed
46- * windows, so check that list too */
47+ /* If this window isn't part of our tracked window
48+ * list and was reparented into the root window then
49+ * we need to track it */
50 if (!w)
51 {
52- foreach (CompWindow *dw, screen->priv->destroyedWindows)
53- {
54- if (dw->priv->serverId == event->xdestroywindow.window)
55- {
56- w = dw;
57- break;
58- }
59- }
60- }
61-
62- if (!w && event->xreparent.parent == priv->root)
63- {
64- /* Failure means that window has been destroyed. We still have to add
65- * the window to the window list as we might get configure requests
66- * which require us to stack other windows relative to it. Setting
67- * some default values if this is the case. */
68- if (!XGetWindowAttributes (priv->dpy, event->xcreatewindow.window, &wa))
69- priv->setDefaultWindowAttributes (&wa);
70-
71- CoreWindow *cw = new CoreWindow (event->xcreatewindow.window);
72- cw->manage (priv->getTopWindow (), wa);
73-
74- priv->createdWindows.remove (cw);
75- delete cw;
76- }
77- else if (!(event->xreparent.parent == priv->root))
78- {
79- /* This is the only case where a window is removed but not
80- destroyed. We must remove our event mask and all passive
81- grabs. */
82-
83- if (w)
84- {
85- if (event->xreparent.parent != w->priv->wrapper)
86- {
87- w->moveInputFocusToOtherWindow ();
88- w->destroy ();
89-
90- XSelectInput (priv->dpy, w->id (), NoEventMask);
91- XShapeSelectInput (priv->dpy, w->id (), NoEventMask);
92- XUngrabButton (priv->dpy, AnyButton, AnyModifier, w->id ());
93- }
94- }
95- }
96+ if (event->xreparent.parent == priv->root)
97+ {
98+ /* Failure means that window has been destroyed. We still have to add
99+ * the window to the window list as we might get configure requests
100+ * which require us to stack other windows relative to it. Setting
101+ * some default values if this is the case. */
102+ if (!XGetWindowAttributes (priv->dpy, event->xcreatewindow.window, &wa))
103+ priv->setDefaultWindowAttributes (&wa);
104+
105+ CoreWindow *cw = new CoreWindow (event->xcreatewindow.window);
106+ cw->manage (priv->getTopWindow (), wa);
107+
108+ priv->createdWindows.remove (cw);
109+ delete cw;
110+ break;
111+ }
112+ else
113+ {
114+ /* It is possible that some plugin might call
115+ * w->destroy () before the window actually receives
116+ * its first ReparentNotify event which would mean
117+ * that it is already in the list of destroyed
118+ * windows, so check that list too */
119+
120+ foreach (CompWindow *dw, screen->priv->destroyedWindows)
121+ {
122+ if (dw->priv->serverId == event->xreparent.window)
123+ {
124+ w = dw;
125+ break;
126+ }
127+ }
128+ }
129+ }
130+
131+ /* This is the only case where a window is removed but not
132+ destroyed. We must remove our event mask and all passive
133+ grabs. */
134+
135+ if (w)
136+ {
137+ if (event->xreparent.parent != w->priv->wrapper)
138+ {
139+ w->moveInputFocusToOtherWindow ();
140+ w->destroy ();
141+
142+ XSelectInput (priv->dpy, w->id (), NoEventMask);
143+ XShapeSelectInput (priv->dpy, w->id (), NoEventMask);
144+ XUngrabButton (priv->dpy, AnyButton, AnyModifier, w->id ());
145+ }
146+ }
147+
148 break;
149 case CirculateNotify:
150 w = findWindow (event->xcirculate.window);
151@@ -1831,7 +1838,7 @@
152 * and the passive button grabs and then we will
153 * get the DestroyNotify later and change the focus
154 * there
155- */
156+ */
157
158 if (wa.root == priv->root)
159 {
160@@ -1845,7 +1852,6 @@
161 if (w->id () != priv->activeWindow)
162 {
163 CompWindow *active = screen->findWindow (priv->activeWindow);
164- w->windowNotify (CompWindowNotifyFocusChange);
165
166 priv->activeWindow = w->id ();
167 w->priv->activeNum = priv->activeNum++;
168@@ -1861,6 +1867,8 @@
169 Atoms::winActive,
170 XA_WINDOW, 32, PropModeReplace,
171 (unsigned char *) &priv->activeWindow, 1);
172+
173+ w->windowNotify (CompWindowNotifyFocusChange);
174 }
175
176 state &= ~CompWindowStateDemandsAttentionMask;
177
178=== modified file 'src/window.cpp'
179--- src/window.cpp 2011-09-30 04:54:21 +0000
180+++ src/window.cpp 2011-10-04 03:31:23 +0000
181@@ -604,7 +604,7 @@
182 break;
183 }
184
185- if (priv->input.top)
186+ if (priv->serverInput.top)
187 actions |= CompWindowActionShadeMask;
188
189 actions |= (CompWindowActionAboveMask | CompWindowActionBelowMask);
190@@ -813,7 +813,10 @@
191 xwc.x = serverGeometry.x () - serverInput.left;
192 xwc.y = serverGeometry.y () - serverInput.top;
193 xwc.width = serverGeometry.width () + serverInput.left + serverInput.right + bw;
194- xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
195+ if (shaded)
196+ xwc.height = serverInput.top + serverInput.bottom + bw;
197+ else
198+ xwc.height = serverGeometry.height () + serverInput.top + serverInput.bottom + bw;
199
200 if (shaded)
201 height = serverInput.top + serverInput.bottom;
202@@ -905,6 +908,7 @@
203 }
204 else
205 XConfigureWindow (screen->dpy (), serverFrame, valueMask, &xwc);
206+
207 if (shaded)
208 {
209 XUnmapWindow (screen->dpy (), wrapper);
210@@ -927,7 +931,13 @@
211 xwc.x = serverGeometry.x ();
212 xwc.y = serverGeometry.y ();
213 xwc.width = serverGeometry.width () + bw;
214- xwc.height = serverGeometry.height () + bw;
215+
216+ /* FIXME: It doesn't make much sense to allow undecorated windows to be
217+ * shaded */
218+ if (shaded)
219+ xwc.height = bw;
220+ else
221+ xwc.height = bw;
222
223 if (shaded)
224 height = 0;
225@@ -1132,10 +1142,10 @@
226
227 }
228
229- r.x = -priv->attrib.border_width;
230- r.y = -priv->attrib.border_width;
231- r.width = priv->width + priv->attrib.border_width;
232- r.height = priv->height + priv->attrib.border_width;
233+ r.x = -priv->geometry.border ();
234+ r.y = -priv->geometry.border ();
235+ r.width = priv->width + priv->geometry.border ();
236+ r.height = priv->height + priv->geometry.border ();
237
238 if (nBounding < 1)
239 {
240@@ -1607,11 +1617,10 @@
241 if (!overrideRedirect ())
242 {
243 /* been shaded */
244- if (!priv->height)
245+ if (priv->shaded)
246 {
247- priv->geometry.setHeight (priv->geometry.height () + 1);
248- resize (priv->geometry.x (), priv->geometry.y (), priv->geometry.width (),
249- priv->geometry.height () - 1, priv->geometry.border ());
250+ priv->shaded = false;
251+ priv->updateFrameWindow ();
252 }
253 }
254 }
255@@ -1637,10 +1646,12 @@
256 * pixmap of the window around, it's safe to
257 * unmap the frame window since there's no use
258 * for it at this point anyways and it just blocks
259- * input */
260+ * input, but keep it around if shaded */
261
262 XUnmapWindow (screen->dpy (), priv->wrapper);
263- XUnmapWindow (screen->dpy (), priv->serverFrame);
264+
265+ if (!priv->shaded)
266+ XUnmapWindow (screen->dpy (), priv->serverFrame);
267
268 priv->unmapRefCnt--;
269 if (priv->unmapRefCnt > 0)
270@@ -1668,7 +1679,7 @@
271 priv->unmanaging = false;
272 }
273
274- if (priv->serverFrame)
275+ if (priv->serverFrame && !priv->shaded)
276 priv->unreparent ();
277
278 if (priv->struts)
279@@ -1681,13 +1692,12 @@
280 screen->priv->desktopWindowCount--;
281
282 priv->attrib.map_state = IsUnmapped;
283-
284 priv->invisible = true;
285
286 if (priv->shaded && priv->height)
287- resize (priv->attrib.x, priv->attrib.y,
288- priv->attrib.width, ++priv->attrib.height - 1,
289- priv->attrib.border_width);
290+ {
291+ priv->updateFrameWindow ();
292+ }
293
294 screen->priv->updateClientList ();
295
296@@ -1792,9 +1802,6 @@
297 pw = gm.width () + gm.border () * 2;
298 ph = gm.height () + gm.border () * 2;
299
300- if (priv->shaded)
301- ph = 0;
302-
303 dx = gm.x () - priv->geometry.x ();
304 dy = gm.y () - priv->geometry.y ();
305 dwidth = gm.width () - priv->geometry.width ();
306@@ -2111,7 +2118,15 @@
307 x = ce->x + priv->serverInput.left;
308 y = ce->y + priv->serverInput.top;
309 width = ce->width - priv->serverGeometry.border () * 2 - priv->serverInput.left - priv->serverInput.right;
310- height = ce->height - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
311+
312+ /* Don't use the server side frame geometry
313+ * to determine the geometry of shaded
314+ * windows since we didn't resize them
315+ * on configureXWindow */
316+ if (priv->shaded)
317+ height = priv->serverGeometry.height () - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
318+ else
319+ height = ce->height - priv->serverGeometry.border () * 2 - priv->serverInput.top - priv->serverInput.bottom;
320
321 /* set the frame geometry */
322 priv->frameGeometry.set (ce->x, ce->y, ce->width, ce->height, ce->border_width);
323@@ -2549,7 +2564,12 @@
324 if (modalTransient)
325 return modalTransient->moveInputFocusTo ();
326
327- if (priv->state & CompWindowStateHiddenMask)
328+ /* If the window is still hidden but not shaded
329+ * it probably meant that a plugin overloaded
330+ * CompWindow::focus to allow the focus to go
331+ * to this window, so only move the input focus
332+ * to the frame if the window is shaded */
333+ if (shaded ())
334 {
335 XSetInputFocus (s->dpy (), priv->serverFrame,
336 RevertToPointerRoot, CurrentTime);
337@@ -3175,9 +3195,22 @@
338 + serverInput.left + serverInput.right)
339 frameValueMask &= ~(CWWidth);
340
341- if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
342- + serverInput.top + serverInput.bottom)
343- frameValueMask &= ~(CWHeight);
344+ /* shaded windows are not allowed to have their frame window
345+ * height changed (but are allowed to have their client height
346+ * changed */
347+
348+ if (shaded)
349+ {
350+ if (serverFrameGeometry.height () == serverGeometry.border () * 2
351+ + serverInput.top + serverInput.bottom)
352+ frameValueMask &= ~(CWHeight);
353+ }
354+ else
355+ {
356+ if (serverFrameGeometry.height () == xwc->height + serverGeometry.border () * 2
357+ + serverInput.top + serverInput.bottom)
358+ frameValueMask &= ~(CWHeight);
359+ }
360
361 /* Can't set the border width of frame windows */
362 frameValueMask &= ~(CWBorderWidth);
363@@ -3192,9 +3225,18 @@
364 serverFrameGeometry.setWidth (xwc->width + serverGeometry.border () * 2
365 + serverInput.left + serverInput.right);
366
367- if (frameValueMask & CWHeight)
368- serverFrameGeometry.setHeight (xwc->height + serverGeometry.border () * 2
369- + serverInput.top + serverInput.bottom);
370+ if (shaded)
371+ {
372+ if (frameValueMask & CWHeight)
373+ serverFrameGeometry.setHeight (serverGeometry.border () * 2
374+ + serverInput.top + serverInput.bottom);
375+ }
376+ else
377+ {
378+ if (frameValueMask & CWHeight)
379+ serverFrameGeometry.setHeight (xwc->height + serverGeometry.border () * 2
380+ + serverInput.top + serverInput.bottom);
381+ }
382
383
384 if (serverFrame)
385@@ -4217,7 +4259,7 @@
386 if (overrideRedirect () || !priv->managed)
387 return;
388
389- if (priv->state & CompWindowStateShadedMask)
390+ if (priv->state & CompWindowStateShadedMask && !priv->shaded)
391 {
392 windowNotify (CompWindowNotifyShade);
393
394@@ -4627,20 +4669,10 @@
395 if (serverFrame)
396 XMapWindow (screen->dpy (), serverFrame);
397
398- if (height)
399- {
400- priv->geometry.setHeight (priv->geometry.height () + 1);
401- window->resize (geometry.x (), geometry.y (),
402- geometry.width (), geometry.height () - 1,
403- geometry.border ());
404- }
405+ updateFrameWindow ();
406
407 return;
408 }
409- else
410- {
411- shaded = false;
412- }
413
414 window->windowNotify (CompWindowNotifyShow);
415
416@@ -6266,12 +6298,7 @@
417 priv->updateIconGeometry ();
418
419 if (priv->shaded)
420- {
421- priv->geometry.setHeight (priv->geometry.height () + 1);
422- resize (priv->geometry.x (), priv->geometry.y (),
423- priv->geometry.width (), priv->geometry.height () - 1,
424- priv->geometry.border ());
425- }
426+ priv->updateFrameWindow ();
427
428 if (priv->attrib.map_state == IsViewable)
429 {

Subscribers

People subscribed via source and target branches