From c4d8152e28ec955ea1d62f524a74654be20ea8b1 Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Thu, 29 Dec 2011 22:34:15 +0300 Subject: [PATCH] Backdrop image cycling based on timer. This code adds the ability to change the backdrop image when it's set to an image-list based on a backdrop-cycle-timer setting. Bug 4850. --- src/xfce-backdrop.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/xfce-backdrop.h | 5 +++ src/xfce-desktop.c | 50 +++++++++++++++++++++++++++++++++- 3 files changed, 128 insertions(+), 1 deletions(-) diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c index 486a796..3d0015a 100644 --- a/src/xfce-backdrop.c +++ b/src/xfce-backdrop.c @@ -52,6 +52,7 @@ static void xfce_backdrop_get_property(GObject *object, guint property_id, GValue *value, GParamSpec *pspec); +gboolean xfce_backdrop_timer(XfceBackdrop *backdrop); struct _XfceBackdropPriv { @@ -68,11 +69,13 @@ struct _XfceBackdropPriv gint brightness; gdouble saturation; + gint cycle_timer; }; enum { BACKDROP_CHANGED, + BACKDROP_CYCLE, LAST_SIGNAL, }; @@ -87,6 +90,7 @@ enum PROP_IMAGE_FILENAME, PROP_BRIGHTNESS, PROP_SATURATION, + PROP_BACKDROP_CYCLE_TIMER }; static guint backdrop_signals[LAST_SIGNAL] = { 0, }; @@ -240,6 +244,10 @@ xfce_backdrop_class_init(XfceBackdropClass *klass) G_OBJECT_CLASS_TYPE(gobject_class), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(XfceBackdropClass, changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + backdrop_signals[BACKDROP_CYCLE] = g_signal_new("cycle", + G_OBJECT_CLASS_TYPE(gobject_class), G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET(XfceBackdropClass, cycle), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); #define XFDESKTOP_PARAM_FLAGS (G_PARAM_READWRITE \ | G_PARAM_CONSTRUCT \ @@ -305,6 +313,13 @@ xfce_backdrop_class_init(XfceBackdropClass *klass) -10.0, 10.0, 1.0, XFDESKTOP_PARAM_FLAGS)); + g_object_class_install_property(gobject_class, PROP_BACKDROP_CYCLE_TIMER, + g_param_spec_int("backdrop-cycle-timer", + "backdrop-cycle-timer", + "backdrop-cycle-timer", + 0, 65535, 10, + XFDESKTOP_PARAM_FLAGS)); + #undef XFDESKTOP_PARAM_FLAGS } @@ -384,6 +399,10 @@ xfce_backdrop_set_property(GObject *object, xfce_backdrop_set_saturation(backdrop, g_value_get_double(value)); break; + case PROP_BACKDROP_CYCLE_TIMER: + xfce_backdrop_set_cycle_timer(backdrop, g_value_get_int(value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -432,6 +451,10 @@ xfce_backdrop_get_property(GObject *object, g_value_set_double(value, xfce_backdrop_get_saturation(backdrop)); break; + case PROP_BACKDROP_CYCLE_TIMER: + g_value_set_int(value, xfce_backdrop_get_cycle_timer(backdrop)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -745,6 +768,57 @@ xfce_backdrop_get_saturation(XfceBackdrop *backdrop) return backdrop->priv->saturation; } +gboolean +xfce_backdrop_timer(XfceBackdrop *backdrop) +{ + static GTimer *timer = NULL; + + g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), FALSE); + + /* g_timeout_add_seconds is really inaccurate and will be several + * seconds early in some cases. Since we work in a time scale of + * minutes this really doesn't impact us. So the + * g_timer_elapsed(timer, NULL) + 5 code safely covers it. + */ + if(timer == NULL) { + timer = g_timer_new(); + } else if(g_timer_elapsed(timer, NULL) + 5 >= backdrop->priv->cycle_timer + && backdrop->priv->cycle_timer != 0) { + g_timer_start(timer); + } else { + return FALSE; + } + + g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CYCLE], 0); + return TRUE; +} + +/** + * xfce_backdrop_set_cycle_timer: + * @backdrop: An #XfceBackdrop. + * @cycle_timer: The amount of time, in minutes, to wait before changing the background image. + * + * Changes the backdrop image based on the cycle_timer a value between 0 and 65535. + * A value of 0 indicates that the backdrop should not be changed. + **/ +void +xfce_backdrop_set_cycle_timer(XfceBackdrop *backdrop, gint cycle_timer) +{ + g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); + + if(cycle_timer != backdrop->priv->cycle_timer) { + backdrop->priv->cycle_timer = cycle_timer; + g_timeout_add_seconds(backdrop->priv->cycle_timer * 60, (GSourceFunc)xfce_backdrop_timer, backdrop); + } +} + +gint +xfce_backdrop_get_cycle_timer(XfceBackdrop *backdrop) +{ + g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), 0); + return backdrop->priv->cycle_timer; +} + /** * xfce_backdrop_get_pixbuf: * @backdrop: An #XfceBackdrop. diff --git a/src/xfce-backdrop.h b/src/xfce-backdrop.h index d193644..57a62fe 100644 --- a/src/xfce-backdrop.h +++ b/src/xfce-backdrop.h @@ -70,6 +70,7 @@ struct _XfceBackdropClass /*< signals >*/ void (*changed)(XfceBackdrop *backdrop); + void (*cycle)(XfceBackdrop *backdrop); }; GType xfce_backdrop_get_type (void) G_GNUC_CONST; @@ -121,6 +122,10 @@ void xfce_backdrop_set_saturation (XfceBackdrop *backdrop, gdouble saturation); gdouble xfce_backdrop_get_saturation (XfceBackdrop *backdrop); +void xfce_backdrop_set_cycle_timer (XfceBackdrop *backdrop, + gint cycle_timer); +gint xfce_backdrop_get_cycle_timer (XfceBackdrop *backdrop); + GdkPixbuf *xfce_backdrop_get_pixbuf (XfceBackdrop *backdrop); G_END_DECLS diff --git a/src/xfce-desktop.c b/src/xfce-desktop.c index cd98ae7..e6f29d4 100644 --- a/src/xfce-desktop.c +++ b/src/xfce-desktop.c @@ -94,6 +94,7 @@ struct _XfceDesktopPriv guint nbackdrops; XfceBackdrop **backdrops; + gchar *backdrop_list; gboolean xinerama_stretch; @@ -363,6 +364,26 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data) } static void +backdrop_cycle_cb(XfceBackdrop *backdrop, gpointer user_data) +{ + XfceDesktop *desktop = XFCE_DESKTOP(user_data); + + g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); + + if(xfdesktop_backdrop_list_is_valid(desktop->priv->backdrop_list)) { + gchar *backdrop_file; + GError *error = NULL; + + backdrop_file = xfdesktop_backdrop_list_choose_random(desktop->priv->backdrop_list, + &error); + + xfce_backdrop_set_image_filename(backdrop, backdrop_file); + g_free(backdrop_file); + backdrop_changed_cb(backdrop, user_data); + } +} + +static void screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data) { XfceDesktop *desktop = user_data; @@ -434,6 +455,9 @@ xfce_desktop_monitors_changed(GdkScreen *gscreen, g_signal_connect(G_OBJECT(desktop->priv->backdrops[0]), "changed", G_CALLBACK(backdrop_changed_cb), desktop); + g_signal_connect(G_OBJECT(desktop->priv->backdrops[0]), + "cycle", + G_CALLBACK(backdrop_cycle_cb), desktop); } desktop->priv->nbackdrops = 1; } @@ -459,6 +483,10 @@ xfce_desktop_monitors_changed(GdkScreen *gscreen, "changed", G_CALLBACK(backdrop_changed_cb), desktop); + g_signal_connect(G_OBJECT(desktop->priv->backdrops[i]), + "cycle", + G_CALLBACK(backdrop_cycle_cb), + desktop); } } desktop->priv->nbackdrops = n_monitors; @@ -627,6 +655,11 @@ xfce_desktop_finalize(GObject *object) g_object_unref(G_OBJECT(desktop->priv->channel)); g_free(desktop->priv->property_prefix); + if(desktop->priv->backdrop_list) { + g_free(desktop->priv->backdrop_list); + desktop->priv->backdrop_list = NULL; + } + G_OBJECT_CLASS(xfce_desktop_parent_class)->finalize(object); } @@ -1033,8 +1066,18 @@ xfce_desktop_image_filename_changed(XfconfChannel *channel, xfce_backdrop_set_image_filename(backdrop, backdrop_file); g_free(backdrop_file); - } else + if(desktop->priv->backdrop_list) { + g_free(desktop->priv->backdrop_list); + } + desktop->priv->backdrop_list = g_strdup(filename); + } else { xfce_backdrop_set_image_filename(backdrop, filename); + + if(desktop->priv->backdrop_list) { + g_free(desktop->priv->backdrop_list); + desktop->priv->backdrop_list = NULL; + } + } } } @@ -1086,6 +1129,11 @@ xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop, xfconf_g_property_bind(channel, buf, G_TYPE_DOUBLE, G_OBJECT(backdrop), "saturation"); + buf[pp_len] = 0; + g_strlcat(buf, "backdrop-cycle-timer", sizeof(buf)); + xfconf_g_property_bind(channel, buf, G_TYPE_INT, + G_OBJECT(backdrop), "backdrop-cycle-timer"); + /* the image filename could be an image or a backdrop list, so we * can't just bind the property directly */ buf[pp_len] = 0; -- 1.7.5.4