Merge lp:~gordallott/unity/unity.fix-bg-hash-crashers into lp:unity

Proposed by Gord Allott
Status: Merged
Approved by: Gord Allott
Approved revision: no longer in the source branch.
Merged at revision: 1385
Proposed branch: lp:~gordallott/unity/unity.fix-bg-hash-crashers
Merge into: lp:unity
Diff against target: 414 lines (+165/-101)
3 files modified
plugins/unityshell/src/BGHash.cpp (+148/-96)
plugins/unityshell/src/BGHash.h (+9/-1)
tests/TestBGHash.cpp (+8/-4)
To merge this branch: bzr merge lp:~gordallott/unity/unity.fix-bg-hash-crashers
Reviewer Review Type Date Requested Status
Sam Spilsbury (community) Approve
Review via email: mp+72020@code.launchpad.net

Description of the change

Fixes a few (hopefully linked) bugs in the bghash code, the race seems to be fixed on my machine as well as the crazy alpha problem, segfaults should be gone too

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

Looks good to me

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/unityshell/src/BGHash.cpp'
2--- plugins/unityshell/src/BGHash.cpp 2011-08-12 04:16:44 +0000
3+++ plugins/unityshell/src/BGHash.cpp 2011-08-18 11:16:32 +0000
4@@ -18,6 +18,7 @@
5
6 #include "BGHash.h"
7 #include <Nux/Nux.h>
8+#include <NuxCore/Logger.h>
9 #include <gdk-pixbuf/gdk-pixbuf.h>
10 #include <libgnome-desktop/gnome-bg.h>
11 #include <unity-misc/gnome-bg-slideshow.h>
12@@ -25,6 +26,11 @@
13 #include "UBusMessages.h"
14 #include "UnityCore/GLibWrapper.h"
15
16+namespace
17+{
18+ nux::logging::Logger logger("unity.BGHash");
19+}
20+
21 namespace {
22 int level_of_recursion;
23 const int MAX_LEVEL_OF_RECURSION = 16;
24@@ -37,9 +43,9 @@
25 _bg_slideshow (NULL),
26 _current_slide (NULL),
27 _slideshow_handler(0),
28- _current_color (nux::color::DimGray),
29- _new_color (nux::color::DimGray),
30- _old_color (nux::color::DimGray),
31+ _current_color (unity::colors::Aubergine),
32+ _new_color (unity::colors::Aubergine),
33+ _old_color (unity::colors::Aubergine),
34 _hires_time_start(10),
35 _hires_time_end(20),
36 _ubus_handle_request_colour(0)
37@@ -47,9 +53,6 @@
38 background_monitor = gnome_bg_new ();
39 client = g_settings_new ("org.gnome.desktop.background");
40
41- glib::Object<GdkPixbuf> pixbuf(GetPixbufFromBG());
42- LoadPixbufToHash(pixbuf);
43-
44 signal_manager_.Add(
45 new glib::Signal<void, GnomeBG*>(background_monitor,
46 "changed",
47@@ -64,6 +67,9 @@
48
49 gnome_bg_load_from_preferences (background_monitor, client);
50
51+ glib::Object<GdkPixbuf> pixbuf(GetPixbufFromBG());
52+ LoadPixbufToHash(pixbuf);
53+
54 g_timeout_add (0, (GSourceFunc)ForceUpdate, (gpointer)this);
55
56 // avoids making a new object method when all we are doing is
57@@ -90,7 +96,7 @@
58 gboolean BGHash::ForceUpdate (BGHash *self)
59 {
60 self->OnBackgroundChanged(self->background_monitor);
61- return FALSE;
62+ return FALSE;
63 }
64
65 void BGHash::OnGSettingsChanged (GSettings *settings, gchar *key)
66@@ -101,98 +107,135 @@
67 void BGHash::OnBackgroundChanged (GnomeBG *bg)
68 {
69 const gchar *filename = gnome_bg_get_filename (bg);
70- if (_bg_slideshow != NULL)
71- {
72- slideshow_unref (_bg_slideshow);
73- _bg_slideshow = NULL;
74- _current_slide = NULL;
75- }
76-
77- if (_slideshow_handler)
78- {
79- g_source_remove (_slideshow_handler);
80- _slideshow_handler = 0;
81- }
82-
83- if (g_str_has_suffix (filename, "xml"))
84- {
85- GError *error = NULL;
86-
87+ if (filename == NULL)
88+ {
89+ // we might have a gradient instead
90+ GdkColor color_primary, color_secondary;
91+ GDesktopBackgroundShading shading_type;
92+ nux::Color parsed_color;
93+
94+ gnome_bg_get_color (bg, &shading_type, &color_primary, &color_secondary);
95+ if (shading_type == G_DESKTOP_BACKGROUND_SHADING_HORIZONTAL ||
96+ shading_type == G_DESKTOP_BACKGROUND_SHADING_SOLID)
97+ {
98+ parsed_color = nux::Color(static_cast<float>(color_primary.red) / 65535,
99+ static_cast<float>(color_primary.green) / 65535,
100+ static_cast<float>(color_primary.blue) / 65535,
101+ 1.0f);
102+ }
103+ else
104+ {
105+ nux::Color primary = nux::Color(static_cast<float>(color_primary.red) / 65535,
106+ static_cast<float>(color_primary.green) / 65535,
107+ static_cast<float>(color_primary.blue) / 65535,
108+ 1.0f);
109+
110+ nux::Color secondary = nux::Color(static_cast<float>(color_secondary.red) / 65535,
111+ static_cast<float>(color_secondary.green) / 65535,
112+ static_cast<float>(color_secondary.blue) / 65535,
113+ 1.0f);
114+
115+ parsed_color = (primary + secondary) * 0.5f;
116+ }
117+
118+ nux::Color new_color = MatchColor (parsed_color);
119+ TransitionToNewColor (new_color);
120+ }
121+ else
122+ {
123 if (_bg_slideshow != NULL)
124 {
125 slideshow_unref (_bg_slideshow);
126 _bg_slideshow = NULL;
127- }
128-
129- _bg_slideshow = read_slideshow_file (filename, &error);
130-
131- if (error != NULL)
132- {
133- g_warning ("BGHash.cpp: could not load filename %s: %s", filename, error->message);
134- g_error_free (error);
135- }
136- else if (_bg_slideshow == NULL)
137- {
138- g_warning ("BGHash.cpp: could not load filename %s", filename);
139- }
140- else
141- {
142- // we loaded fine, hook up to the slideshow
143- time_t current_time = time(0);
144- double now = (double) current_time;
145-
146- double time_diff = now - _bg_slideshow->start_time;
147- double progress = fmod (time_diff, _bg_slideshow->total_duration);
148-
149- // progress now holds how many seconds we are in to this slideshow.
150- // iterate over the slideshows until we get in to the current slideshow
151- Slide *slide_iteration;
152- Slide *slide_current = NULL;
153- double elapsed = 0;
154- double time_to_next_change = 0;
155- GList *list;
156-
157- for (list = _bg_slideshow->slides->head; list != NULL; list = list->next)
158- {
159- slide_iteration = reinterpret_cast<Slide *>(list->data);
160- if (elapsed + slide_iteration->duration > progress)
161- {
162- slide_current = slide_iteration;
163- time_to_next_change = slide_current->duration- (progress - elapsed);
164- break;
165- }
166-
167- elapsed += slide_iteration->duration;
168- }
169-
170- if (slide_current == NULL)
171- {
172- slide_current = reinterpret_cast<Slide *>(g_queue_peek_head(_bg_slideshow->slides));
173- time_to_next_change = slide_current->duration;
174- }
175-
176- // time_to_next_change now holds the seconds until the next slide change
177- // the next slide change may or may not be a fixed slide.
178- _slideshow_handler = g_timeout_add ((guint)(time_to_next_change * 1000),
179- (GSourceFunc)OnSlideshowTransition,
180- (gpointer)this);
181-
182- // find our current slide now
183- if (slide_current->file1 == NULL)
184- {
185- g_warning ("BGHash.cpp: could not load filename %s - slide has no filename", filename);
186+ _current_slide = NULL;
187+ }
188+
189+ if (_slideshow_handler)
190+ {
191+ g_source_remove (_slideshow_handler);
192+ _slideshow_handler = 0;
193+ }
194+
195+ if (g_str_has_suffix (filename, "xml"))
196+ {
197+ GError *error = NULL;
198+
199+ if (_bg_slideshow != NULL)
200+ {
201+ slideshow_unref (_bg_slideshow);
202+ _bg_slideshow = NULL;
203+ }
204+
205+ _bg_slideshow = read_slideshow_file (filename, &error);
206+
207+ if (error != NULL)
208+ {
209+ LOG_WARNING(logger) << "Could not load filename \"" << filename << "\": " << error->message;
210+ g_error_free (error);
211+ }
212+ else if (_bg_slideshow == NULL)
213+ {
214+ LOG_WARNING(logger) << "Could not load filename \"" << filename << "\"";
215 }
216 else
217 {
218- FileSize *fs = reinterpret_cast<FileSize *>(slide_current->file1->data);
219- filename = reinterpret_cast<gchar *>(fs->file);
220+ // we loaded fine, hook up to the slideshow
221+ time_t current_time = time(0);
222+ double now = (double) current_time;
223+
224+ double time_diff = now - _bg_slideshow->start_time;
225+ double progress = fmod (time_diff, _bg_slideshow->total_duration);
226+
227+ // progress now holds how many seconds we are in to this slideshow.
228+ // iterate over the slideshows until we get in to the current slideshow
229+ Slide *slide_iteration;
230+ Slide *slide_current = NULL;
231+ double elapsed = 0;
232+ double time_to_next_change = 0;
233+ GList *list;
234+
235+ for (list = _bg_slideshow->slides->head; list != NULL; list = list->next)
236+ {
237+ slide_iteration = reinterpret_cast<Slide *>(list->data);
238+ if (elapsed + slide_iteration->duration > progress)
239+ {
240+ slide_current = slide_iteration;
241+ time_to_next_change = slide_current->duration- (progress - elapsed);
242+ break;
243+ }
244+
245+ elapsed += slide_iteration->duration;
246+ }
247+
248+ if (slide_current == NULL)
249+ {
250+ slide_current = reinterpret_cast<Slide *>(g_queue_peek_head(_bg_slideshow->slides));
251+ time_to_next_change = slide_current->duration;
252+ }
253+
254+ // time_to_next_change now holds the seconds until the next slide change
255+ // the next slide change may or may not be a fixed slide.
256+ _slideshow_handler = g_timeout_add ((guint)(time_to_next_change * 1000),
257+ (GSourceFunc)OnSlideshowTransition,
258+ (gpointer)this);
259+
260+ // find our current slide now
261+ if (slide_current->file1 == NULL)
262+ {
263+ LOG_WARNING(logger) << "Could not load filename \"" << filename << "\"";
264+ }
265+ else
266+ {
267+ FileSize *fs = reinterpret_cast<FileSize *>(slide_current->file1->data);
268+ filename = reinterpret_cast<gchar *>(fs->file);
269+ }
270+
271+ _current_slide = slide_current;
272 }
273-
274- _current_slide = slide_current;
275 }
276+
277+ LoadFileToHash(filename);
278 }
279-
280- LoadFileToHash(filename);
281 }
282
283 gboolean BGHash::OnSlideshowTransition (BGHash *self)
284@@ -235,7 +278,7 @@
285 const gchar *filename = NULL;
286 if (proposed_slide->file1 == NULL)
287 {
288- g_warning ("BGHash.cpp: could not load filename %s - slide has no filename", filename);
289+ LOG_WARNING(logger) << "Could not load filename \"" << filename << "\"";
290 }
291 else
292 {
293@@ -310,7 +353,7 @@
294 _current_color.red * 0.7f,
295 _current_color.green * 0.7f,
296 _current_color.blue * 0.7f,
297- _current_color.alpha)
298+ 0.5)
299 );
300 }
301
302@@ -336,10 +379,17 @@
303
304 void BGHash::LoadPixbufToHash(GdkPixbuf *pixbuf)
305 {
306+ nux::Color new_color;
307 if (pixbuf == NULL)
308- return;
309+ {
310+ LOG_WARNING(logger) << "Passed in a bad pixbuf, defaulting colour";
311+ new_color = unity::colors::Aubergine;
312+ }
313+ else
314+ {
315+ new_color = HashColor (pixbuf);
316+ }
317
318- nux::Color new_color = HashColor (pixbuf);
319 TransitionToNewColor (new_color);
320 }
321
322@@ -350,8 +400,12 @@
323
324 if (error)
325 {
326+ LOG_WARNING(logger) << "Could not load filename \"" << path << "\": " << error.Message();
327 _current_color = nux::Color(0.2, 0.2, 0.2, 0.9);
328- return;
329+
330+ // try and get a colour from gnome-bg, for various reasons, gnome bg might not
331+ // return a correct image which sucks =\ but this is a fallback
332+ pixbuf = GetPixbufFromBG();
333 }
334
335 LoadPixbufToHash (pixbuf);
336@@ -507,8 +561,6 @@
337 // apply design to the colour
338 chosen_color.alpha = 0.5f;
339
340-
341-
342 return chosen_color;
343 }
344
345
346=== modified file 'plugins/unityshell/src/BGHash.h'
347--- plugins/unityshell/src/BGHash.h 2011-08-11 16:47:44 +0000
348+++ plugins/unityshell/src/BGHash.h 2011-08-18 11:16:32 +0000
349@@ -25,11 +25,19 @@
350 #include <unity-misc/gnome-bg-slideshow.h>
351 #include <UnityCore/GLibSignal.h>
352
353+namespace unity {
354+namespace colors {
355+ const nux::Color Aubergine(0x3E, 0x20, 0x60);
356+};
357+};
358+
359 namespace unity
360 {
361 class BGHash
362 {
363 public:
364+
365+
366 BGHash ();
367 ~BGHash ();
368
369@@ -67,7 +75,7 @@
370
371 guint64 _hires_time_start;
372 guint64 _hires_time_end;
373- glib::SignalManager signal_manager_;
374+ glib::SignalManager signal_manager_;
375 uint _ubus_handle_request_colour;
376 };
377 };
378
379=== modified file 'tests/TestBGHash.cpp'
380--- tests/TestBGHash.cpp 2011-07-28 11:02:56 +0000
381+++ tests/TestBGHash.cpp 2011-08-18 11:16:32 +0000
382@@ -16,9 +16,10 @@
383 *
384 * Authored by: Gordon Allott <gord.allott@canonical.com>
385 */
386-#include "Nux/Nux.h"
387-#include "Nux/WindowThread.h"
388-#include "NuxGraphics/GraphicsEngine.h"
389+#include <Nux/Nux.h>
390+#include <NuxCore/Logger.h>
391+#include <Nux/WindowThread.h>
392+#include <NuxGraphics/GraphicsEngine.h>
393 #include <gtk/gtk.h>
394
395 #include "BGHash.h"
396@@ -84,7 +85,7 @@
397 int main(int argc, char **argv)
398 {
399 UBusServer *ubus;
400- unity::BGHash bg_hash;
401+
402 nux::SystemThread* st = NULL;
403 nux::WindowThread* wt = NULL;
404
405@@ -97,6 +98,9 @@
406 gtk_init (&argc, &argv);
407
408 nux::NuxInitialize(0);
409+ nux::logging::configure_logging(::getenv("UNITY_LOG_SEVERITY"));
410+
411+ unity::BGHash bg_hash;
412
413 ubus = ubus_server_get_default ();
414 ubus_server_register_interest (ubus, UBUS_BACKGROUND_COLOR_CHANGED,