Merge lp:~smspillaz/compiz-core/compiz-core.decor_928173 into lp:compiz-core

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 2990
Proposed branch: lp:~smspillaz/compiz-core/compiz-core.decor_928173
Merge into: lp:compiz-core
Prerequisite: lp:~smspillaz/compiz-core/compiz-core.work_923683
Diff against target: 920 lines (+357/-193)
8 files modified
include/decoration.h (+16/-0)
libdecoration/decoration.c (+60/-0)
plugins/decor/src/decor.cpp (+226/-169)
plugins/decor/src/decor.h (+35/-17)
plugins/resize/src/resize.cpp (+2/-5)
plugins/resize/src/resize.h (+2/-1)
src/window/extents/include/core/windowextents.h (+6/-1)
src/window/extents/src/windowextents.cpp (+10/-0)
To merge this branch: bzr merge lp:~smspillaz/compiz-core/compiz-core.decor_928173
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Review via email: mp+91986@code.launchpad.net

Commit message

Be a little smarter about updating decorations

Description of the change

Be a little smarter about updating decorations (bug 928173)

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :

I can't say for sure whether or not this will fix bug 928173 but it will certainly help

Revision history for this message
Alan Griffiths (alan-griffiths) wrote :

There's a lot of shared_(ptr|array) where scoped_(ptr|array) would be more appropriate. E.g. "boost::shared_array <decor_quad_t> quad" - scoped_array would be more appropriate.

"throw std::exception ();" - this doesn't give the client code much chance of identifying the problem.

There's inconsistent use of "Decoration::Ptr (new ...)" and "Decoration::Ptr = Decoration::create (...)" - have you come across make_shared<>()? (Part of boost and C++11)

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> There's a lot of shared_(ptr|array) where scoped_(ptr|array) would be more
> appropriate. E.g. "boost::shared_array <decor_quad_t> quad" - scoped_array
> would be more appropriate.
>

scoped_* is noncopyable, and I need it to be copyable so that I can store it in DecorWindow

> "throw std::exception ();" - this doesn't give the client code much chance of
> identifying the problem.

There are no users except internally and the users of that code only need to know if creating the decoration failed for /some/ reason, eg pixmap binding failed or whatever.

>
> There's inconsistent use of "Decoration::Ptr (new ...)" and "Decoration::Ptr =
> Decoration::create (...)" - have you come across make_shared<>()? (Part of
> boost and C++11)

I agree that the combination of Decoration::Ptr (new) and Decoration::create (...) is awkward - I would have made the constructor protected in favor of the named constructor, however the default "window" type decoration is just initialized from some property data. Maybe a named constructor there (eg defaultWindow () defaultPixmap () would be useful ?)

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Nice. It works and bug 928173 is no more. Two stylistic comments though...

1. Shouldn't these:
    compiz::window::extents::Extents::Extents () {}

    compiz::window::extents::Extents::Extents (int left, int right, int top, int bottom) :
    ...
instead be written as:
    namespace compiz::window::extents {

    Extents::Extents () {}

    Extents::Extents (int left, int right, int top, int bottom) :
    ...
    } // namespace compiz::window::extents

2. Unnecessary namespaces: Shouldn't "compiz::window::extents" simply be "compiz::window::extents"? Or even just "compiz"? Namespaces should really only change across different build targets. So that would mean core uses "compiz" and plugin Foo uses "compiz::Foo". Though, this point is purely opinion.

review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

If only the prerequisite branch didn't still cause a regression, I would merge this.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

On Thu, 9 Feb 2012, Daniel van Vugt wrote:

> Review: Approve
>
> Nice. It works and bug 928173 is no more. Two stylistic comments though...
>

Good to hear.

> 1. Shouldn't these:
> compiz::window::extents::Extents::Extents () {}
>
> compiz::window::extents::Extents::Extents (int left, int right, int top, int bottom) :
> ...
> instead be written as:
> namespace compiz::window::extents {
>
> Extents::Extents () {}
>
> Extents::Extents (int left, int right, int top, int bottom) :
> ...
> } // namespace compiz::window::extents
>
> 2. Unnecessary namespaces: Shouldn't "compiz::window::extents" simply be "compiz::window::extents"? Or even just "compiz"? Namespaces should really only change across different build targets. So that would mean core uses "compiz" and plugin Foo uses "compiz::Foo". Though, this point is purely opinion.
> --
> https://code.launchpad.net/~smspillaz/compiz-core/compiz-core.decor_928173/+merge/91986
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.decor_928173.
>

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Also, as we have discussed before, memcmp on structures is usually unsafe:

70 + if (memcmp (&cFrame, frame, sizeof (decor_extents_t)) ||
71 + memcmp (&cBorder, border, sizeof (decor_extents_t)) ||
72 + memcmp (&cMax_frame, max_frame, sizeof (decor_extents_t)) ||
73 + memcmp (&cMax_border, max_border, sizeof (decor_extents_t)))
74 + continue;

However in this case, I believe it will be safe with decor_extents_t on any architecture. Because 4 ints should always add up to a multiple of the struct alignment. There *should* be no padding bytes to worry about.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

> If only the prerequisite branch didn't still cause a regression, I would merge
> this.

I found that if I only cherry pick revisions 2984+2985 then the fix for bug 928173 continues to work without the regression introduced by the prerequisite branch. So I'll do that.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'include/decoration.h'
2--- include/decoration.h 2011-05-08 13:44:09 +0000
3+++ include/decoration.h 2012-02-08 07:32:18 +0000
4@@ -267,6 +267,22 @@
5 decor_quad_t *quad);
6
7 int
8+decor_match_pixmap (long *data,
9+ int size,
10+ Pixmap *pixmap,
11+ decor_extents_t *frame,
12+ decor_extents_t *border,
13+ decor_extents_t *max_frame,
14+ decor_extents_t *max_border,
15+ int min_width,
16+ int min_height,
17+ unsigned int frame_type,
18+ unsigned int frame_state,
19+ unsigned int frame_actions,
20+ decor_quad_t *quad,
21+ unsigned int n_quad);
22+
23+int
24 decor_window_property (long *data,
25 unsigned int n,
26 int size,
27
28=== modified file 'libdecoration/decoration.c'
29--- libdecoration/decoration.c 2012-01-17 05:19:03 +0000
30+++ libdecoration/decoration.c 2012-02-08 07:32:18 +0000
31@@ -369,6 +369,66 @@
32 return n;
33 }
34
35+/* Returns n for a match, returns -1 for no match */
36+
37+int
38+decor_match_pixmap (long *data,
39+ int size,
40+ Pixmap *pixmap,
41+ decor_extents_t *frame,
42+ decor_extents_t *border,
43+ decor_extents_t *max_frame,
44+ decor_extents_t *max_border,
45+ int min_width,
46+ int min_height,
47+ unsigned int frame_type,
48+ unsigned int frame_state,
49+ unsigned int frame_actions,
50+ decor_quad_t *quad,
51+ unsigned int n_quad)
52+{
53+ int n = decor_property_get_num (data);
54+ unsigned int i = 0;
55+
56+ for (; i < n; i++)
57+ {
58+ Pixmap cPixmap;
59+ decor_extents_t cFrame, cBorder, cMax_frame, cMax_border;
60+ int cMin_width, cMin_height;
61+ unsigned int cFrame_type, cFrame_state, cFrame_actions, cNQuad;
62+ decor_quad_t cQuad[N_QUADS_MAX];
63+ cNQuad = decor_pixmap_property_to_quads (data, i, size, &cPixmap, &cFrame, &cBorder, &cMax_frame,
64+ &cMax_border, &cMin_width, &cMin_height, &cFrame_type,
65+ &cFrame_state, &cFrame_actions, cQuad);
66+
67+ if (cPixmap != *pixmap)
68+ continue;
69+
70+ if (memcmp (&cFrame, frame, sizeof (decor_extents_t)) ||
71+ memcmp (&cBorder, border, sizeof (decor_extents_t)) ||
72+ memcmp (&cMax_frame, max_frame, sizeof (decor_extents_t)) ||
73+ memcmp (&cMax_border, max_border, sizeof (decor_extents_t)))
74+ continue;
75+
76+ if (cFrame_type != frame_type ||
77+ cFrame_state != frame_state ||
78+ cFrame_actions != frame_actions ||
79+ cMin_width != min_width ||
80+ cMin_height != min_height)
81+ continue;
82+
83+ if (cNQuad != n_quad)
84+ continue;
85+
86+ if (memcmp (cQuad, quad, sizeof (decor_quad_t) * n_quad))
87+ continue;
88+
89+ return n;
90+ }
91+
92+ return -1;
93+}
94+
95 int
96 decor_window_property (long *data,
97 unsigned int n,
98
99=== modified file 'plugins/decor/src/decor.cpp'
100--- plugins/decor/src/decor.cpp 2012-02-08 07:32:18 +0000
101+++ plugins/decor/src/decor.cpp 2012-02-08 07:32:18 +0000
102@@ -536,63 +536,48 @@
103 *
104 */
105
106-Decoration *
107+Decoration::Ptr
108 Decoration::create (Window id,
109 long *prop,
110 unsigned int size,
111 unsigned int type,
112 unsigned int nOffset)
113 {
114- Decoration *decoration;
115 unsigned int frameType, frameState, frameActions;
116 Pixmap pixmap = None;
117 decor_extents_t border;
118 decor_extents_t input;
119 decor_extents_t maxBorder;
120 decor_extents_t maxInput;
121- decor_quad_t *quad = NULL;
122- int nQuad = 0;
123 int minWidth;
124 int minHeight;
125- int left, right, top, bottom;
126- int x1, y1, x2, y2;
127+ int nQuad = N_QUADS_MAX;
128+ boost::shared_array <decor_quad_t> quad (new decor_quad_t[nQuad]);
129
130 if (type == WINDOW_DECORATION_TYPE_PIXMAP &&
131 !DecorScreen::get (screen)->cmActive)
132 {
133- compLogMessage ("decor", CompLogLevelWarn, "requested a pixmap type decoration when compositing isn't available");
134- return NULL;
135+ compLogMessage ("decor", CompLogLevelWarn, "requested a pixmap type decoration when compositing isn't available");
136+ throw std::exception ();
137 }
138
139 if (type == WINDOW_DECORATION_TYPE_PIXMAP)
140 {
141- nQuad = N_QUADS_MAX;
142-
143- quad = new decor_quad_t [nQuad];
144- if (!quad)
145- {
146- compLogMessage ("decor", CompLogLevelWarn, "failed to allocate %i quads\n", nQuad);
147- return NULL;
148- }
149-
150 nQuad = decor_pixmap_property_to_quads (prop, nOffset, size, &pixmap, &input,
151 &border, &maxInput,
152 &maxBorder, &minWidth, &minHeight,
153- &frameType, &frameState, &frameActions, quad);
154+ &frameType, &frameState, &frameActions, quad.get ());
155
156 if (!nQuad)
157- {
158- delete [] quad;
159- return NULL;
160- }
161+ throw std::exception ();
162 }
163 else if (type == WINDOW_DECORATION_TYPE_WINDOW)
164 {
165- if (!decor_window_property (prop, nOffset, size, &input, &maxInput,
166- &minWidth, &minHeight, &frameType, &frameState, &frameActions))
167+ if (!decor_window_property (prop, nOffset, size, &input, &maxInput,
168+ &minWidth, &minHeight, &frameType, &frameState, &frameActions))
169 {
170 compLogMessage ("decor", CompLogLevelWarn, "malformed decoration - not a window");
171- return NULL;
172+ throw std::exception ();
173 }
174
175 border = input;
176@@ -600,35 +585,49 @@
177 }
178 else
179 {
180- compLogMessage ("decor", CompLogLevelWarn, "malformed decoration - undetermined type");
181- return NULL;
182- }
183-
184- decoration = new Decoration ();
185- if (!decoration)
186- {
187- delete [] quad;
188- return NULL;
189- }
190-
191- if (pixmap)
192- decoration->texture = DecorScreen::get (screen)->getTexture (pixmap);
193- else
194- decoration->texture = NULL;
195-
196- if (!decoration->texture && type == WINDOW_DECORATION_TYPE_PIXMAP)
197+ compLogMessage ("decor", CompLogLevelWarn, "malformed decoration - undetermined type");
198+ throw std::exception ();
199+ }
200+
201+ return Decoration::Ptr (new Decoration (type, border, input, maxBorder, maxInput, frameType, frameState, frameActions, minWidth, minHeight, pixmap, quad, nQuad));
202+}
203+
204+Decoration::Decoration (int type,
205+ const decor_extents_t &border,
206+ const decor_extents_t &input,
207+ const decor_extents_t &maxBorder,
208+ const decor_extents_t &maxInput,
209+ unsigned int frameType,
210+ unsigned int frameState,
211+ unsigned int frameActions,
212+ unsigned int minWidth,
213+ unsigned int minHeight,
214+ Pixmap pixmap,
215+ const boost::shared_array <decor_quad_t> &quad,
216+ unsigned int nQuad) :
217+ texture (DecorScreen::get (screen)->getTexture (pixmap)),
218+ border (border.left, border.right, border.top, border.bottom),
219+ input (input.left, input.right, input.top, input.bottom),
220+ maxBorder (maxBorder.left, maxBorder.right, maxBorder.top, maxBorder.bottom),
221+ maxInput (maxInput.left, maxInput.right, maxInput.top, maxInput.bottom),
222+ minWidth (minWidth),
223+ minHeight (minHeight),
224+ frameType (frameType),
225+ frameState (frameState),
226+ frameActions (frameActions),
227+ quad (quad),
228+ nQuad (nQuad),
229+ type (type)
230+{
231+ int left, right, top, bottom;
232+ int x1, y1, x2, y2;
233+
234+ if (!texture && type == WINDOW_DECORATION_TYPE_PIXMAP)
235 {
236 compLogMessage ("decor", CompLogLevelWarn, "failed to bind pixmap to texture");
237- delete decoration;
238- delete [] quad;
239- return NULL;
240+ throw std::exception ();
241 }
242
243- decoration->minWidth = minWidth;
244- decoration->minHeight = minHeight;
245- decoration->quad = quad;
246- decoration->nQuad = nQuad;
247-
248 if (type == WINDOW_DECORATION_TYPE_PIXMAP)
249 {
250 left = 0;
251@@ -636,9 +635,9 @@
252 top = 0;
253 bottom = minHeight;
254
255- while (nQuad--)
256+ for (unsigned int i = 0; i < nQuad; i++)
257 {
258- computeQuadBox (quad, minWidth, minHeight, &x1, &y1, &x2, &y2,
259+ computeQuadBox (&(quad[i]), minWidth, minHeight, &x1, &y1, &x2, &y2,
260 NULL, NULL);
261
262 if (x1 < left)
263@@ -649,83 +648,34 @@
264 right = x2;
265 if (y2 > bottom)
266 bottom = y2;
267-
268- quad++;
269 }
270
271- decoration->output.left = -left;
272- decoration->output.right = right - minWidth;
273- decoration->output.top = -top;
274- decoration->output.bottom = bottom - minHeight;
275+ this->output.left = -left;
276+ this->output.right = right - minWidth;
277+ this->output.top = -top;
278+ this->output.bottom = bottom - minHeight;
279 }
280 else
281 {
282- decoration->output.left = MAX (input.left, maxInput.left);
283- decoration->output.right = MAX (input.right, maxInput.right);
284- decoration->output.top = MAX (input.top, maxInput.top);
285- decoration->output.bottom = MAX (input.bottom, maxInput.bottom);
286+ this->output.left = MAX (input.left, maxInput.left);
287+ this->output.right = MAX (input.right, maxInput.right);
288+ this->output.top = MAX (input.top, maxInput.top);
289+ this->output.bottom = MAX (input.bottom, maxInput.bottom);
290 }
291-
292- /* Extents of actual frame window */
293-
294- decoration->input.left = input.left;
295- decoration->input.right = input.right;
296- decoration->input.top = input.top;
297- decoration->input.bottom = input.bottom;
298-
299- /* Border extents */
300-
301- decoration->border.left = border.left;
302- decoration->border.right = border.right;
303- decoration->border.top = border.top;
304- decoration->border.bottom = border.bottom;
305-
306- /* Extents of actual frame window */
307-
308- decoration->maxInput.left = maxInput.left;
309- decoration->maxInput.right = maxInput.right;
310- decoration->maxInput.top = maxInput.top;
311- decoration->maxInput.bottom = maxInput.bottom;
312-
313- /* Border extents */
314-
315- decoration->maxBorder.left = maxBorder.left;
316- decoration->maxBorder.right = maxBorder.right;
317- decoration->maxBorder.top = maxBorder.top;
318- decoration->maxBorder.bottom = maxBorder.bottom;
319-
320- /* Decoration info */
321-
322- decoration->frameType = frameType;
323- decoration->frameState = frameState;
324- decoration->frameActions = frameActions;
325-
326- decoration->refCount = 1;
327- decoration->type = type;
328-
329- return decoration;
330 }
331
332 /*
333- * Decoration::release
334+ * Decoration::~Decoration
335 *
336 * Unreferences the decoration, also unreferences the texture
337 * if this decoration is about to be destroyed
338 *
339 */
340
341-void
342-Decoration::release (Decoration *decoration)
343+Decoration::~Decoration ()
344 {
345- decoration->refCount--;
346- if (decoration->refCount)
347- return;
348-
349- if (decoration->texture)
350- DecorScreen::get (screen)->releaseTexture (decoration->texture);
351-
352- delete [] decoration->quad;
353- delete decoration;
354+ if (texture)
355+ DecorScreen::get (screen)->releaseTexture (texture);
356 }
357
358 /*
359@@ -772,11 +722,6 @@
360 int result, format;
361 unsigned int type;
362
363- /* FIXME: Should really check the property to see
364- * if the decoration changed, and /then/ release
365- * and re-update it, but for now just releasing all */
366- mList.clear ();
367-
368 result = XGetWindowProperty (screen->dpy (), id,
369 decorAtom, 0L,
370 PROP_HEADER_SIZE + 6 * (BASE_PROP_SIZE +
371@@ -818,21 +763,121 @@
372
373 type = decor_property_get_type (prop);
374
375+ std::list <Decoration::Ptr> remove;
376+ std::list <int> skip;
377+
378+ /* only recreate decorations if they need to be updated */
379+ foreach (const Decoration::Ptr &d, mList)
380+ {
381+ decor_extents_t input, border, maxInput, maxBorder;
382+
383+ input.left = d->input.left;
384+ input.right = d->input.right;
385+ input.top = d->input.top;
386+ input.bottom = d->input.bottom;
387+
388+ border.left = d->border.left;
389+ border.right = d->border.right;
390+ border.top = d->border.top;
391+ border.bottom = d->border.bottom;
392+
393+ maxInput.left = d->maxInput.left;
394+ maxInput.right = d->maxInput.right;
395+ maxInput.top = d->maxInput.top;
396+ maxInput.bottom = d->maxInput.bottom;
397+
398+ maxBorder.left = d->maxBorder.left;
399+ maxBorder.right = d->maxBorder.right;
400+ maxBorder.top = d->maxBorder.top;
401+ maxBorder.bottom = d->maxBorder.bottom;
402+
403+ int num = decor_match_pixmap (prop, n, &d->texture->pixmap, &input, &border, &maxInput, &maxBorder,
404+ d->minWidth, d->minHeight, d->frameType, d->frameState, d->frameActions,
405+ d->quad.get (), d->nQuad);
406+ if (num != -1)
407+ skip.push_back (num);
408+ else
409+ remove.push_back (d);
410+ }
411+
412 /* Create a new decoration for each individual item on the property */
413 for (int i = 0; i < decor_property_get_num (prop); i++)
414 {
415- Decoration *d = Decoration::create (id, prop, n, type, i);
416-
417- if (!d)
418- {
419- XFree (data);
420- mList.clear ();
421- return false;
422- }
423- else
424- mList.push_back (d);
425+ if (std::find (skip.begin (), skip.end (), i) != skip.end ())
426+ continue;
427+
428+ try
429+ {
430+ std::list <Decoration::Ptr>::iterator it = mList.begin ();
431+ Decoration::Ptr d = Decoration::create (id, prop, n, type, i);
432+
433+ /* Try to replace an existing decoration */
434+ for (; it != mList.end (); it++)
435+ {
436+ if ((*it)->frameType == d->frameType &&
437+ (*it)->frameState == d->frameState &&
438+ (*it)->frameActions == d->frameActions)
439+ {
440+ remove.remove ((*it));
441+ (*it) = d;
442+ break;
443+ }
444+ }
445+
446+ if (it == mList.end ())
447+ mList.push_back (d);
448+ }
449+ catch (...)
450+ {
451+ /* Creating a new decoration failed ... see if we can use
452+ * the old one */
453+
454+ unsigned int frameType, frameState, frameActions;
455+ Pixmap pixmap = None;
456+ decor_extents_t border;
457+ decor_extents_t input;
458+ decor_extents_t maxBorder;
459+ decor_extents_t maxInput;
460+ int minWidth;
461+ int minHeight;
462+ int ok = 0;
463+ boost::shared_array <decor_quad_t> quad (new decor_quad_t[N_QUADS_MAX]);
464+
465+ if (type == WINDOW_DECORATION_TYPE_PIXMAP)
466+ {
467+ ok = decor_pixmap_property_to_quads (prop, i, n, &pixmap, &input,
468+ &border, &maxInput,
469+ &maxBorder, &minWidth, &minHeight,
470+ &frameType, &frameState, &frameActions, quad.get ());
471+ }
472+ else if (type == WINDOW_DECORATION_TYPE_WINDOW)
473+ {
474+ ok = decor_window_property (prop, i, n, &input, &maxInput,
475+ &minWidth, &minHeight, &frameType, &frameState, &frameActions);
476+ }
477+
478+ if (ok)
479+ {
480+ std::list <Decoration::Ptr>::iterator it = mList.begin ();
481+
482+ /* Use an existing decoration */
483+ for (; it != mList.end (); it++)
484+ {
485+ if ((*it)->frameType == frameType &&
486+ (*it)->frameState == frameState &&
487+ (*it)->frameActions == frameActions)
488+ {
489+ remove.remove ((*it));
490+ break;
491+ }
492+ }
493+ }
494+ }
495 }
496
497+ foreach (const Decoration::Ptr &d, remove)
498+ mList.remove (d);
499+
500 XFree (data);
501
502 return true;
503@@ -869,7 +914,7 @@
504 *
505 */
506 WindowDecoration *
507-WindowDecoration::create (Decoration *d)
508+WindowDecoration::create (const Decoration::Ptr &d)
509 {
510 WindowDecoration *wd;
511
512@@ -907,7 +952,6 @@
513 void
514 WindowDecoration::destroy (WindowDecoration *wd)
515 {
516- Decoration::release (wd->decor);
517 delete [] wd->quad;
518 delete wd;
519 }
520@@ -1057,7 +1101,7 @@
521 *
522 */
523 bool
524-DecorWindow::checkSize (Decoration *decoration)
525+DecorWindow::checkSize (const Decoration::Ptr &decoration)
526 {
527 return (decoration->minWidth <= (int) window->geometry ().width () &&
528 decoration->minHeight <= (int) window->geometry ().height ());
529@@ -1225,11 +1269,11 @@
530 * match the locked property, then it is not matched
531 *
532 */
533-Decoration *
534+const Decoration::Ptr &
535 DecorationList::findMatchingDecoration (CompWindow *w,
536 bool sizeCheck)
537 {
538- Decoration *decoration = NULL;
539+ std::list <Decoration::Ptr>::iterator cit = mList.end ();
540 DECOR_WINDOW (w);
541
542 if (mList.size ())
543@@ -1240,17 +1284,22 @@
544
545 unsigned int currentDecorState = 0;
546
547- decoration = (sizeCheck ? dw->checkSize (mList.front ()) : true) ? mList.front () : NULL;
548+ if (sizeCheck)
549+ if (dw->checkSize (mList.front ()))
550+ cit = mList.begin ();
551
552- foreach (Decoration *d, mList)
553+ for (std::list <Decoration::Ptr>::iterator it = mList.begin ();
554+ it != mList.end (); it++)
555 {
556+ const Decoration::Ptr &d = *it;
557+
558 /* Must always match type */
559 if (DecorWindow::matchType (w, d->frameType))
560 {
561 /* Use this decoration if the type matched */
562 if (!(typeMatch & currentDecorState) && (!sizeCheck || dw->checkSize (d)))
563 {
564- decoration = d;
565+ cit = it;
566 currentDecorState |= typeMatch;
567 }
568
569@@ -1260,7 +1309,7 @@
570 /* Use this decoration if the type and state match */
571 if (!(stateMatch & currentDecorState))
572 {
573- decoration = d;
574+ cit = it;
575 currentDecorState |= stateMatch;
576 }
577
578@@ -1270,7 +1319,7 @@
579 /* Use this decoration if the requested actions match */
580 if (!(actionsMatch & currentDecorState))
581 {
582- decoration = d;
583+ cit = it;
584 currentDecorState |= actionsMatch;
585
586 /* Perfect match, no need to continue searching */
587@@ -1282,7 +1331,10 @@
588 }
589 }
590
591- return decoration;
592+ if (cit == mList.end ())
593+ throw std::exception ();
594+
595+ return *cit;
596 }
597
598 /*
599@@ -1324,12 +1376,15 @@
600 bool
601 DecorWindow::update (bool allowDecoration)
602 {
603- Decoration *old, *decoration = NULL;
604+ Decoration::Ptr old, decoration;
605 bool decorate = false;
606 bool shadowOnly = true;
607 CompPoint oldShift, movement;
608
609- old = (wd) ? wd->decor : NULL;
610+ if (wd)
611+ old = wd->decor;
612+ else
613+ old.reset ();
614
615 /* Only want to decorate windows which have a frame or are in the process
616 * of waiting for an animation to be unmapped (in which case we can give
617@@ -1377,9 +1432,11 @@
618 if (decorate || frameExtentsRequested)
619 {
620 /* Attempt to find a matching decoration */
621- decoration = decor.findMatchingDecoration (window, true);
622-
623- if (!decoration)
624+ try
625+ {
626+ decoration = decor.findMatchingDecoration (window, true);
627+ }
628+ catch (...)
629 {
630 /* Find an appropriate default decoration to use */
631 if (dScreen->dmSupports & WINDOW_DECORATION_TYPE_PIXMAP &&
632@@ -1387,13 +1444,18 @@
633 !(dScreen->dmSupports & WINDOW_DECORATION_TYPE_WINDOW &&
634 pixmapFailed))
635 {
636- decoration = dScreen->decor[DECOR_ACTIVE].findMatchingDecoration (window, false);
637-
638- if (!decoration)
639+ try
640+ {
641+ decoration = dScreen->decor[DECOR_ACTIVE].findMatchingDecoration (window, false);
642+ }
643+ catch (...)
644+ {
645 compLogMessage ("decor", CompLogLevelWarn, "No default decoration found, placement will not be correct");
646+ decoration.reset ();
647+ }
648 }
649 else if (dScreen->dmSupports & WINDOW_DECORATION_TYPE_WINDOW)
650- decoration = &dScreen->windowDefault;
651+ decoration = dScreen->windowDefault;
652 }
653
654 /* Do not allow windows which are later undecorated
655@@ -1413,7 +1475,7 @@
656 if (decoration)
657 {
658 if (!checkSize (decoration))
659- decoration = NULL;
660+ decoration.reset ();
661 }
662 }
663 }
664@@ -1423,7 +1485,7 @@
665 * (nobody owns the selection window)
666 */
667 if (!dScreen->dmWin || !allowDecoration)
668- decoration = NULL;
669+ decoration.reset ();
670
671 /* Don't bother going any further if
672 * this window is going to get the same
673@@ -2885,7 +2947,20 @@
674 textures (),
675 dmWin (None),
676 dmSupports (0),
677- cmActive (false)
678+ cmActive (false),
679+ windowDefault (new Decoration (WINDOW_DECORATION_TYPE_WINDOW,
680+ decor_extents_t (),
681+ decor_extents_t (),
682+ decor_extents_t (),
683+ decor_extents_t (),
684+ 0,
685+ 0,
686+ 0,
687+ 0,
688+ 0,
689+ None,
690+ boost::shared_array <decor_quad_t> (NULL),
691+ 0))
692 {
693 supportingDmCheckAtom =
694 XInternAtom (s->dpy (), DECOR_SUPPORTING_DM_CHECK_ATOM_NAME, 0);
695@@ -2914,24 +2989,6 @@
696 shadowInfoAtom =
697 XInternAtom (s->dpy (), "_COMPIZ_NET_CM_SHADOW_PROPERTIES", 0);
698
699- windowDefault.texture = NULL;
700- windowDefault.minWidth = 0;
701- windowDefault.minHeight = 0;
702- windowDefault.quad = NULL;
703- windowDefault.nQuad = 0;
704- windowDefault.type = WINDOW_DECORATION_TYPE_WINDOW;
705-
706- windowDefault.input.left = 0;
707- windowDefault.input.right = 0;
708- windowDefault.input.top = 1;
709- windowDefault.input.bottom = 0;
710-
711- windowDefault.border = windowDefault.maxBorder =
712- windowDefault.maxInput = windowDefault.output =
713- windowDefault.input;
714-
715- windowDefault.refCount = 1;
716-
717 cmActive = (cScreen) ? cScreen->compositingActive () &&
718 GLScreen::get (s) != NULL : false;
719
720
721=== modified file 'plugins/decor/src/decor.h'
722--- plugins/decor/src/decor.h 2012-01-21 19:05:23 +0000
723+++ plugins/decor/src/decor.h 2012-02-08 07:32:18 +0000
724@@ -24,6 +24,7 @@
725 */
726
727 #include <boost/shared_ptr.hpp>
728+#include <boost/shared_array.hpp>
729 #include <core/window.h>
730 #include <core/pluginclasshandler.h>
731
732@@ -68,12 +69,30 @@
733 class Decoration {
734
735 public:
736- static Decoration * create (Window id,
737- long *prop,
738- unsigned int size,
739- unsigned int type,
740- unsigned int nOffset);
741- static void release (Decoration *);
742+
743+ typedef boost::shared_ptr <Decoration> Ptr;
744+
745+ static Decoration::Ptr create (Window id,
746+ long *prop,
747+ unsigned int size,
748+ unsigned int type,
749+ unsigned int nOffset);
750+
751+ Decoration (int type,
752+ const decor_extents_t &border,
753+ const decor_extents_t &input,
754+ const decor_extents_t &maxBorder,
755+ const decor_extents_t &maxInput,
756+ unsigned int frameType,
757+ unsigned int frameState,
758+ unsigned int frameActions,
759+ unsigned int minWidth,
760+ unsigned int minHeight,
761+ Pixmap pixmap,
762+ const boost::shared_array <decor_quad_t> &quad,
763+ unsigned int nQuad);
764+
765+ ~Decoration ();
766
767 public:
768 int refCount;
769@@ -88,7 +107,7 @@
770 unsigned int frameType;
771 unsigned int frameState;
772 unsigned int frameActions;
773- decor_quad_t *quad;
774+ boost::shared_array <decor_quad_t> quad;
775 int nQuad;
776 int type;
777 };
778@@ -97,16 +116,15 @@
779 {
780 public:
781 bool updateDecoration (Window id, Atom decorAtom);
782- Decoration *findMatchingDecoration (CompWindow *w, bool sizeCheck);
783+ const Decoration::Ptr & findMatchingDecoration (CompWindow *w, bool sizeCheck);
784 void clear ()
785 {
786- foreach (Decoration *d, mList)
787- Decoration::release (d);
788+ mList.clear ();
789 };
790
791 DecorationList ();
792
793- std::vector <Decoration *> mList;
794+ std::list <Decoration::Ptr> mList;
795 };
796
797 struct ScaledQuad {
798@@ -118,11 +136,11 @@
799
800 class WindowDecoration {
801 public:
802- static WindowDecoration * create (Decoration *);
803+ static WindowDecoration * create (const Decoration::Ptr &);
804 static void destroy (WindowDecoration *);
805
806 public:
807- Decoration *decor;
808+ Decoration::Ptr decor;
809 ScaledQuad *quad;
810 int nQuad;
811 };
812@@ -178,10 +196,10 @@
813 Window dmWin;
814 int dmSupports;
815
816+ bool cmActive;
817+
818 DecorationList decor[DECOR_NUM];
819- Decoration windowDefault;
820-
821- bool cmActive;
822+ Decoration::Ptr windowDefault;
823
824 std::map<Window, DecorWindow *> frames;
825
826@@ -226,7 +244,7 @@
827 void updateOutputFrame ();
828 void updateWindowRegions ();
829
830- bool checkSize (Decoration *decor);
831+ bool checkSize (const Decoration::Ptr &decor);
832
833 int shiftX ();
834 int shiftY ();
835
836=== modified file 'plugins/resize/src/resize.cpp'
837--- plugins/resize/src/resize.cpp 2012-01-25 09:20:47 +0000
838+++ plugins/resize/src/resize.cpp 2012-02-08 07:32:18 +0000
839@@ -510,10 +510,7 @@
840 int top = screen->outputDevs ().at (tco).workArea ().top ();
841 int bottom = screen->outputDevs ().at (bco).workArea ().bottom ();
842
843- if (rs->grabWindowWorkArea)
844- delete rs->grabWindowWorkArea;
845-
846- rs->grabWindowWorkArea = new CompRect (0, 0, 0, 0);
847+ rs->grabWindowWorkArea.reset (new CompRect (0, 0, 0, 0));
848 rs->grabWindowWorkArea->setLeft (left);
849 rs->grabWindowWorkArea->setRight (right);
850 rs->grabWindowWorkArea->setTop (top);
851@@ -1767,7 +1764,7 @@
852 releaseButton (0),
853 isConstrained (false),
854 offWorkAreaConstrained (true),
855- grabWindowWorkArea (NULL)
856+ grabWindowWorkArea ()
857 {
858 CompOption::Vector atomTemplate;
859 Display *dpy = s->dpy ();
860
861=== modified file 'plugins/resize/src/resize.h'
862--- plugins/resize/src/resize.h 2012-01-18 16:26:45 +0000
863+++ plugins/resize/src/resize.h 2012-02-08 07:32:18 +0000
864@@ -26,6 +26,7 @@
865 #ifndef _RESIZE_H
866 #define _RESIZE_H
867
868+#include <boost/shared_ptr.hpp>
869 #include <core/screen.h>
870 #include <core/pluginclasshandler.h>
871 #include <core/propertywriter.h>
872@@ -148,7 +149,7 @@
873 CompSize lastGoodSize;
874
875 bool offWorkAreaConstrained;
876- CompRect *grabWindowWorkArea;
877+ boost::shared_ptr <CompRect> grabWindowWorkArea;
878 };
879
880 class ResizeWindow :
881
882=== modified file 'src/window/extents/include/core/windowextents.h'
883--- src/window/extents/include/core/windowextents.h 2012-01-19 20:18:20 +0000
884+++ src/window/extents/include/core/windowextents.h 2012-02-08 07:32:18 +0000
885@@ -41,8 +41,13 @@
886 * Specifies the left, right, top and bottom positions of a window's
887 * geometry
888 */
889-struct Extents {
890+class Extents
891+{
892 public:
893+
894+ Extents ();
895+ Extents (int left, int right, int top, int bottom);
896+
897 int left;
898 int right;
899 int top;
900
901=== modified file 'src/window/extents/src/windowextents.cpp'
902--- src/window/extents/src/windowextents.cpp 2012-01-19 20:18:20 +0000
903+++ src/window/extents/src/windowextents.cpp 2012-02-08 07:32:18 +0000
904@@ -65,6 +65,16 @@
905 return rv;
906 }
907
908+compiz::window::extents::Extents::Extents () {}
909+
910+compiz::window::extents::Extents::Extents (int left, int right, int top, int bottom) :
911+ left (left),
912+ right (right),
913+ top (top),
914+ bottom (bottom)
915+{
916+}
917+
918 bool
919 compiz::window::extents::Extents::operator== (const Extents &other)
920 {

Subscribers

People subscribed via source and target branches