This is an automated email from the git hooks/post-receive script. eric pushed a commit to branch master in repository xfce/xfdesktop.
commit c93238818dec7c1666102ef3e33e40240ccea317 Author: Eric Koegel <eric.koe...@gmail.com> Date: Sun Jan 24 05:28:16 2016 +0300 Use gdk's get static image for animation files This way it will return a reasonable thing to display as a static unanimated image, which might be the first frame, or something more sophisticated. And since it's only a little bit more work, add a hidden property to display animations as a wallpaper, the xfconf property is /backdrop/screen#/MonitorName/Workspace#/backdrop-do-animations such as: /backdrop/screen0/monitoreDP1/workspace1/backdrop-do-animations it's a boolean value and setting it to TRUE turns it on, default is obviously off. Signed-off-by: Eric Koegel <eric.koe...@gmail.com> --- src/xfce-backdrop.c | 186 ++++++++++++++++++++++++++++++++++++++++++++------ src/xfce-backdrop.h | 3 + src/xfce-workspace.c | 14 +++- 3 files changed, 182 insertions(+), 21 deletions(-) diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c index f3c8d58..b4c884c 100644 --- a/src/xfce-backdrop.c +++ b/src/xfce-backdrop.c @@ -70,6 +70,10 @@ static gboolean xfce_backdrop_timer(XfceBackdrop *backdrop); static GdkPixbuf *xfce_backdrop_generate_canvas(XfceBackdrop *backdrop); +static void xfce_backdrop_create_final_image(XfceBackdrop *backdrop); + +static gboolean xfce_backdrop_update_frame(XfceBackdrop *backdrop); + static void xfce_backdrop_loader_size_prepared_cb(GdkPixbufLoader *loader, gint width, gint height, @@ -103,6 +107,10 @@ struct _XfceBackdropPriv gint width, height; gint bpp; + GdkPixbufAnimation *animation; + GdkPixbufAnimationIter *animation_iter; + gint animation_timer; + GdkPixbuf *pix; XfceBackdropImageData *image_data; @@ -122,6 +130,7 @@ struct _XfceBackdropPriv guint cycle_timer_id; XfceBackdropCyclePeriod cycle_period; gboolean random_backdrop_order; + gboolean do_animations; }; struct _XfceBackdropImageData @@ -156,6 +165,7 @@ enum PROP_BACKDROP_CYCLE_PERIOD, PROP_BACKDROP_CYCLE_TIMER, PROP_BACKDROP_RANDOM_ORDER, + PROP_BACKDROP_DO_ANIMATIONS, }; static guint backdrop_signals[LAST_SIGNAL] = { 0, }; @@ -257,6 +267,28 @@ xfce_backdrop_clear_cached_image(XfceBackdrop *backdrop) } static void +xfce_backdrop_clear_animation(XfceBackdrop *backdrop) +{ + TRACE("entering"); + + g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); + + if(G_IS_OBJECT(backdrop->priv->animation)) { + g_object_unref(backdrop->priv->animation); + backdrop->priv->animation = NULL; + } + + if(G_IS_OBJECT(backdrop->priv->animation_iter)) { + backdrop->priv->animation_iter = NULL; + } + + if(backdrop->priv->animation_timer != 0) { + g_source_remove(backdrop->priv->animation_timer); + backdrop->priv->animation_timer = 0; + } +} + +static void xfdesktop_backdrop_clear_directory_monitor(XfceBackdrop *backdrop) { g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); @@ -381,6 +413,7 @@ cb_xfce_backdrop_image_files_changed(GFileMonitor *monitor, DBG("match"); /* clear the outdated backdrop */ xfce_backdrop_clear_cached_image(backdrop); + xfce_backdrop_clear_animation(backdrop); /* backdrop changed! */ g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CHANGED], 0); @@ -764,6 +797,13 @@ xfce_backdrop_class_init(XfceBackdropClass *klass) FALSE, XFDESKTOP_PARAM_FLAGS)); + g_object_class_install_property(gobject_class, PROP_BACKDROP_DO_ANIMATIONS, + g_param_spec_boolean("backdrop-do-animations", + "backdrop-do-animations", + "backdrop-do-animations", + FALSE, + XFDESKTOP_PARAM_FLAGS)); + #undef XFDESKTOP_PARAM_FLAGS } @@ -799,6 +839,7 @@ xfce_backdrop_finalize(GObject *object) } xfce_backdrop_clear_cached_image(backdrop); + xfce_backdrop_clear_animation(backdrop); xfdesktop_backdrop_clear_directory_monitor(backdrop); @@ -862,6 +903,10 @@ xfce_backdrop_set_property(GObject *object, xfce_backdrop_set_random_order(backdrop, g_value_get_boolean(value)); break; + case PROP_BACKDROP_DO_ANIMATIONS: + xfce_backdrop_set_do_animations(backdrop, g_value_get_boolean(value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -914,6 +959,10 @@ xfce_backdrop_get_property(GObject *object, g_value_set_boolean(value, xfce_backdrop_get_random_order(backdrop)); break; + case PROP_BACKDROP_DO_ANIMATIONS: + g_value_set_boolean(value, xfce_backdrop_get_do_animations(backdrop)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -1185,6 +1234,7 @@ xfce_backdrop_set_image_filename(XfceBackdrop *backdrop, const gchar *filename) backdrop->priv->image_path = NULL; xfce_backdrop_clear_cached_image(backdrop); + xfce_backdrop_clear_animation(backdrop); xfce_backdrop_load_image_files(backdrop); @@ -1523,6 +1573,37 @@ xfce_backdrop_get_random_order(XfceBackdrop *backdrop) return backdrop->priv->random_backdrop_order; } +/** + * xfce_backdrop_set_do_animations: + * @backdrop: An #XfceBackdrop. + * @animate: When TRUE and the backdrops will animate. + * + **/ +void +xfce_backdrop_set_do_animations(XfceBackdrop *backdrop, + gboolean do_animations) +{ + g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); + + TRACE("entering"); + + if(backdrop->priv->do_animations != do_animations) { + backdrop->priv->do_animations = do_animations; + + if(backdrop->priv->animation) { + xfce_backdrop_update_frame(backdrop); + } + } +} + +gboolean +xfce_backdrop_get_do_animations(XfceBackdrop *backdrop) +{ + g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), FALSE); + + return backdrop->priv->do_animations; +} + void xfce_backdrop_force_cycle(XfceBackdrop *backdrop) { @@ -1604,6 +1685,10 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) { TRACE("entering"); + if(backdrop->priv->animation) { + xfce_backdrop_create_final_image(backdrop); + } + if(backdrop->priv->pix) { /* return a reference so we can cache it */ return g_object_ref(backdrop->priv->pix); @@ -1739,11 +1824,27 @@ xfce_backdrop_loader_size_prepared_cb(GdkPixbufLoader *loader, } } +static gboolean +xfce_backdrop_update_frame(XfceBackdrop *backdrop) +{ + g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), G_SOURCE_REMOVE); + + /* kill the old timer, we won't bother with frame updates until + * a frame is loaded to cut down on CPU usage */ + if(backdrop->priv->animation_timer != 0) { + g_source_remove(backdrop->priv->animation_timer); + backdrop->priv->animation_timer = 0; + } + + /* backdrop changed! */ + g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CHANGED], 0); + + return G_SOURCE_REMOVE; +} + static void -xfce_backdrop_loader_closed_cb(GdkPixbufLoader *loader, - XfceBackdropImageData *image_data) +xfce_backdrop_create_final_image(XfceBackdrop *backdrop) { - XfceBackdrop *backdrop = image_data->backdrop; GdkPixbuf *final_image, *image, *tmp; gint i, j; gint w, h, iw = 0, ih = 0; @@ -1755,15 +1856,21 @@ xfce_backdrop_loader_closed_cb(GdkPixbufLoader *loader, TRACE("entering"); g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); + g_return_if_fail(backdrop->priv->animation); + g_return_if_fail(backdrop->priv->animation_iter); - /* canceled? quit now */ - if(g_cancellable_is_cancelled(image_data->cancellable)) { - xfce_backdrop_image_data_release(image_data); - g_free(image_data); - return; + xfce_backdrop_clear_cached_image(backdrop); + + if(gdk_pixbuf_animation_is_static_image (backdrop->priv->animation) || !backdrop->priv->do_animations) { + /* Get a reasonable thing to display as a static unanimated image */ + DBG("static image"); + image = gdk_pixbuf_animation_get_static_image(backdrop->priv->animation); + } else { + DBG("animation"); + gdk_pixbuf_animation_iter_advance(backdrop->priv->animation_iter, NULL); + image = gdk_pixbuf_animation_iter_get_pixbuf(backdrop->priv->animation_iter); } - image = gdk_pixbuf_loader_get_pixbuf(loader); if(image) { /* If the image is supposed to be rotated, do that now */ GdkPixbuf *temp = gdk_pixbuf_apply_embedded_orientation (image); @@ -1807,16 +1914,12 @@ xfce_backdrop_loader_closed_cb(GdkPixbufLoader *loader, final_image = xfce_backdrop_generate_canvas(backdrop); - /* no image and not canceled? return just the canvas */ - if(!image && !g_cancellable_is_cancelled(image_data->cancellable)) { + /* no image? return just the canvas */ + if(!image) { XF_DEBUG("image failed to load, displaying canvas only"); backdrop->priv->pix = final_image; g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_READY], 0); - - backdrop->priv->image_data = NULL; - xfce_backdrop_image_data_release(image_data); - g_free(image_data); return; } @@ -1906,17 +2009,60 @@ xfce_backdrop_loader_closed_cb(GdkPixbufLoader *loader, g_critical("Invalid image style: %d\n", (gint)istyle); } - /* keep the backdrop and emit the signal if it hasn't been canceled */ - if(!g_cancellable_is_cancelled(image_data->cancellable)) { - backdrop->priv->pix = final_image; - g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_READY], 0); - } + /* keep the backdrop and emit the signal */ + backdrop->priv->pix = final_image; + g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_READY], 0); + /* We either created image or took a ref with * gdk_pixbuf_apply_embedded_orientation, free it here */ if(image) g_object_unref(image); + + /* do we need to set a new timer for the next frame? */ + if(gdk_pixbuf_animation_is_static_image (backdrop->priv->animation) == FALSE && backdrop->priv->do_animations) { + gint timeout; + + timeout = gdk_pixbuf_animation_iter_get_delay_time(backdrop->priv->animation_iter); + DBG("animation timeout %d", timeout); + + if(timeout > 0) { + backdrop->priv->animation_timer = g_timeout_add(timeout, + (GSourceFunc)xfce_backdrop_update_frame, + backdrop); + } + } else { + /* static image, no need to continue */ + return; + } + + return; +} + +static void +xfce_backdrop_loader_closed_cb(GdkPixbufLoader *loader, + XfceBackdropImageData *image_data) +{ + XfceBackdrop *backdrop = image_data->backdrop; + + TRACE("entering"); + + g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); + + /* canceled? quit now */ + if(g_cancellable_is_cancelled(image_data->cancellable)) { + xfce_backdrop_image_data_release(image_data); + g_free(image_data); + return; + } + + backdrop->priv->animation = gdk_pixbuf_loader_get_animation(loader); + backdrop->priv->animation_iter = gdk_pixbuf_animation_get_iter(backdrop->priv->animation, NULL); + + /* manually load the first frame */ + xfce_backdrop_update_frame (backdrop); + backdrop->priv->image_data = NULL; xfce_backdrop_image_data_release(image_data); g_free(image_data); diff --git a/src/xfce-backdrop.h b/src/xfce-backdrop.h index ce72e97..4879a34 100644 --- a/src/xfce-backdrop.h +++ b/src/xfce-backdrop.h @@ -145,6 +145,9 @@ gboolean xfce_backdrop_get_random_order (XfceBackdrop *backdrop); void xfce_backdrop_force_cycle (XfceBackdrop *backdrop); +void xfce_backdrop_set_do_animations (XfceBackdrop *backdrop, + gboolean do_animations); +gboolean xfce_backdrop_get_do_animations (XfceBackdrop *backdrop); GdkPixbuf *xfce_backdrop_get_pixbuf (XfceBackdrop *backdrop); diff --git a/src/xfce-workspace.c b/src/xfce-workspace.c index 13e1187..6a0a00c 100644 --- a/src/xfce-workspace.c +++ b/src/xfce-workspace.c @@ -277,6 +277,13 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data) g_signal_emit(G_OBJECT(user_data), signals[WORKSPACE_BACKDROP_CHANGED], 0, backdrop); } +static void +backdrop_ready_cb(XfceBackdrop *backdrop, gpointer user_data) +{ + TRACE("entering"); + /* do nothing */ +} + /** * xfce_workspace_monitors_changed: * @workspace: An #XfceWorkspace. @@ -339,7 +346,7 @@ xfce_workspace_monitors_changed(XfceWorkspace *workspace, workspace); g_signal_connect(G_OBJECT(workspace->priv->backdrops[i]), "ready", - G_CALLBACK(backdrop_changed_cb), workspace); + G_CALLBACK(backdrop_ready_cb), workspace); } } @@ -668,6 +675,11 @@ xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace, G_OBJECT(backdrop), "backdrop-cycle-random-order"); buf[pp_len] = 0; + g_strlcat(buf, "backdrop-do-animations", sizeof(buf)); + xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, + G_OBJECT(backdrop), "backdrop-do-animations"); + + buf[pp_len] = 0; g_strlcat(buf, "last-image", sizeof(buf)); if(!xfconf_channel_has_property(channel, buf)) { xfce_workspace_migrate_backdrop_image(workspace, backdrop, monitor); -- To stop receiving notification emails like this one, please contact the administrator of this repository. _______________________________________________ Xfce4-commits mailing list Xfce4-commits@xfce.org https://mail.xfce.org/mailman/listinfo/xfce4-commits