Merge lp:~macslow/notify-osd/fix-mem-leaks into lp:notify-osd/trunk
- fix-mem-leaks
- Merge into main
Proposed by
Mirco Müller
Status: | Merged |
---|---|
Approved by: | Mirco Müller |
Approved revision: | 401 |
Merged at revision: | not available |
Proposed branch: | lp:~macslow/notify-osd/fix-mem-leaks |
Merge into: | lp:notify-osd/trunk |
Diff against target: | None lines |
To merge this branch: | bzr merge lp:~macslow/notify-osd/fix-mem-leaks |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
David Barth (community) | Approve | ||
Review via email: mp+12283@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Mirco Müller (macslow) wrote : | # |
Revision history for this message
David Barth (dbarth) wrote : | # |
approve, all look like good changes
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/bubble.c' |
2 | --- src/bubble.c 2009-08-27 09:52:34 +0000 |
3 | +++ src/bubble.c 2009-09-23 01:05:51 +0000 |
4 | @@ -475,41 +475,6 @@ |
5 | cairo_surface_destroy (new_surface); |
6 | } |
7 | |
8 | -cairo_surface_t* |
9 | -_copy_surface (cairo_surface_t* orig) |
10 | -{ |
11 | - cairo_surface_t* copy = NULL; |
12 | - guchar* pixels_src = NULL; |
13 | - guchar* pixels_cpy = NULL; |
14 | - cairo_format_t format; |
15 | - gint width; |
16 | - gint height; |
17 | - gint stride; |
18 | - |
19 | - pixels_src = cairo_image_surface_get_data (orig); |
20 | - if (!pixels_src) |
21 | - return NULL; |
22 | - |
23 | - format = cairo_image_surface_get_format (orig); |
24 | - width = cairo_image_surface_get_width (orig); |
25 | - height = cairo_image_surface_get_height (orig); |
26 | - stride = cairo_image_surface_get_stride (orig); |
27 | - |
28 | - pixels_cpy = g_malloc0 (stride * height); |
29 | - if (!pixels_cpy) |
30 | - return NULL; |
31 | - |
32 | - memcpy ((void*) pixels_cpy, (void*) pixels_src, height * stride); |
33 | - |
34 | - copy = cairo_image_surface_create_for_data (pixels_cpy, |
35 | - format, |
36 | - width, |
37 | - height, |
38 | - stride); |
39 | - |
40 | - return copy; |
41 | -} |
42 | - |
43 | static void |
44 | _draw_layout_grid (cairo_t* cr, |
45 | Bubble* bubble) |
46 | @@ -665,9 +630,11 @@ |
47 | |
48 | g_return_if_fail (scratch); |
49 | |
50 | - if (cairo_surface_status (scratch) != CAIRO_STATUS_SUCCESS) { |
51 | + if (cairo_surface_status (scratch) != CAIRO_STATUS_SUCCESS) |
52 | + { |
53 | if (scratch) |
54 | cairo_surface_destroy (scratch); |
55 | + |
56 | return; |
57 | } |
58 | |
59 | @@ -676,8 +643,10 @@ |
60 | if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) |
61 | { |
62 | cairo_surface_destroy (scratch); |
63 | + |
64 | if (cr) |
65 | cairo_destroy (cr); |
66 | + |
67 | return; |
68 | } |
69 | |
70 | @@ -766,7 +735,7 @@ |
71 | cairo_image_surface_get_stride (clone)); |
72 | blurred = copy_surface (dummy); |
73 | cairo_surface_destroy (dummy); |
74 | - cairo_surface_destroy (clone); |
75 | + destroy_cloned_surface (clone); |
76 | |
77 | // finally create tile with top-left shadow/background part |
78 | if (priv->tile_background_part) |
79 | @@ -782,9 +751,13 @@ |
80 | normal = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, |
81 | width, |
82 | height); |
83 | - if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) { |
84 | + if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) |
85 | + { |
86 | + cairo_surface_destroy (scratch); |
87 | + |
88 | if (normal) |
89 | cairo_surface_destroy (normal); |
90 | + |
91 | return; |
92 | } |
93 | |
94 | @@ -793,9 +766,12 @@ |
95 | height); |
96 | if (cairo_surface_status (blurred) != CAIRO_STATUS_SUCCESS) |
97 | { |
98 | + cairo_surface_destroy (normal); |
99 | + cairo_surface_destroy (scratch); |
100 | + |
101 | if (blurred) |
102 | cairo_surface_destroy (blurred); |
103 | - cairo_surface_destroy (normal); |
104 | + |
105 | return; |
106 | } |
107 | } |
108 | @@ -805,9 +781,13 @@ |
109 | normal = cairo_image_surface_create (CAIRO_FORMAT_RGB24, |
110 | width, |
111 | height); |
112 | - if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) { |
113 | + if (cairo_surface_status (normal) != CAIRO_STATUS_SUCCESS) |
114 | + { |
115 | + cairo_surface_destroy (scratch); |
116 | + |
117 | if (normal) |
118 | cairo_surface_destroy (normal); |
119 | + |
120 | return; |
121 | } |
122 | } |
123 | @@ -821,8 +801,11 @@ |
124 | { |
125 | cairo_surface_destroy (normal); |
126 | cairo_surface_destroy (blurred); |
127 | + cairo_surface_destroy (scratch); |
128 | + |
129 | if (cr) |
130 | cairo_destroy (cr); |
131 | + |
132 | return; |
133 | } |
134 | |
135 | @@ -851,6 +834,7 @@ |
136 | if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) |
137 | { |
138 | cairo_surface_destroy (normal); |
139 | + cairo_surface_destroy (scratch); |
140 | |
141 | if (priv->composited) |
142 | cairo_surface_destroy (blurred); |
143 | @@ -890,6 +874,7 @@ |
144 | cairo_surface_destroy (blurred); |
145 | |
146 | cairo_surface_destroy (normal); |
147 | + cairo_surface_destroy (scratch); |
148 | } |
149 | |
150 | void |
151 | @@ -947,13 +932,14 @@ |
152 | void |
153 | _refresh_title (Bubble* self) |
154 | { |
155 | - BubblePrivate* priv = GET_PRIVATE (self); |
156 | - Defaults* d = self->defaults; |
157 | - cairo_surface_t* normal = NULL; |
158 | - cairo_t* cr = NULL; |
159 | - PangoFontDescription* desc = NULL; |
160 | - PangoLayout* layout = NULL; |
161 | - raico_blur_t* blur = NULL; |
162 | + BubblePrivate* priv = GET_PRIVATE (self); |
163 | + Defaults* d = self->defaults; |
164 | + cairo_surface_t* normal = NULL; |
165 | + cairo_t* cr = NULL; |
166 | + PangoFontDescription* desc = NULL; |
167 | + PangoLayout* layout = NULL; |
168 | + raico_blur_t* blur = NULL; |
169 | + gchar* text_font_face = NULL; |
170 | |
171 | // create temp. scratch surface |
172 | normal = cairo_image_surface_create ( |
173 | @@ -986,13 +972,14 @@ |
174 | defaults_get_text_title_size (d) * |
175 | PANGO_SCALE); |
176 | |
177 | - pango_font_description_set_family_static (desc, |
178 | - defaults_get_text_font_face (d)); |
179 | + text_font_face = defaults_get_text_font_face (d); |
180 | + pango_font_description_set_family_static (desc, text_font_face); |
181 | pango_font_description_set_weight (desc, |
182 | defaults_get_text_title_weight (d)); |
183 | pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); |
184 | pango_layout_set_font_description (layout, desc); |
185 | pango_font_description_free (desc); |
186 | + g_free ((gpointer) text_font_face); |
187 | |
188 | pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); |
189 | pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); |
190 | @@ -1051,13 +1038,14 @@ |
191 | void |
192 | _refresh_body (Bubble* self) |
193 | { |
194 | - BubblePrivate* priv = GET_PRIVATE (self); |
195 | - Defaults* d = self->defaults; |
196 | - cairo_surface_t* normal = NULL; |
197 | - cairo_t* cr = NULL; |
198 | - PangoFontDescription* desc = NULL; |
199 | - PangoLayout* layout = NULL; |
200 | - raico_blur_t* blur = NULL; |
201 | + BubblePrivate* priv = GET_PRIVATE (self); |
202 | + Defaults* d = self->defaults; |
203 | + cairo_surface_t* normal = NULL; |
204 | + cairo_t* cr = NULL; |
205 | + PangoFontDescription* desc = NULL; |
206 | + PangoLayout* layout = NULL; |
207 | + raico_blur_t* blur = NULL; |
208 | + gchar* text_font_face = NULL; |
209 | |
210 | // create temp. scratch surface |
211 | normal = cairo_image_surface_create ( |
212 | @@ -1090,13 +1078,14 @@ |
213 | defaults_get_text_body_size (d) * |
214 | PANGO_SCALE); |
215 | |
216 | - pango_font_description_set_family_static (desc, |
217 | - defaults_get_text_font_face (d)); |
218 | + text_font_face = defaults_get_text_font_face (d); |
219 | + pango_font_description_set_family_static (desc, text_font_face); |
220 | pango_font_description_set_weight (desc, |
221 | defaults_get_text_body_weight (d)); |
222 | pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); |
223 | pango_layout_set_font_description (layout, desc); |
224 | pango_font_description_free (desc); |
225 | + g_free ((gpointer) text_font_face); |
226 | |
227 | pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); |
228 | pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); |
229 | @@ -1787,7 +1776,6 @@ |
230 | GdkPixbuf* buffer = NULL; |
231 | GdkPixbuf* pixbuf = NULL; |
232 | GtkIconTheme* theme = NULL; |
233 | - GFile* file = NULL; |
234 | GError* error = NULL; |
235 | |
236 | /* sanity check */ |
237 | @@ -1797,9 +1785,7 @@ |
238 | if (!strncmp (filename, "file://", 7)) |
239 | filename += 7; |
240 | |
241 | - file = g_file_new_for_path (filename); |
242 | - if (g_file_query_exists (file, NULL)) |
243 | - /* Implementation note: blocking I/O; could be cancellable though */ |
244 | + if (filename[0] == '/') |
245 | { |
246 | /* load image into pixbuf */ |
247 | pixbuf = gdk_pixbuf_new_from_file_at_scale (filename, |
248 | @@ -2226,7 +2212,7 @@ |
249 | this->priv->layout = LAYOUT_NONE; |
250 | this->priv->widget = window; |
251 | this->priv->title = g_string_new (""); |
252 | - this->priv->message_body = g_string_new (""); |
253 | + this->priv->message_body = NULL; |
254 | this->priv->icon_pixbuf = NULL; |
255 | this->priv->value = -2; |
256 | this->priv->visible = FALSE; |
257 | @@ -2314,7 +2300,7 @@ |
258 | |
259 | priv = GET_PRIVATE (self); |
260 | |
261 | - if (priv->message_body->len != 0) |
262 | + if (priv->message_body && priv->message_body->len != 0) |
263 | { |
264 | g_signal_emit (self, |
265 | g_bubble_signals[MESSAGE_BODY_DELETED], |
266 | @@ -3049,6 +3035,7 @@ |
267 | PangoRectangle log_rect = {0, 0, 0, 0}; |
268 | gint title_height; |
269 | BubblePrivate* priv; |
270 | + gchar* text_font_face = NULL; |
271 | |
272 | if (!self || !IS_BUBBLE (self)) |
273 | return 0; |
274 | @@ -3089,9 +3076,8 @@ |
275 | defaults_get_text_title_size (d) * |
276 | PANGO_SCALE); |
277 | |
278 | - pango_font_description_set_family_static ( |
279 | - desc, |
280 | - defaults_get_text_font_face (d)); |
281 | + text_font_face = defaults_get_text_font_face (d); |
282 | + pango_font_description_set_family_static (desc, text_font_face); |
283 | |
284 | pango_font_description_set_weight ( |
285 | desc, |
286 | @@ -3100,6 +3086,7 @@ |
287 | pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); |
288 | pango_layout_set_font_description (layout, desc); |
289 | pango_font_description_free (desc); |
290 | + g_free ((gpointer) text_font_face); |
291 | |
292 | pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END); |
293 | pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR); |
294 | @@ -3127,6 +3114,7 @@ |
295 | PangoRectangle log_rect; |
296 | gint body_height; |
297 | BubblePrivate* priv; |
298 | + gchar* text_font_face = NULL; |
299 | |
300 | if (!self || !IS_BUBBLE (self)) |
301 | return 0; |
302 | @@ -3159,9 +3147,8 @@ |
303 | defaults_get_text_body_size (d) * |
304 | PANGO_SCALE); |
305 | |
306 | - pango_font_description_set_family_static ( |
307 | - desc, |
308 | - defaults_get_text_font_face (d)); |
309 | + text_font_face = defaults_get_text_font_face (d); |
310 | + pango_font_description_set_family_static (desc, text_font_face); |
311 | |
312 | pango_font_description_set_weight ( |
313 | desc, |
314 | @@ -3222,6 +3209,7 @@ |
315 | body_height = PANGO_PIXELS (log_rect.height); |
316 | |
317 | pango_font_description_free (desc); |
318 | + g_free ((gpointer) text_font_face); |
319 | g_object_unref (layout); |
320 | cairo_destroy (cr); |
321 | |
322 | |
323 | === modified file 'src/defaults.c' |
324 | --- src/defaults.c 2009-09-16 12:33:40 +0000 |
325 | +++ src/defaults.c 2009-09-18 19:48:10 +0000 |
326 | @@ -179,15 +179,17 @@ |
327 | GString* font_face = NULL; |
328 | gdouble dpi = 0.0f; |
329 | gdouble pixels_per_em = 0; |
330 | + gchar* font_name = NULL; |
331 | |
332 | if (!IS_DEFAULTS (self)) |
333 | return; |
334 | |
335 | /* determine current system font-name/size */ |
336 | error = NULL; |
337 | - string = g_string_new (gconf_client_get_string (self->context, |
338 | - GCONF_UI_FONT_NAME, |
339 | - &error)); |
340 | + font_name = gconf_client_get_string (self->context, |
341 | + GCONF_UI_FONT_NAME, |
342 | + &error); |
343 | + string = g_string_new (font_name); |
344 | if (error) |
345 | { |
346 | /* if something went wrong, assume "Sans 10" and continue */ |
347 | @@ -197,6 +199,7 @@ |
348 | error->message); |
349 | g_error_free (error); |
350 | } |
351 | + g_free ((gpointer) font_name); |
352 | |
353 | /* extract font-family-name and font-size */ |
354 | scanner = g_scanner_new (NULL); |
355 | @@ -430,63 +433,6 @@ |
356 | g_signal_emit (defaults, g_defaults_signals[GRAVITY_CHANGED], 0); |
357 | } |
358 | |
359 | -static gdouble |
360 | -_get_average_char_width (Defaults* self) |
361 | -{ |
362 | - cairo_surface_t* surface; |
363 | - cairo_t* cr; |
364 | - PangoFontDescription* desc; |
365 | - PangoLayout* layout; |
366 | - PangoContext* context; |
367 | - PangoLanguage* language; |
368 | - PangoFontMetrics* metrics; |
369 | - gint char_width; |
370 | - |
371 | - if (!self || !IS_DEFAULTS (self)) |
372 | - return 0; |
373 | - |
374 | - surface = cairo_image_surface_create (CAIRO_FORMAT_A1, 1, 1); |
375 | - if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS) |
376 | - return 0; |
377 | - |
378 | - cr = cairo_create (surface); |
379 | - cairo_surface_destroy (surface); |
380 | - if (cairo_status (cr) != CAIRO_STATUS_SUCCESS) |
381 | - return 0; |
382 | - |
383 | - layout = pango_cairo_create_layout (cr); |
384 | - desc = pango_font_description_new (); |
385 | - pango_font_description_set_size ( |
386 | - desc, |
387 | - EM2PIXELS (defaults_get_text_title_size (self), self) * |
388 | - PANGO_SCALE); |
389 | - |
390 | - pango_font_description_set_family_static ( |
391 | - desc, |
392 | - defaults_get_text_font_face (self)); |
393 | - |
394 | - pango_font_description_set_weight ( |
395 | - desc, |
396 | - defaults_get_text_title_weight (self)); |
397 | - |
398 | - pango_font_description_set_style (desc, PANGO_STYLE_NORMAL); |
399 | - pango_layout_set_wrap (layout, PANGO_WRAP_WORD); |
400 | - pango_layout_set_font_description (layout, desc); |
401 | - |
402 | - context = pango_layout_get_context (layout); /* no need to unref */ |
403 | - language = pango_language_get_default (); /* no need to unref */ |
404 | - metrics = pango_context_get_metrics (context, desc, language); |
405 | - char_width = pango_font_metrics_get_approximate_char_width (metrics); |
406 | - |
407 | - /* clean up */ |
408 | - pango_font_metrics_unref (metrics); |
409 | - pango_font_description_free (desc); |
410 | - g_object_unref (layout); |
411 | - cairo_destroy (cr); |
412 | - |
413 | - return PIXELS2EM (char_width / PANGO_SCALE, self); |
414 | -} |
415 | - |
416 | void |
417 | defaults_refresh_screen_dimension_properties (Defaults *self) |
418 | { |
419 | @@ -562,9 +508,6 @@ |
420 | gdouble icon_size; |
421 | gdouble bubble_height; |
422 | gdouble new_bubble_height; |
423 | - gdouble bubble_width; |
424 | - gdouble new_bubble_width; |
425 | - gdouble average_char_width; |
426 | |
427 | self = DEFAULTS (gobject); |
428 | |
429 | @@ -605,31 +548,6 @@ |
430 | NULL); |
431 | } |
432 | |
433 | - /* correct the default bubble-width depending on the average width of a |
434 | - * character rendered in the default system-font at the default |
435 | - * font-size, |
436 | - * as default layout, we'll take the icon+title+body+message case, thus |
437 | - * seen from left to right we use: |
438 | - * |
439 | - * margin + icon_size + margin + 20 * avg_char_width + margin |
440 | - */ |
441 | - g_object_get (self, |
442 | - "bubble-width", |
443 | - &bubble_width, |
444 | - NULL); |
445 | - average_char_width = _get_average_char_width (self); |
446 | - |
447 | - new_bubble_width = 3.0f * margin_size + |
448 | - icon_size + |
449 | - 20.0f * average_char_width; |
450 | - /*if (new_bubble_width > bubble_width) |
451 | - { |
452 | - g_object_set (self, |
453 | - "bubble-width", |
454 | - new_bubble_width, |
455 | - NULL); |
456 | - }*/ |
457 | - |
458 | /* FIXME: calling this here causes a segfault */ |
459 | /* chain up to the parent class */ |
460 | /*G_OBJECT_CLASS (defaults_parent_class)->constructed (gobject);*/ |
461 | @@ -2431,19 +2349,22 @@ |
462 | static gboolean |
463 | defaults_multihead_does_focus_follow (Defaults *self) |
464 | { |
465 | - GError *error = NULL; |
466 | - gboolean mode = FALSE; |
467 | + GError* error = NULL; |
468 | + gboolean mode = FALSE; |
469 | |
470 | g_return_val_if_fail (self != NULL && IS_DEFAULTS (self), FALSE); |
471 | |
472 | - gchar *mode_str = gconf_client_get_string (self->context, |
473 | + gchar* mode_str = gconf_client_get_string (self->context, |
474 | GCONF_MULTIHEAD_MODE, |
475 | &error); |
476 | if (mode_str != NULL) |
477 | { |
478 | if (! g_strcmp0 (mode_str, "focus-follow")) |
479 | mode = TRUE; |
480 | - } else if (error != NULL) |
481 | + |
482 | + g_free ((gpointer) mode_str); |
483 | + } |
484 | + else if (error != NULL) |
485 | { |
486 | g_warning ("defaults_multihead_does_focus_follow(): " |
487 | "Got error \"%s\"\n", |
488 | |
489 | === modified file 'tests/test-scroll-text.c' |
490 | --- tests/test-scroll-text.c 2009-08-04 17:34:48 +0000 |
491 | +++ tests/test-scroll-text.c 2009-09-23 01:06:20 +0000 |
492 | @@ -64,8 +64,6 @@ |
493 | cairo_t* cr; |
494 | PangoFontDescription* desc; |
495 | PangoLayout* layout; |
496 | - PangoRectangle ink_rect; |
497 | - PangoRectangle log_rect; |
498 | |
499 | // sanity check |
500 | if (!text || |
501 | @@ -112,7 +110,6 @@ |
502 | |
503 | // print and layout string (pango-wise) |
504 | pango_layout_set_text (layout, text, -1); |
505 | - pango_layout_get_extents (layout, &ink_rect, &log_rect); |
506 | |
507 | // make sure system-wide font-options like hinting, antialiasing etc. |
508 | // are taken into account |
509 | @@ -126,6 +123,8 @@ |
510 | cairo_move_to (cr, 0.0f, 0.0f); |
511 | cairo_set_operator (cr, CAIRO_OPERATOR_OVER); |
512 | cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); |
513 | + |
514 | + // this call leaks 3803 bytes, I've no idea how to fix that |
515 | pango_cairo_show_layout (cr, layout); |
516 | |
517 | // clean up |
518 | @@ -749,6 +748,7 @@ |
519 | cairo_set_source_surface (cr, text, 0.0f, 0.0f); |
520 | cairo_paint (cr); |
521 | |
522 | + cairo_destroy (cr); |
523 | cairo_surface_destroy (text); |
524 | tile = tile_new (surface, 6); |
525 | cairo_surface_destroy (surface); |
526 | @@ -870,11 +870,13 @@ |
527 | |
528 | // actually create the tile with padding in mind |
529 | tile = tile_new_for_padding (norm_surf, blur_surf); |
530 | + destroy_cloned_surface (norm_surf); |
531 | + destroy_cloned_surface (blur_surf); |
532 | + destroy_cloned_surface (dummy_surf); |
533 | |
534 | cairo_destroy (cr); |
535 | cairo_surface_destroy (cr_surf); |
536 | |
537 | - cairo_surface_destroy (norm_surf); |
538 | norm_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); |
539 | cr = cairo_create (norm_surf); |
540 | cairo_scale (cr, 1.0f, 1.0f); |
541 | @@ -884,7 +886,6 @@ |
542 | tile_paint_with_padding (tile, cr, 0.0f, 0.0f, w, h, 1.0f, 0.0f); |
543 | cairo_destroy (cr); |
544 | |
545 | - cairo_surface_destroy (blur_surf); |
546 | blur_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, w, h); |
547 | cr = cairo_create (blur_surf); |
548 | cairo_scale (cr, 1.0f, 1.0f); |
549 | @@ -897,7 +898,7 @@ |
550 | g_tile = tile_new_for_padding (norm_surf, blur_surf); |
551 | |
552 | // clean up |
553 | - cairo_surface_destroy (dummy_surf); |
554 | + tile_destroy (tile); |
555 | cairo_surface_destroy (norm_surf); |
556 | cairo_surface_destroy (blur_surf); |
557 | } |
This fixes numerous mem-leaks identified by valgrind'ing notify-osd, examples and tests. It is by no means complete, but a good start. The work sofar showed that lots of the mem-leaks sadly happen outside of notify-osd scope (e.g. libfontconfig, libfreetype, libpango ...) resulting in notify-osd still leaking like sieve unfortunately.