commit dd206abe4e48f098e1026e525a38b04305b6007b
Author: phantomjinx <p.g.richard...@phantomjinx.co.uk>
Date:   Sat Nov 5 23:11:54 2011 +0000

    Fix for cogl errors generated by clarity plugin
    
    * Bug evident in clarity when plugin window is loaded but initially
      obscured by other plugin windows. Making the window visible generates
      cogl texture errors as the window is not completely realised by the time
      the load texture functions are called.
    
    * All signal callbacks now check whether the window has been realized before
      trying to go any further.
    
    * Realized signal callback added to ensure that when the window is made
      visible, the current playlist is loaded.
    
    * g_idle_add functions used to slow down the initialisation of cogl textures
      until the window has been fully realized.

 plugins/clarity/clarity_canvas.c |   25 ++++-
 plugins/clarity/clarity_widget.c |  214 ++++++++++++++++++++++++++------------
 2 files changed, 172 insertions(+), 67 deletions(-)
---
diff --git a/plugins/clarity/clarity_canvas.c b/plugins/clarity/clarity_canvas.c
index ba71c9c..db770c4 100644
--- a/plugins/clarity/clarity_canvas.c
+++ b/plugins/clarity/clarity_canvas.c
@@ -548,6 +548,16 @@ static gpointer _init_album_model(gpointer data) {
     return NULL;
 }
 
+static gboolean _init_album_model_idle(gpointer data) {
+    g_return_val_if_fail(CLARITY_IS_CANVAS(data), FALSE);
+
+    ClarityCanvas *self = CLARITY_CANVAS(data);
+
+    _init_album_model(self);
+
+    return FALSE;
+}
+
 void clarity_canvas_init_album_model(ClarityCanvas *self, AlbumModel *model) {
     g_return_if_fail(self);
     g_return_if_fail(model);
@@ -558,8 +568,19 @@ void clarity_canvas_init_album_model(ClarityCanvas *self, 
AlbumModel *model) {
     ClarityCanvasPrivate *priv = CLARITY_CANVAS_GET_PRIVATE(self);
     priv->model = model;
 
-    _init_album_model(self);
-
+    /*
+     * Necessary to avoid generating cogl errors in the following use case:
+     * 1) Load gtkpod with clarity plugin window docked in the gui but
+     *      obscured by another plugin window.
+     * 2) Select a playlist.
+     * 3) Select the relevant toggle button to bring the clarity window to
+     *      the front and visible.
+     *
+     * This function gets called during the realized signal callback so using
+     * g_idle_add lets the realized callback finish and the window display
+     * before loading the cogl textures.
+     */
+    g_idle_add(_init_album_model_idle, self);
 }
 
 static void _clear_rotation_behaviours(GList *covers) {
diff --git a/plugins/clarity/clarity_widget.c b/plugins/clarity/clarity_widget.c
index 1c51f71..ad709e8 100644
--- a/plugins/clarity/clarity_widget.c
+++ b/plugins/clarity/clarity_widget.c
@@ -235,6 +235,132 @@ static void _set_text_color(ClarityWidget *self) {
     clarity_canvas_set_text_color(CLARITY_CANVAS(priv->draw_area), hex_string);
 }
 
+/**
+ * Sort the given list of tracks based on the clarity_sort preference
+ */
+GList *_sort_track_list(GList *tracks) {
+    enum GtkPodSortTypes value = prefs_get_int("clarity_sort");
+
+    switch(value) {
+        case SORT_ASCENDING:
+            tracks = g_list_sort(tracks, (GCompareFunc) compare_tracks);
+            break;
+        case SORT_DESCENDING:
+            tracks = g_list_sort(tracks, (GCompareFunc) compare_tracks);
+            tracks = g_list_reverse(tracks);
+            break;
+        default:
+            // Do Nothing
+            break;
+    }
+
+    return tracks;
+}
+
+/**
+ * Clear the clarity canvas of all tracks and album covers
+ */
+static void _clarity_widget_clear(ClarityWidget *self) {
+    ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(self);
+    clarity_canvas_clear(CLARITY_CANVAS(priv->draw_area));
+    album_model_clear(priv->album_model);
+}
+
+/**
+ * Reload the clarity canvas with the given playlist.
+ */
+static void _init_clarity_with_playlist(ClarityWidget *cw, Playlist *playlist) 
{
+    if (! gtk_widget_get_realized(GTK_WIDGET(cw)))
+        return;
+
+    if (cw->current_playlist == playlist)
+        // Should already have all these tracks displayed
+        return;
+
+    _clarity_widget_clear(cw);
+
+    cw->current_playlist = playlist;
+    GList *tracks = playlist->members;
+    if (!tracks)
+        return;
+
+    ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(cw);
+
+    album_model_add_tracks(priv->album_model, tracks);
+
+    clarity_canvas_init_album_model(CLARITY_CANVAS(priv->draw_area), 
priv->album_model);
+
+    _init_slider_range(priv);
+}
+
+/**
+ * Select the given tracks in the clarity widget
+ */
+static void _clarity_widget_select_tracks(ClarityWidget *self, GList *tracks) {
+    if (! gtk_widget_get_realized(GTK_WIDGET(self)))
+            return;
+
+    ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(self);
+
+    tracks = _sort_track_list(tracks);
+    ClarityCanvas *ccanvas = CLARITY_CANVAS(priv->draw_area);
+
+    if (clarity_canvas_is_blocked(ccanvas))
+        return;
+
+    gint album_index = album_model_get_index_with_track(priv->album_model, 
tracks->data);
+    gtk_range_set_value(GTK_RANGE (priv->cdslider), album_index);
+}
+
+/**
+ * Select gtkpod's currently selected tracks in the clarity window.
+ *
+ * Shoudl be called from a g_idle thread.
+ */
+static gboolean _clarity_widget_select_tracks_idle(gpointer data) {
+    if (! CLARITY_IS_WIDGET(data))
+        return FALSE;
+
+    ClarityWidget *cw = CLARITY_WIDGET(data);
+    GList *tracks = gtkpod_get_selected_tracks();
+    if (!tracks)
+        return FALSE;
+
+    _clarity_widget_select_tracks(cw, tracks);
+
+    return FALSE;
+}
+
+/**
+ * Necessary callback for following use case:
+ *
+ * 1) Load gtkpod with clarity plugin window docked in the gui but
+ *      obscured by another plugin window.
+ * 2) Select a playlist.
+ * 3) Select the relevant toggle button to bring the clarity window to
+ *      the front and visible.
+ *
+ * Without this callback the window remains blank.
+ */
+static void _clarity_widget_realized_cb(GtkWidget *widget, gpointer data) {
+    if (! CLARITY_IS_WIDGET(widget))
+        return;
+
+    ClarityWidget *cw = CLARITY_WIDGET(widget);
+    Playlist *playlist = gtkpod_get_current_playlist();
+    if (!playlist)
+        return;
+
+    _init_clarity_with_playlist(cw, playlist);
+
+    /*
+     * Needs to be an idle function that will be called
+     * after the idle cover addition functions called by
+     * _init_clarity_with_playlist.
+     */
+    g_idle_add(_clarity_widget_select_tracks_idle, cw);
+}
+
 static void clarity_widget_class_init (ClarityWidgetClass *klass) {
     GObjectClass *gobject_class;
 
@@ -298,6 +424,14 @@ static void clarity_widget_init (ClarityWidget *self) {
             G_CALLBACK (dnd_clarity_drag_motion),
             NULL);
 
+    /*
+     * Ensure everything is inited correctly if gtkpod is loaded with
+     * the clarity window is not initially visible.
+     */
+    g_signal_connect_after(GTK_WIDGET(self), "realize",
+            G_CALLBACK(_clarity_widget_realized_cb),
+            NULL);
+
     _init_slider_range(priv);
 
     priv->controlbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 2);
@@ -319,27 +453,6 @@ GtkWidget *clarity_widget_new() {
     return GTK_WIDGET(cw);
 }
 
-static void clarity_widget_clear(ClarityWidget *self) {
-    ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(self);
-    clarity_canvas_clear(CLARITY_CANVAS(priv->draw_area));
-    album_model_clear(priv->album_model);
-}
-
-static void _init_tracks(ClarityWidget *cw, GList *tracks) {
-    g_return_if_fail(CLARITY_IS_WIDGET(cw));
-
-    if (!tracks)
-        return;
-
-    ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(cw);
-
-    album_model_add_tracks(priv->album_model, tracks);
-
-    clarity_canvas_init_album_model(CLARITY_CANVAS(priv->draw_area), 
priv->album_model);
-
-    _init_slider_range(priv);
-}
-
 GdkRGBA *clarity_widget_get_background_display_color(ClarityWidget *self) {
     g_return_val_if_fail(CLARITY_IS_WIDGET(self), NULL);
 
@@ -392,25 +505,13 @@ void clarity_widget_preference_changed_cb(GtkPodApp *app, 
gpointer pfname, gpoin
 
 void clarity_widget_playlist_selected_cb(GtkPodApp *app, gpointer pl, gpointer 
data) {
     g_return_if_fail(CLARITY_IS_WIDGET(data));
-
     ClarityWidget *cw = CLARITY_WIDGET(data);
 
     Playlist *playlist = (Playlist *) pl;
     if (!playlist)
         return;
 
-    if (cw->current_playlist == playlist)
-        // Should already have all these tracks displayed
-        return;
-
-    clarity_widget_clear(cw);
-
-    cw->current_playlist = playlist;
-    GList *tracks = playlist->members;
-    if (!tracks)
-        return;
-
-    _init_tracks(cw, tracks);
+    _init_clarity_with_playlist(cw, playlist);
 }
 
 void clarity_widget_playlist_removed_cb(GtkPodApp *app, gpointer pl, gpointer 
data) {
@@ -421,47 +522,23 @@ void clarity_widget_playlist_removed_cb(GtkPodApp *app, 
gpointer pl, gpointer da
     if (!playlist)
         return;
 
-    if (cw->current_playlist == playlist)
-        clarity_widget_clear(cw);
-}
-
-GList *_sort_track_list(GList *tracks) {
-    enum GtkPodSortTypes value = prefs_get_int("clarity_sort");
-
-    switch(value) {
-        case SORT_ASCENDING:
-            tracks = g_list_sort(tracks, (GCompareFunc) compare_tracks);
-            break;
-        case SORT_DESCENDING:
-            tracks = g_list_sort(tracks, (GCompareFunc) compare_tracks);
-            tracks = g_list_reverse(tracks);
-            break;
-        default:
-            // Do Nothing
-            break;
-    }
+    if (! gtk_widget_get_realized(GTK_WIDGET(cw)))
+        return;
 
-    return tracks;
+    if (cw->current_playlist == playlist)
+        _clarity_widget_clear(cw);
 }
 
 void clarity_widget_tracks_selected_cb(GtkPodApp *app, gpointer tks, gpointer 
data) {
     g_return_if_fail(CLARITY_IS_WIDGET(data));
 
     ClarityWidget *cw = CLARITY_WIDGET(data);
-    ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(cw);
     GList *tracks = g_list_copy((GList *) tks);
 
     if (!tracks)
         return;
 
-    tracks = _sort_track_list(tracks);
-    ClarityCanvas *ccanvas = CLARITY_CANVAS(priv->draw_area);
-
-    if (clarity_canvas_is_blocked(ccanvas))
-        return;
-
-    gint album_index = album_model_get_index_with_track(priv->album_model, 
tracks->data);
-    gtk_range_set_value(GTK_RANGE (priv->cdslider), album_index);
+    _clarity_widget_select_tracks(cw, tracks);
 }
 
 static void _add_track(ClarityWidgetPrivate *priv, Track *track) {
@@ -484,10 +561,12 @@ void clarity_widget_track_added_cb(GtkPodApp *app, 
gpointer tk, gpointer data) {
     ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(cw);
     Track *track = tk;
 
-
     if (!track)
         return;
 
+    if (! gtk_widget_get_realized(GTK_WIDGET(cw)))
+        return;
+
     GList *current_tracks = cw->current_playlist->members;
     if (!g_list_find(current_tracks, track)) {
         // Track not added to this playlist
@@ -526,10 +605,12 @@ void clarity_widget_track_removed_cb(GtkPodApp *app, 
gpointer tk, gpointer data)
     ClarityWidgetPrivate *priv = CLARITY_WIDGET_GET_PRIVATE(cw);
     Track *track = tk;
 
-
     if (!track)
         return;
 
+    if (! gtk_widget_get_realized(GTK_WIDGET(cw)))
+        return;
+
     AlbumItem *item = album_model_get_item_with_track(priv->album_model, 
track);
 
     _remove_track(priv, item, track);
@@ -545,6 +626,9 @@ void clarity_widget_track_updated_cb(GtkPodApp *app, 
gpointer tk, gpointer data)
     if (!track)
         return;
 
+    if (! gtk_widget_get_realized(GTK_WIDGET(cw)))
+        return;
+
     ClarityCanvas *ccanvas = CLARITY_CANVAS(priv->draw_area);
 
     if (clarity_canvas_is_blocked(ccanvas))

------------------------------------------------------------------------------
RSA(R) Conference 2012
Save $700 by Nov 18
Register now
http://p.sf.net/sfu/rsa-sfdev2dev1
_______________________________________________
gtkpod-cvs2 mailing list
gtkpod-cvs2@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2

Reply via email to