Merge lp:~smspillaz/compiz-core/compiz-core.decor_928173 into lp:compiz-core
- compiz-core.decor_928173
- Merge into 0.9.7
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 |
Related bugs: |
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)
Sam Spilsbury (smspillaz) wrote : | # |
Alan Griffiths (alan-griffiths) wrote : | # |
There's a lot of shared_(ptr|array) where scoped_(ptr|array) would be more appropriate. E.g. "boost:
"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)
Sam Spilsbury (smspillaz) wrote : | # |
> There's a lot of shared_(ptr|array) where scoped_(ptr|array) would be more
> appropriate. E.g. "boost:
> 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 ?)
Daniel van Vugt (vanvugt) wrote : | # |
Nice. It works and bug 928173 is no more. Two stylistic comments though...
1. Shouldn't these:
compiz:
compiz:
...
instead be written as:
namespace compiz:
Extents:
Extents:
...
} // namespace compiz:
2. Unnecessary namespaces: Shouldn't "compiz:
Daniel van Vugt (vanvugt) wrote : | # |
If only the prerequisite branch didn't still cause a regression, I would merge this.
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:
>
> compiz:
> ...
> instead be written as:
> namespace compiz:
>
> Extents::Extents () {}
>
> Extents::Extents (int left, int right, int top, int bottom) :
> ...
> } // namespace compiz:
>
> 2. Unnecessary namespaces: Shouldn't "compiz:
> --
> https:/
> You are the owner of lp:~smspillaz/compiz-core/compiz-core.decor_928173.
>
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.
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
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 | { |
I can't say for sure whether or not this will fix bug 928173 but it will certainly help