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