[Xfce4-commits] <xfdesktop:eric/settings-changes> Additonal backdrop cycle options

Eric Koegel noreply at xfce.org
Sat Oct 19 20:26:03 CEST 2013


Updating branch refs/heads/eric/settings-changes
         to 8ee9256cf6459ee827d8a98e09fa51e0ca7e2a30 (commit)
       from c460b0acb86791eb7ee9d954fae505589b88a68a (commit)

commit 8ee9256cf6459ee827d8a98e09fa51e0ca7e2a30
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Sat Oct 19 21:20:43 2013 +0300

    Additonal backdrop cycle options
    
    Xfdesktop can now change the backdrop every x seconds, minutes,
    or hours. It can also change every hour on the hour, or every day,
    or just during start up.

 common/xfdesktop-common.c                          |   31 ++--
 settings/main.c                                    |   70 ++++++-
 .../xfdesktop-settings-appearance-frame-ui.glade   |   31 +++-
 src/xfce-backdrop.c                                |  192 ++++++++++++++++++--
 src/xfce-backdrop.h                                |   16 ++
 src/xfce-workspace.c                               |   46 ++++-
 6 files changed, 340 insertions(+), 46 deletions(-)

diff --git a/common/xfdesktop-common.c b/common/xfdesktop-common.c
index 6d5546d..bf86ba4 100644
--- a/common/xfdesktop-common.c
+++ b/common/xfdesktop-common.c
@@ -84,7 +84,8 @@ list_files_in_dir(const gchar *path)
     return files;
 }
 
-
+/* Gets the next valid image file in the folder. Free when done using it
+ * returns NULL on fail. */
 gchar *
 xfdesktop_backdrop_choose_next(const gchar *filename)
 {
@@ -93,6 +94,8 @@ xfdesktop_backdrop_choose_next(const gchar *filename)
 
     g_return_val_if_fail(filename, NULL);
 
+    /* We don't cache the list at all. This way the user can add/remove items
+     * whenever they like without xfdesktop having to do anything */
     files = list_files_in_dir(g_path_get_dirname(filename));
     if(!files)
         return NULL;
@@ -127,10 +130,11 @@ xfdesktop_backdrop_choose_next(const gchar *filename)
     return file;
 }
 
+/* Gets a random valid image file in the folder. Free when done using it.
+ * returns NULL on fail. */
 gchar *
 xfdesktop_backdrop_choose_random(const gchar *filename)
 {
-    static gboolean __initialized = FALSE;
     static gint previndex = -1;
     GList *files;
     gchar *file = NULL;
@@ -138,30 +142,21 @@ xfdesktop_backdrop_choose_random(const gchar *filename)
 
     g_return_val_if_fail(filename, NULL);
 
+    /* We don't cache the list at all. This way the user can add/remove items
+     * whenever they like without xfdesktop having to do anything */
     files = list_files_in_dir(g_path_get_dirname(filename));
     if(!files)
         return NULL;
 
     n_items = g_list_length(files);
 
+    /* If there's only 1 item, just return it, easy */
     if(1 == n_items) {
         file = g_strdup(g_list_first(files)->data);
         g_list_free_full(files, g_free);
         return file;
     }
 
-    /* NOTE: 4.3BSD random()/srandom() are a) stronger and b) faster than
-    * ANSI-C rand()/srand(). So we use random() if available */
-    if(G_UNLIKELY(!__initialized))    {
-        guint seed = time(NULL) ^ (getpid() + (getpid() << 15));
-#ifdef HAVE_SRANDOM
-        srandom(seed);
-#else
-        srand(seed);
-#endif
-        __initialized = TRUE;
-    }
-
     do {
         if(tries++ == n_items) {
             /* this isn't precise, but if we've failed to get a good
@@ -172,17 +167,15 @@ xfdesktop_backdrop_choose_random(const gchar *filename)
         }
 
         do {
-#ifdef HAVE_SRANDOM
-            cur_file = random() % n_items;
-#else
-            cur_file = rand() % n_items;
-#endif
+            /* g_random_int_range bounds to n_items-1 */
+            cur_file = g_random_int_range(0, n_items);
         } while(cur_file == previndex && G_LIKELY(previndex != -1));
 
     } while(!xfdesktop_image_file_is_valid(g_list_nth(files, cur_file)->data));
 
     previndex = cur_file;
 
+    /* Keep a copy of our new random item, free everything else */
     file = g_strdup(g_list_nth(files, cur_file)->data);
     g_list_free_full(files, g_free);
 
diff --git a/settings/main.c b/settings/main.c
index 84340f0..cbc7e2d 100644
--- a/settings/main.c
+++ b/settings/main.c
@@ -109,8 +109,10 @@ typedef struct
     gulong color1_btn_id;
     gulong color2_btn_id;
 
-    GtkWidget *backdrop_cycle_spinbox;
+    /* backdrop cycling options */
     GtkWidget *backdrop_cycle_chkbox;
+    GtkWidget *combo_backdrop_cycle_period;
+    GtkWidget *backdrop_cycle_spinbox;
     GtkWidget *random_backdrop_order_chkbox;
 
     GThread *preview_thread;
@@ -877,11 +879,42 @@ cb_xfdesktop_chk_custom_font_size_toggled(GtkCheckButton *button,
 }
 
 static void
+update_backdrop_cycle_spinbox(AppearancePanel *panel)
+{
+    gboolean sensitive = FALSE;
+    gint period;
+
+    /* For the spinbox to be active the combo_backdrop_cycle_period needs to be
+     * active and needs to be set to something where the spinbox would apply */
+    if(gtk_widget_get_sensitive(panel->combo_backdrop_cycle_period)) {
+        period = gtk_combo_box_get_active(GTK_COMBO_BOX(panel->combo_backdrop_cycle_period));
+        if(period == XFCE_BACKDROP_PERIOD_SECONDS ||
+           period == XFCE_BACKDROP_PERIOD_MINUES  ||
+           period == XFCE_BACKDROP_PERIOD_HOURS)
+        {
+            sensitive = TRUE;
+        }
+    }
+
+    gtk_widget_set_sensitive(panel->backdrop_cycle_spinbox, sensitive);
+}
+
+static void
+cb_combo_backdrop_cycle_period_change(GtkComboBox *combo,
+                                      gpointer user_data)
+{
+    AppearancePanel *panel = user_data;
+
+    /* determine if the spin box should be sensitive */
+    update_backdrop_cycle_spinbox(panel);
+}
+
+static void
 cb_xfdesktop_chk_cycle_backdrop_toggled(GtkCheckButton *button,
                                         gpointer user_data)
 {
-    gboolean sensitive = FALSE;
     AppearancePanel *panel = user_data;
+    gboolean sensitive = FALSE;
 
     TRACE("entering");
 
@@ -889,8 +922,11 @@ cb_xfdesktop_chk_cycle_backdrop_toggled(GtkCheckButton *button,
            sensitive = TRUE;
     }
 
-    gtk_widget_set_sensitive(panel->backdrop_cycle_spinbox, sensitive);
+    /* The cycle backdrop toggles the period and random widgets */
+    gtk_widget_set_sensitive(panel->combo_backdrop_cycle_period, sensitive);
     gtk_widget_set_sensitive(panel->random_backdrop_order_chkbox, sensitive);
+    /* determine if the spin box should be sensitive */
+    update_backdrop_cycle_spinbox(panel);
 }
 
 static gboolean
@@ -1239,6 +1275,19 @@ xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     }
     g_free(buf);
 
+    /* backdrop cycle period combo box */
+    buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, "backdrop-cycle-period");
+    if(remove_binding) {
+        xfconf_g_property_unbind_by_property(channel, buf,
+                               G_OBJECT(panel->combo_backdrop_cycle_period), "active");
+    } else {
+        xfconf_g_property_bind(channel, buf, G_TYPE_INT,
+                               G_OBJECT(panel->combo_backdrop_cycle_period), "active");
+        /* determine if the cycle timer spin box is sensitive */
+        cb_combo_backdrop_cycle_period_change(GTK_COMBO_BOX(panel->combo_backdrop_cycle_period), panel);
+    }
+    g_free(buf);
+
     /* cycle timer spin box */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, "backdrop-cycle-timer");
     if(remove_binding) {
@@ -1246,6 +1295,10 @@ xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
                    G_OBJECT(gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(panel->backdrop_cycle_spinbox))),
                    "value");
     } else {
+        guint current_timer = xfconf_channel_get_uint(channel, buf, 10);
+        /* Update the spin box before we bind to it */
+        gtk_spin_button_set_value(GTK_SPIN_BUTTON(panel->backdrop_cycle_spinbox), current_timer);
+
         xfconf_g_property_bind(channel, buf, G_TYPE_UINT,
                        G_OBJECT(gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(panel->backdrop_cycle_spinbox))),
                        "value");
@@ -1667,15 +1720,24 @@ xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml,
     /* background cycle timer */
     panel->backdrop_cycle_chkbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
                                                                      "chk_cycle_backdrop"));
+    panel->combo_backdrop_cycle_period = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
+                                                                           "combo_cycle_backdrop_period"));
     panel->backdrop_cycle_spinbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
-                                                                     "spin_backdrop_time_minutes"));
+                                                                     "spin_backdrop_time"));
     panel->random_backdrop_order_chkbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
                                                                      "chk_random_backdrop_order"));
 
+    /* Pick the first entry so something shows up */
+    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->combo_backdrop_cycle_period), XFCE_BACKDROP_PERIOD_MINUES);
+
     g_signal_connect(G_OBJECT(panel->backdrop_cycle_chkbox), "toggled",
                     G_CALLBACK(cb_xfdesktop_chk_cycle_backdrop_toggled),
                     panel);
 
+    g_signal_connect(G_OBJECT(panel->combo_backdrop_cycle_period), "changed",
+                     G_CALLBACK(cb_combo_backdrop_cycle_period_change),
+                     panel);
+
     g_object_unref(G_OBJECT(appearance_gxml));
 
 
diff --git a/settings/xfdesktop-settings-appearance-frame-ui.glade b/settings/xfdesktop-settings-appearance-frame-ui.glade
index 32e10c0..a878fad 100644
--- a/settings/xfdesktop-settings-appearance-frame-ui.glade
+++ b/settings/xfdesktop-settings-appearance-frame-ui.glade
@@ -143,7 +143,6 @@
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                         <property name="tooltip-text" translatable="yes">Specify how the image will be resized to fit the screen</property>
-                        <signal handler="image_style_changed" name="changed"/>
                         <items>
                           <item translatable="yes">None</item>
                           <item translatable="yes">Centered</item>
@@ -184,7 +183,6 @@
                         <property name="visible">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                         <property name="tooltip-text" translatable="yes">Specify the style of the color drawn behind the backdrop image</property>
-                        <signal handler="color_style_changed" name="changed"/>
                         <property name="model">model2</property>
                         <child>
                           <object class="GtkCellRendererText" id="renderer2"/>
@@ -211,7 +209,6 @@
                         <property name="tooltip-text" translatable="yes">Specifies the solid color, or the "left" or "top" color of the gradient</property>
                         <property name="title" translatable="yes">Select First Color</property>
                         <property name="color">#151522223333</property>
-                        <signal handler="color1_changed" name="color_set"/>
                       </object>
                       <packing>
                         <property name="left-attach">2</property>
@@ -231,7 +228,6 @@
                         <property name="tooltip-text" translatable="yes">Specifies the "right" or "bottom" color of the gradient</property>
                         <property name="title" translatable="yes">Select Second Color</property>
                         <property name="color">#151522223333</property>
-                        <signal handler="color2_changed" name="color_set"/>
                       </object>
                       <packing>
                         <property name="left-attach">3</property>
@@ -278,8 +274,8 @@
                         <property name="sensitive">True</property>
                         <property name="can_focus">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
-                        <property name="label" translatable="yes">_Change the background (in minutes):</property>
-                        <property name="tooltip-text" translatable="yes">Automatically select a different background from the current directory after a set number of minutes.</property>
+                        <property name="label" translatable="yes">_Change the background </property>
+                        <property name="tooltip-text" translatable="yes">Automatically select a different background from the current directory.</property>
                         <property name="use_underline">True</property>
                         <property name="draw_indicator">True</property>
                       </object>
@@ -288,13 +284,32 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkSpinButton" id="spin_backdrop_time_minutes">
+                      <object class="GtkComboBoxText" id="combo_cycle_backdrop_period">
+                        <property name="visible">True</property>
+                        <property name="sensitive">False</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="tooltip-text" translatable="yes">Specify how often the background will change</property>
+                        <items>
+                          <item translatable="yes">in seconds:</item>
+                          <item translatable="yes">in minutes:</item>
+                          <item translatable="yes">in hours:</item>
+                          <item translatable="yes">at start up</item>
+                          <item translatable="yes">every hour</item>
+                          <item translatable="yes">every day</item>
+                        </items>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="spin_backdrop_time">
                         <property name="visible">True</property>
                         <property name="sensitive">False</property>
                         <property name="can_focus">True</property>
                         <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                         <property name="adjustment">adjustment3</property>
-                        <property name="tooltip-text" translatable="yes">Number of minutes before a different background is selected.</property>
+                        <property name="tooltip-text" translatable="yes">Amount of time before a different background is selected.</property>
                       </object>
                       <packing>
                         <property name="expand">False</property>
diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c
index 6344288..fb07043 100644
--- a/src/xfce-backdrop.c
+++ b/src/xfce-backdrop.c
@@ -45,7 +45,7 @@
 #define abs(x)  ( (x) < 0 ? -(x) : (x) )
 #endif
 
-#define XFCE_BACKDROP_BUFFER_SIZE 4096
+#define XFCE_BACKDROP_BUFFER_SIZE 32768
 
 typedef struct _XfceBackdropImageData XfceBackdropImageData;
 
@@ -98,6 +98,7 @@ struct _XfceBackdropPriv
     gboolean cycle_backdrop;
     guint cycle_timer;
     guint cycle_timer_id;
+    XfceBackdropCyclePeriod cycle_period;
     gboolean random_backdrop_order;
 };
 
@@ -130,6 +131,7 @@ enum
     PROP_IMAGE_FILENAME,
     PROP_BRIGHTNESS,
     PROP_BACKDROP_CYCLE_ENABLE,
+    PROP_BACKDROP_CYCLE_PERIOD,
     PROP_BACKDROP_CYCLE_TIMER,
     PROP_BACKDROP_RANDOM_ORDER
 };
@@ -317,12 +319,20 @@ xfce_backdrop_class_init(XfceBackdropClass *klass)
                                                          FALSE,
                                                          XFDESKTOP_PARAM_FLAGS));
 
+    g_object_class_install_property(gobject_class, PROP_BACKDROP_CYCLE_PERIOD,
+                                    g_param_spec_enum("backdrop-cycle-period",
+                                                      "backdrop-cycle-period",
+                                                      "backdrop-cycle-period",
+                                                      XFCE_TYPE_BACKDROP_CYCLE_PERIOD,
+                                                      XFCE_BACKDROP_PERIOD_MINUES,
+                                                      XFDESKTOP_PARAM_FLAGS));
+
     g_object_class_install_property(gobject_class, PROP_BACKDROP_CYCLE_TIMER,
                                     g_param_spec_uint("backdrop-cycle-timer",
-                                                     "backdrop-cycle-timer",
-                                                     "backdrop-cycle-timer",
-                                                     0, G_MAXUSHORT, 10,
-                                                     XFDESKTOP_PARAM_FLAGS));
+                                                      "backdrop-cycle-timer",
+                                                      "backdrop-cycle-timer",
+                                                      0, G_MAXUSHORT, 10,
+                                                      XFDESKTOP_PARAM_FLAGS));
 
     g_object_class_install_property(gobject_class, PROP_BACKDROP_RANDOM_ORDER,
                                     g_param_spec_boolean("backdrop-cycle-random-order",
@@ -409,6 +419,10 @@ xfce_backdrop_set_property(GObject *object,
             xfce_backdrop_set_cycle_backdrop(backdrop, g_value_get_boolean(value));
             break;
 
+        case PROP_BACKDROP_CYCLE_PERIOD:
+            xfce_backdrop_set_cycle_period(backdrop, g_value_get_enum(value));
+            break;
+
         case PROP_BACKDROP_CYCLE_TIMER:
             xfce_backdrop_set_cycle_timer(backdrop, g_value_get_uint(value));
             break;
@@ -457,6 +471,10 @@ xfce_backdrop_get_property(GObject *object,
             g_value_set_boolean(value, xfce_backdrop_get_cycle_backdrop(backdrop));
             break;
 
+        case PROP_BACKDROP_CYCLE_PERIOD:
+            g_value_set_enum(value, xfce_backdrop_get_cycle_period(backdrop));
+            break;
+
         case PROP_BACKDROP_CYCLE_TIMER:
             g_value_set_uint(value, xfce_backdrop_get_cycle_timer(backdrop));
             break;
@@ -664,7 +682,7 @@ xfce_backdrop_get_second_color(XfceBackdrop *backdrop,
  **/
 void
 xfce_backdrop_set_image_style(XfceBackdrop *backdrop,
-        XfceBackdropImageStyle style)
+                              XfceBackdropImageStyle style)
 {
     g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
     
@@ -721,6 +739,11 @@ xfce_backdrop_get_image_filename(XfceBackdrop *backdrop)
 static gboolean
 xfce_backdrop_timer(XfceBackdrop *backdrop)
 {
+    GDateTime *local_time = NULL;
+    gint hour, minute, second;
+    guint cycle_interval = 0;
+    gboolean continue_cycling = TRUE;
+
     TRACE("entering");
 
     g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), FALSE);
@@ -729,42 +752,149 @@ xfce_backdrop_timer(XfceBackdrop *backdrop)
     if(backdrop->priv->image_style != XFCE_BACKDROP_IMAGE_NONE)
         g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CYCLE], 0);
 
-    return TRUE;
+    /* Now to complicate things; we have to handle some special cases */
+    switch(backdrop->priv->cycle_period) {
+        case XFCE_BACKDROP_PERIOD_STARTUP:
+            /* no more cycling */
+            continue_cycling = FALSE;
+            break;
+
+        case XFCE_BACKDROP_PERIOD_HOURLY:
+            TRACE("XFCE_BACKDROP_PERIOD_HOURLY");
+            local_time = g_date_time_new_now_local();
+            minute = g_date_time_get_minute(local_time);
+            second = g_date_time_get_second(local_time);
+
+            /* find out how long until the next hour so we cycle on the hour */
+            DBG("minute %d, second %d", minute, second);
+            cycle_interval = ((59 - minute) * 60) + (60 - second);
+
+            /* We created a new instance, kill this one */
+            continue_cycling = FALSE;
+            break;
+
+        case XFCE_BACKDROP_PERIOD_DAILY:
+            TRACE("XFCE_BACKDROP_PERIOD_DAILY");
+            local_time = g_date_time_new_now_local();
+            hour   = g_date_time_get_hour  (local_time);
+            minute = g_date_time_get_minute(local_time);
+            second = g_date_time_get_second(local_time);
+
+            /* find out how long until the next day so we cycle on the day */
+            DBG("hour %d minute %d, second %d", hour, minute, second);
+            cycle_interval = ((23 - hour) * 60 * 60) + ((59 - minute) * 60) + (60 - second);
+
+            /* We created a new instance, kill this one */
+            continue_cycling = FALSE;
+            break;
+
+        default:
+            /* no changes required */
+            break;
+    }
+
+    /* Update the timer if we're trying to keep things on the hour/day */
+    if(cycle_interval != 0) {
+        DBG("calling g_timeout_add_seconds, interval is %d", cycle_interval);
+        backdrop->priv->cycle_timer_id = g_timeout_add_seconds(cycle_interval,
+                                                               (GSourceFunc)xfce_backdrop_timer,
+                                                               backdrop);
+    }
+
+    if(local_time != NULL)
+        g_date_time_unref(local_time);
+
+    return continue_cycling;
 }
 
 /**
  * xfce_backdrop_set_cycle_timer:
  * @backdrop: An #XfceBackdrop.
- * @cycle_timer: The amount of time, in minutes, to wait before changing the
- *               background image.
+ * @cycle_timer: The amount of time, based on the cycle_period, to wait before
+ *               changing the background image.
  *
  * If cycle_backdrop is enabled then this function will change the backdrop
- * image based on the cycle_timer, a value between 0 and G_MAXUSHORT.
- * A value of 0 indicates that the backdrop should not be changed.
+ * image based on the cycle_timer and cycle_period. The cycle_timer is a value
+ * between 0 and G_MAXUSHORT where a value of 0 indicates that the backdrop
+ * should not be changed.
  **/
 void
 xfce_backdrop_set_cycle_timer(XfceBackdrop *backdrop, guint cycle_timer)
 {
+    GDateTime *local_time = NULL;
+    guint cycle_interval;
+    gint hour, minute, second;
+
     g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
 
     TRACE("entering, cycle_timer = %d", cycle_timer);
 
+    /* Sanity check to help prevent overflows */
     if(cycle_timer > G_MAXUSHORT)
         cycle_timer = G_MAXUSHORT;
 
     backdrop->priv->cycle_timer = cycle_timer;
 
+    /* always remove the old timer */
     if(backdrop->priv->cycle_timer_id != 0) {
         g_source_remove(backdrop->priv->cycle_timer_id);
         backdrop->priv->cycle_timer_id = 0;
     }
 
-    if(backdrop->priv->cycle_timer != 0 &&
-       backdrop->priv->cycle_backdrop == TRUE) {
-        backdrop->priv->cycle_timer_id = g_timeout_add_seconds(backdrop->priv->cycle_timer * 60,
+    if(backdrop->priv->cycle_timer != 0 && backdrop->priv->cycle_backdrop == TRUE) {
+        switch(backdrop->priv->cycle_period) {
+            case XFCE_BACKDROP_PERIOD_SECONDS:
+                cycle_interval = backdrop->priv->cycle_timer;
+                break;
+
+            case XFCE_BACKDROP_PERIOD_MINUES:
+                cycle_interval = backdrop->priv->cycle_timer * 60;
+                break;
+
+            case XFCE_BACKDROP_PERIOD_HOURS:
+                cycle_interval = backdrop->priv->cycle_timer * 60 * 60;
+                break;
+
+            case XFCE_BACKDROP_PERIOD_STARTUP:
+                cycle_interval = 1;
+                break;
+
+            case XFCE_BACKDROP_PERIOD_HOURLY:
+                TRACE("XFCE_BACKDROP_PERIOD_HOURLY");
+                local_time = g_date_time_new_now_local();
+                minute = g_date_time_get_minute(local_time);
+                second = g_date_time_get_second(local_time);
+
+                /* find out how long until the next hour so we cycle on the hour */
+                DBG("minute %d, second %d", minute, second);
+                cycle_interval = ((59 - minute) * 60) + (60 - second);
+                break;
+
+            case XFCE_BACKDROP_PERIOD_DAILY:
+                TRACE("XFCE_BACKDROP_PERIOD_DAILY");
+                local_time = g_date_time_new_now_local();
+                hour   = g_date_time_get_hour  (local_time);
+                minute = g_date_time_get_minute(local_time);
+                second = g_date_time_get_second(local_time);
+
+                /* find out how long until the next day so we cycle on the day */
+                DBG("hour %d minute %d, second %d", hour, minute, second);
+                cycle_interval = ((23 - hour) * 60 * 60) + ((59 - minute) * 60) + (60 - second);
+                break;
+
+            default:
+                g_critical("Unknown backdrop-cycle-period set");
+                break;
+            }
+
+        DBG("calling g_timeout_add_seconds, interval is %d", cycle_interval);
+        backdrop->priv->cycle_timer_id = g_timeout_add_seconds(cycle_interval,
                                                                (GSourceFunc)xfce_backdrop_timer,
                                                                backdrop);
     }
+
+    if(local_time != NULL)
+        g_date_time_unref(local_time);
 }
 
 guint
@@ -807,6 +937,40 @@ xfce_backdrop_get_cycle_backdrop(XfceBackdrop *backdrop)
 }
 
 /**
+ * xfce_backdrop_set_cycle_period:
+ * @backdrop: An #XfceBackdrop.
+ * @period: Determines how often the backdrop will cycle.
+ *
+ * When cycling backdrops, the period setting will determine how fast the timer
+ * will fire (seconds vs minutes) or if the periodic backdrop will be based on
+ * actual wall clock values or just at xfdesktop's start up.
+ **/
+void
+xfce_backdrop_set_cycle_period(XfceBackdrop *backdrop,
+                               XfceBackdropCyclePeriod period)
+{
+    g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
+    g_return_if_fail(period != XFCE_BACKDROP_PERIOD_INVALID);
+
+    TRACE("entering");
+
+    if(backdrop->priv->cycle_period != period) {
+        backdrop->priv->cycle_period = period;
+        /* Start or stop the backdrop changing */
+        xfce_backdrop_set_cycle_timer(backdrop,
+                                      xfce_backdrop_get_cycle_timer(backdrop));
+    }
+}
+
+XfceBackdropCyclePeriod
+xfce_backdrop_get_cycle_period(XfceBackdrop *backdrop)
+{
+    g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), XFCE_BACKDROP_PERIOD_INVALID);
+
+    return backdrop->priv->cycle_period;
+}
+
+/**
  * xfce_backdrop_set_random_order:
  * @backdrop: An #XfceBackdrop.
  * @random_order: When TRUE and the backdrops are set to cycle, a random image
diff --git a/src/xfce-backdrop.h b/src/xfce-backdrop.h
index 8a46927..3de02d0 100644
--- a/src/xfce-backdrop.h
+++ b/src/xfce-backdrop.h
@@ -59,6 +59,17 @@ typedef enum
     XFCE_BACKDROP_COLOR_TRANSPARENT,
 } XfceBackdropColorStyle;
 
+typedef enum
+{
+    XFCE_BACKDROP_PERIOD_INVALID = -1,
+    XFCE_BACKDROP_PERIOD_SECONDS = 0,
+    XFCE_BACKDROP_PERIOD_MINUES,
+    XFCE_BACKDROP_PERIOD_HOURS,
+    XFCE_BACKDROP_PERIOD_STARTUP,
+    XFCE_BACKDROP_PERIOD_HOURLY,
+    XFCE_BACKDROP_PERIOD_DAILY,
+} XfceBackdropCyclePeriod;
+
 struct _XfceBackdrop
 {
     GObject gobject;
@@ -118,6 +129,11 @@ void xfce_backdrop_set_cycle_backdrop    (XfceBackdrop *backdrop,
                                           gboolean cycle_backdrop);
 gboolean xfce_backdrop_get_cycle_backdrop(XfceBackdrop *backdrop);
 
+void xfce_backdrop_set_cycle_period      (XfceBackdrop *backdrop,
+                                          XfceBackdropCyclePeriod period);
+XfceBackdropCyclePeriod xfce_backdrop_get_cycle_period
+                                         (XfceBackdrop *backdrop);
+
 void xfce_backdrop_set_cycle_timer       (XfceBackdrop *backdrop,
                                           guint cycle_timer);
 guint xfce_backdrop_get_cycle_timer      (XfceBackdrop *backdrop);
diff --git a/src/xfce-workspace.c b/src/xfce-workspace.c
index 936b960..9d33a6f 100644
--- a/src/xfce-workspace.c
+++ b/src/xfce-workspace.c
@@ -129,6 +129,45 @@ xfce_workspace_get_xinerama_stretch(XfceWorkspace *workspace)
 }
 
 static void
+xfce_workspace_change_backdrop(XfceWorkspace *workspace,
+                               XfceBackdrop *backdrop,
+                               const gchar *backdrop_file)
+{
+    XfconfChannel *channel = workspace->priv->channel;
+    char buf[1024];
+    gchar *monitor_name = NULL;
+    guint i, monitor_num;
+
+    g_return_if_fail(workspace->priv->nbackdrops > 0);
+
+    TRACE("entering");
+
+    /* Find out which monitor we're on */
+    for(i = 0; i < workspace->priv->nbackdrops; ++i) {
+        if(backdrop == workspace->priv->backdrops[i]) {
+            monitor_num = i;
+            break;
+        }
+    }
+
+    monitor_name = gdk_screen_get_monitor_plug_name(workspace->priv->gscreen,
+                                                    monitor_num);
+
+    /* Get the backdrop's image property */
+    if(monitor_name == NULL) {
+        g_snprintf(buf, sizeof(buf), "%smonitor%d/workspace%d/last-image",
+                   workspace->priv->property_prefix, monitor_num, workspace->priv->workspace_num);
+    } else {
+        g_snprintf(buf, sizeof(buf), "%smonitor%s/workspace%d/last-image",
+                   workspace->priv->property_prefix, monitor_name, workspace->priv->workspace_num);
+    }
+
+    /* Update the property so that xfdesktop won't show the same image every
+     * time it starts up when the user wants it to cycle different images */
+    xfconf_channel_set_string(channel, buf, backdrop_file);
+}
+
+static void
 backdrop_cycle_cb(XfceBackdrop *backdrop, gpointer user_data)
 {
     const gchar* backdrop_file;
@@ -155,7 +194,7 @@ backdrop_cycle_cb(XfceBackdrop *backdrop, gpointer user_data)
         xfce_workspace_get_workspace_num(workspace));
 
     if(g_strcmp0(backdrop_file, new_backdrop) != 0) {
-        xfce_backdrop_set_image_filename(backdrop, new_backdrop);
+        xfce_workspace_change_backdrop(workspace, backdrop, new_backdrop);
         g_free(new_backdrop);
     }
 }
@@ -507,6 +546,11 @@ xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace,
                            G_OBJECT(backdrop), "backdrop-cycle-enable");
 
     buf[pp_len] = 0;
+    g_strlcat(buf, "backdrop-cycle-period", sizeof(buf));
+    xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_CYCLE_PERIOD,
+                           G_OBJECT(backdrop), "backdrop-cycle-period");
+
+    buf[pp_len] = 0;
     g_strlcat(buf, "backdrop-cycle-timer", sizeof(buf));
     xfconf_g_property_bind(channel, buf, G_TYPE_UINT,
                            G_OBJECT(backdrop), "backdrop-cycle-timer");


More information about the Xfce4-commits mailing list