Updating branch refs/heads/master
         to af240b063cd0678dc1739ffa28e93f1ff530bead (commit)
       from 1c44c0f12eb2a87e94b217a6251e93255dda34a1 (commit)

commit af240b063cd0678dc1739ffa28e93f1ff530bead
Author: Eric Koegel <eric.koe...@gmail.com>
Date:   Sun Oct 13 20:17:26 2013 +0300

    Migrate backdrop settings from previous versions (Bug 10380)
    
    This patch allows for migrating from previous versions (before 4.11). 
Continuing
    to use the older format should make it easier for distribution maintainers 
to
    apply their own backdrop settings since the newer format uses monitor names
    rather than numbers.
    Xfdesktop will search for backdrop settings in the new location, then the 
old
    location, and finally fall back to the built-in defaults (DEFAULT_BACKDROP,
    stretched image style, solid color style, etc).
    It also fixes issues where xfdesktop ended up trying to use an invalid
    workspace.

 common/xfdesktop-common.c                  |   15 ++
 common/xfdesktop-common.h                  |    2 +
 settings/main.c                            |  401 +++++++++++++++++++++-------
 settings/xfce-backdrop-settings.desktop.in |    2 +-
 src/xfce-backdrop.c                        |   83 ++++--
 src/xfce-backdrop.h                        |    2 +
 src/xfce-desktop.c                         |   23 +-
 src/xfce-workspace.c                       |  155 +++++++++++
 8 files changed, 553 insertions(+), 130 deletions(-)

diff --git a/common/xfdesktop-common.c b/common/xfdesktop-common.c
index 65f0214..b2fb406 100644
--- a/common/xfdesktop-common.c
+++ b/common/xfdesktop-common.c
@@ -51,6 +51,7 @@
 #include <libxfce4util/libxfce4util.h>
 
 #include "xfdesktop-common.h"
+#include "xfce-backdrop.h" /* for XfceBackdropImageStyle */
 
 #ifndef O_BINARY
 #define O_BINARY  0
@@ -301,6 +302,20 @@ xfdesktop_send_client_message(Window xid, const gchar *msg)
     gtk_widget_destroy(win);
 }
 
+/* The image styles changed from versions prior to 4.11.
+ * Auto isn't an option anymore, additionally we should handle invalid
+ * values. Set them to the default of stretched. */
+gint
+xfce_translate_image_styles(gint input)
+{
+    gint style = input;
+
+    if(style <= 0 || style > XFCE_BACKDROP_IMAGE_SPANNING_SCREENS)
+        style = XFCE_BACKDROP_IMAGE_STRETCHED;
+
+    return style;
+}
+
 guint
 xfce_grab_cursor(GtkWidget *w,
                  GdkEventButton *evt)
diff --git a/common/xfdesktop-common.h b/common/xfdesktop-common.h
index 1d6db85..725da4f 100644
--- a/common/xfdesktop-common.h
+++ b/common/xfdesktop-common.h
@@ -86,6 +86,8 @@ gchar *xfdesktop_get_file_mimetype(const gchar *file);
 gboolean xfdesktop_check_is_running(Window *xid);
 void xfdesktop_send_client_message(Window xid, const gchar *msg);
 
+gint xfce_translate_image_styles(gint input);
+
 guint xfce_grab_cursor(GtkWidget *w, GdkEventButton *evt);
 gboolean xfdesktop_popup_grab_available(GdkWindow *win, guint32 timestamp);
 
diff --git a/settings/main.c b/settings/main.c
index 69a5da5..74da46e 100644
--- a/settings/main.c
+++ b/settings/main.c
@@ -48,14 +48,19 @@
 #include <xfconf/xfconf.h>
 #include <libxfce4ui/libxfce4ui.h>
 #include <libwnck/libwnck.h>
+#include <exo/exo.h>
 
 #include "xfdesktop-common.h"
 #include "xfdesktop-thumbnailer.h"
 #include "xfdesktop-settings-ui.h"
 #include "xfdesktop-settings-appearance-frame-ui.h"
+/* for XfceBackdropImageStyle && XfceBackdropColorStyle */
+#include "xfce-backdrop.h"
 
-#define PREVIEW_HEIGHT  96
 #define MAX_ASPECT_RATIO 1.5f
+#define PREVIEW_HEIGHT   96
+#define PREVIEW_WIDTH    (PREVIEW_HEIGHT * MAX_ASPECT_RATIO)
+
 
 #define SHOW_DESKTOP_MENU_PROP               "/desktop-menu/show"
 #define DESKTOP_MENU_SHOW_ICONS_PROP         "/desktop-menu/show-icons"
@@ -77,9 +82,6 @@
 #define DESKTOP_ICONS_SHOW_FILESYSTEM        
"/desktop-icons/file-icons/show-filesystem"
 #define DESKTOP_ICONS_SHOW_REMOVABLE         
"/desktop-icons/file-icons/show-removable"
 
-#define XFCE_BACKDROP_IMAGE_NONE             0
-#define XFCE_BACKDROP_IMAGE_SCALED           4
-#define XFCE_BACKDROP_IMAGE_SPANNING_SCREENS 6
 
 typedef struct
 {
@@ -97,6 +99,9 @@ typedef struct
     gulong image_list_loaded:1;
 
     WnckWindow *wnck_window;
+    /* We keep track of the current workspace number because
+     * wnck_screen_get_active_workspace sometimes has to return NULL. */
+    gint active_workspace;
 
     GtkWidget *frame_image_list;
     GtkWidget *image_iconview;
@@ -158,58 +163,41 @@ static void cb_xfdesktop_chk_apply_to_all(GtkCheckButton 
*button,
                                           gpointer user_data);
 static gchar 
*xfdesktop_settings_generate_per_workspace_binding_string(AppearancePanel 
*panel,
                                                                        const 
gchar* property);
-
+static gchar *xfdesktop_settings_get_backdrop_image(AppearancePanel *panel);
 
 static void
 xfdesktop_settings_do_single_preview(GtkTreeModel *model,
                                      GtkTreeIter *iter)
 {
     gchar *filename = NULL, *thumbnail = NULL;
-    GdkPixbuf *pix, *pix_scaled = NULL;
+    GdkPixbuf *pix;
 
-    GDK_THREADS_ENTER ();
     gtk_tree_model_get(model, iter,
                        COL_FILENAME, &filename,
                        COL_THUMBNAIL, &thumbnail,
                        -1);
-    GDK_THREADS_LEAVE ();
 
+    /* If we didn't create a thumbnail there might not be a thumbnailer service
+     * or it may not support that format */
     if(thumbnail == NULL) {
-        pix = gdk_pixbuf_new_from_file(filename, NULL);
+        pix = exo_gdk_pixbuf_new_from_file_at_max_size(filename,
+                                                       PREVIEW_WIDTH, 
PREVIEW_HEIGHT,
+                                                       TRUE, NULL);
     } else {
-        pix = gdk_pixbuf_new_from_file(thumbnail, NULL);
+        pix = exo_gdk_pixbuf_new_from_file_at_max_size(thumbnail,
+                                                       PREVIEW_WIDTH, 
PREVIEW_HEIGHT,
+                                                       TRUE, NULL);
         g_free(thumbnail);
     }
 
     g_free(filename);
-    if(pix) {
-        gint width, height;
-        gdouble aspect;
 
-        width = gdk_pixbuf_get_width(pix);
-        height = gdk_pixbuf_get_height(pix);
-        aspect = (gdouble)width / height;
-
-        /* Keep the aspect ratio sensible otherwise the treeview looks bad */
-        if(aspect > MAX_ASPECT_RATIO) {
-            aspect = MAX_ASPECT_RATIO;
-        }
-
-        width = PREVIEW_HEIGHT * aspect;
-        height = PREVIEW_HEIGHT;
-        pix_scaled = gdk_pixbuf_scale_simple(pix, width, height,
-                                             GDK_INTERP_BILINEAR);
-
-        g_object_unref(G_OBJECT(pix));
-    }
-
-    if(pix_scaled) {
-        GDK_THREADS_ENTER ();
+    if(pix) {
         gtk_list_store_set(GTK_LIST_STORE(model), iter,
-                           COL_PIX, pix_scaled,
+                           COL_PIX, pix,
                            -1);
-        GDK_THREADS_LEAVE ();
-        g_object_unref(G_OBJECT(pix_scaled));
+
+        g_object_unref(G_OBJECT(pix));
     }
 }
 
@@ -259,7 +247,7 @@ xfdesktop_settings_add_file_to_queue(AppearancePanel 
*panel, PreviewData *pdata)
     /* Create the thread if it doesn't exist */
     if(panel->preview_thread == NULL) {
 #if GLIB_CHECK_VERSION(2, 32, 0)
-        panel->preview_thread = 
g_thread_try_new("xfdesktop_settings_create_previews",
+        panel->preview_thread = g_thread_try_new("create_previews",
                                                  
xfdesktop_settings_create_previews,
                                                  panel, NULL);
 #else
@@ -615,7 +603,6 @@ xfdesktop_image_list_add_dir(GObject *source_object,
                              gpointer user_data)
 {
     AppearancePanel *panel = user_data;
-    gchar *property;
     AddDirData *dir_data = g_new0(AddDirData, 1);
 
     TRACE("entering");
@@ -627,9 +614,7 @@ xfdesktop_image_list_add_dir(GObject *source_object,
 
     /* Get the last image/current image displayed so we can select it in the
      * icon view */
-    property = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"last-image");
-
-    dir_data->last_image = xfconf_channel_get_string(panel->channel, property, 
DEFAULT_BACKDROP);
+    dir_data->last_image = xfdesktop_settings_get_backdrop_image(panel);
 
     dir_data->file_path = g_file_get_path(panel->selected_folder);
 
@@ -643,8 +628,6 @@ xfdesktop_image_list_add_dir(GObject *source_object,
                                              xfdesktop_image_list_add_item,
                                              dir_data,
                                              cb_destroy_add_dir_enumeration);
-
-    g_free(property);
 }
 
 static void
@@ -653,16 +636,24 @@ 
xfdesktop_settings_update_iconview_frame_name(AppearancePanel *panel,
 {
     gchar buf[1024];
     gchar *workspace_name;
+    WnckScreen *screen;
+    WnckWorkspace *workspace;
 
-    if(panel->monitor < 0 && panel->workspace < 0)
+    /* Don't update the name until we find our window */
+    if(panel->wnck_window == NULL)
         return;
 
+    g_return_if_fail(panel->monitor >= 0 && panel->workspace >= 0);
+
+    /* If it's a pinned window get the active workspace */
     if(wnck_workspace == NULL) {
-        WnckScreen *wnck_screen = wnck_window_get_screen(panel->wnck_window);
-        wnck_workspace = wnck_screen_get_active_workspace(wnck_screen);
+        screen = wnck_window_get_screen(panel->wnck_window);
+        workspace = wnck_screen_get_workspace(screen, panel->active_workspace);
+    } else {
+        workspace = wnck_workspace;
     }
 
-    workspace_name = g_strdup(wnck_workspace_get_name(wnck_workspace));
+    workspace_name = g_strdup(wnck_workspace_get_name(workspace));
 
     
if(gdk_screen_get_n_monitors(gtk_widget_get_screen(panel->chk_apply_to_all)) > 
1) {
         
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->chk_apply_to_all))) {
@@ -723,6 +714,51 @@ 
xfdesktop_settings_generate_per_workspace_binding_string(AppearancePanel *panel,
     return buf;
 }
 
+static gchar*
+xfdesktop_settings_generate_old_binding_string(AppearancePanel *panel,
+                                               const gchar* property)
+{
+    gchar *buf = NULL;
+
+    buf = g_strdup_printf("/backdrop/screen%d/monitor%d/%s",
+                          panel->screen, panel->monitor, property);
+
+    DBG("name %s", buf);
+
+    return buf;
+}
+
+/* Attempts to load the backdrop from the current location followed by using
+ * how previous versions of xfdesktop (before 4.11) did. This matches how
+ * xfdesktop searches for backdrops.
+ * Free the returned string when done using it. */
+static gchar *
+xfdesktop_settings_get_backdrop_image(AppearancePanel *panel)
+{
+    gchar *last_image;
+    gchar *property, *old_property = NULL;
+
+    /* Get the last image/current image displayed, if available */
+    property = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"last-image");
+
+    last_image = xfconf_channel_get_string(panel->channel, property, NULL);
+
+    /* Try the previous version or fall back to our provided default */
+    if(last_image == NULL) {
+        old_property = xfdesktop_settings_generate_old_binding_string(panel,
+                                                                      
"image-path");
+        last_image = xfconf_channel_get_string(panel->channel,
+                                               old_property,
+                                               DEFAULT_BACKDROP);
+    }
+
+    g_free(property);
+    if(old_property)
+        g_free(old_property);
+
+    return last_image;
+}
+
 static void
 cb_image_selection_changed(GtkIconView *icon_view,
                            gpointer user_data)
@@ -732,7 +768,7 @@ cb_image_selection_changed(GtkIconView *icon_view,
     GtkTreeIter iter;
     GList *selected_items = NULL;
     gchar *filename = NULL, *current_filename = NULL;
-    gchar *buf;
+    gchar *buf = NULL;
 
     TRACE("entering");
 
@@ -751,9 +787,8 @@ cb_image_selection_changed(GtkIconView *icon_view,
 
     gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
 
-    buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"last-image");
-
-    current_filename = xfconf_channel_get_string(panel->channel, buf, "");
+    /* Get the current/last image, handles migrating from old versions */
+    current_filename = xfdesktop_settings_get_backdrop_image(panel);
 
     /* check to see if the selection actually did change */
     if(g_strcmp0(current_filename, filename) != 0) {
@@ -765,13 +800,19 @@ cb_image_selection_changed(GtkIconView *icon_view,
                 panel->screen, panel->monitor_name, panel->workspace);
         }
 
+        /* Get the property location to save our changes, always save to new
+         * location */
+        buf = xfdesktop_settings_generate_per_workspace_binding_string(panel,
+                                                                       
"last-image");
+        DBG("Saving to %s/%s", buf, filename);
         xfconf_channel_set_string(panel->channel, buf, filename);
     }
 
     g_list_foreach (selected_items, (GFunc)gtk_tree_path_free, NULL);
     g_list_free(selected_items);
     g_free(current_filename);
-    g_free(buf);
+    if(buf)
+        g_free(buf);
 }
 
 static gint
@@ -785,13 +826,14 @@ xfdesktop_settings_get_active_workspace(AppearancePanel 
*panel,
 
     wnck_workspace = wnck_window_get_workspace(wnck_window);
 
+    /* If wnck_workspace is NULL that means it's pinned and we just need to
+     * use the active/current workspace */
     if(wnck_workspace != NULL) {
         workspace_num = wnck_workspace_get_number(wnck_workspace);
     } else {
-        workspace_num = 
wnck_workspace_get_number(wnck_screen_get_active_workspace(wnck_screen));
+        workspace_num = panel->active_workspace;
     }
 
-
     single_workspace = xfconf_channel_get_bool(panel->channel,
                                                SINGLE_WORKSPACE_MODE,
                                                TRUE);
@@ -1033,12 +1075,15 @@ cb_xfdesktop_combo_color_changed(GtkComboBox *combo,
 static void
 xfdesktop_settings_update_iconview_folder(AppearancePanel *panel)
 {
-    gchar *current_folder, *prop_last, *dirname;
+    gchar *current_folder, *dirname;
+
+    /* If we haven't found our window return now and wait for that */
+    if(panel->wnck_window == NULL)
+        return;
 
     TRACE("entering");
 
-    prop_last = 
xfdesktop_settings_generate_per_workspace_binding_string(panel, "last-image");
-    current_folder = xfconf_channel_get_string(panel->channel, prop_last, 
DEFAULT_BACKDROP);
+    current_folder = xfdesktop_settings_get_backdrop_image(panel);
     dirname = g_path_get_dirname(current_folder);
 
     gtk_file_chooser_set_current_folder((GtkFileChooser*)panel->btn_folder, 
dirname);
@@ -1047,7 +1092,6 @@ xfdesktop_settings_update_iconview_folder(AppearancePanel 
*panel)
     cb_folder_selection_changed(panel->btn_folder, panel);
 
     g_free(current_folder);
-    g_free(prop_last);
     g_free(dirname);
 }
 
@@ -1057,15 +1101,30 @@ static void
 xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
                                                   gboolean remove_binding)
 {
-    gchar *buf;
+    gchar *buf, *old_property = NULL;
     XfconfChannel *channel = panel->channel;
 
-    /* Style combobox */
+    /* Image style combo box */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"image-style");
     if(remove_binding) {
         xfconf_g_property_unbind_by_property(channel, buf,
                                G_OBJECT(panel->image_style_combo), "active");
     } else {
+        /* If the current image style doesn't exist, try to load the old one */
+        if(!xfconf_channel_has_property(channel, buf)) {
+            gint image_style;
+            old_property = 
xfdesktop_settings_generate_old_binding_string(panel, "image-style");
+
+            /* default to stretched when trying to migrate */
+            image_style = xfconf_channel_get_int(channel, old_property, 
XFCE_BACKDROP_IMAGE_STRETCHED);
+
+            /* xfce_translate_image_styles will do sanity checking */
+            gtk_combo_box_set_active(GTK_COMBO_BOX(panel->image_style_combo),
+                                     xfce_translate_image_styles(image_style));
+
+            g_free(old_property);
+        }
+
         xfconf_g_property_bind(channel, buf, G_TYPE_INT,
                                G_OBJECT(panel->image_style_combo), "active");
         /* determine if the iconview is sensitive */
@@ -1073,12 +1132,31 @@ 
xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     }
     g_free(buf);
 
-    /* Color options*/
+    /* Color style combo box */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"color-style");
     if(remove_binding) {
         xfconf_g_property_unbind_by_property(channel, buf,
                            G_OBJECT(panel->color_style_combo), "active");
     } else {
+        /* If the current color style doesn't exist, try to load the old one */
+        if(!xfconf_channel_has_property(channel, buf)) {
+            gint color_style;
+            old_property = 
xfdesktop_settings_generate_old_binding_string(panel, "color-style");
+
+            /* default to solid when trying to migrate */
+            color_style = xfconf_channel_get_int(channel, old_property, 
XFCE_BACKDROP_COLOR_SOLID);
+
+            /* sanity check */
+            if(color_style < 0 || color_style > 
XFCE_BACKDROP_COLOR_TRANSPARENT) {
+                g_warning("invalid color style, setting to solid");
+                color_style = XFCE_BACKDROP_COLOR_SOLID;
+            }
+
+            gtk_combo_box_set_active(GTK_COMBO_BOX(panel->color_style_combo),
+                                     color_style);
+            g_free(old_property);
+        }
+
         xfconf_g_property_bind(channel, buf, G_TYPE_INT,
                                G_OBJECT(panel->color_style_combo), "active");
         /* update the color button sensitivity */
@@ -1086,27 +1164,63 @@ 
xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     }
     g_free(buf);
 
+    /* color 1 button */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"color1");
     if(remove_binding) {
         xfconf_g_property_unbind(panel->color1_btn_id);
     } else {
+        /* If the first color doesn't exist, try to load the old one */
+        if(!xfconf_channel_has_property(channel, buf)) {
+            GValue value = { 0, };
+            old_property = 
xfdesktop_settings_generate_old_binding_string(panel, "color1");
+
+            xfconf_channel_get_property(channel, old_property, &value);
+
+            if(G_VALUE_HOLDS_BOXED(&value)) {
+                gtk_color_button_set_color(GTK_COLOR_BUTTON(panel->color1_btn),
+                                           g_value_get_boxed(&value));
+                g_value_unset(&value);
+            }
+
+            g_free(old_property);
+        }
+
+        /* Now bind to the new value */
         panel->color1_btn_id = xfconf_g_property_bind_gdkcolor(channel, buf,
                                                                
G_OBJECT(panel->color1_btn),
                                                                "color");
     }
     g_free(buf);
 
+    /* color 2 button */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"color2");
     if(remove_binding) {
         xfconf_g_property_unbind(panel->color2_btn_id);
     } else {
+        /* If the 2nd color doesn't exist, try to load the old one */
+        if(!xfconf_channel_has_property(channel, buf)) {
+            GValue value = { 0, };
+            old_property = 
xfdesktop_settings_generate_old_binding_string(panel, "color1");
+
+            xfconf_channel_get_property(channel, old_property, &value);
+
+            if(G_VALUE_HOLDS_BOXED(&value)) {
+                gtk_color_button_set_color(GTK_COLOR_BUTTON(panel->color1_btn),
+                                           g_value_get_boxed(&value));
+                g_value_unset(&value);
+            }
+
+            g_free(old_property);
+        }
+
+        /* Now bind to the new value */
         panel->color2_btn_id = xfconf_g_property_bind_gdkcolor(channel, buf,
                                                                
G_OBJECT(panel->color2_btn),
                                                                "color");
     }
     g_free(buf);
 
-    /* Cycle timer options */
+    /* enable cycle timer check box */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"backdrop-cycle-enable");
     if(remove_binding) {
         xfconf_g_property_unbind_by_property(channel, buf,
@@ -1117,6 +1231,7 @@ 
xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     }
     g_free(buf);
 
+    /* cycle timer spin box */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"backdrop-cycle-timer");
     if(remove_binding) {
         xfconf_g_property_unbind_by_property(channel, buf,
@@ -1129,6 +1244,7 @@ 
xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     }
     g_free(buf);
 
+    /* cycle random order check box */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, 
"backdrop-cycle-random-order");
     if(remove_binding) {
         xfconf_g_property_unbind_by_property(channel, buf,
@@ -1159,6 +1275,11 @@ cb_update_background_tab(WnckWindow *wnck_window,
     WnckWorkspace *wnck_workspace = NULL;
     GdkScreen *screen;
 
+    /* If we haven't found our window return now and wait for that */
+    if(panel->wnck_window == NULL)
+        return;
+
+    /* Get all the new settings for comparison */
     screen = gtk_widget_get_screen(panel->image_iconview);
     wnck_workspace = wnck_window_get_workspace(wnck_window);
 
@@ -1168,18 +1289,31 @@ cb_update_background_tab(WnckWindow *wnck_window,
                                                    
gtk_widget_get_window(panel->image_iconview));
     monitor_name = gdk_screen_get_monitor_plug_name(screen, monitor_num);
 
-    /* Check to see if something changed */
-    if(panel->workspace == workspace_num &&
-       panel->screen == screen_num &&
-       panel->monitor_name != NULL &&
-       g_strcmp0(panel->monitor_name, monitor_name) == 0) {
-           return;
+    /* Most of the time we won't change monitor, screen, or workspace so try
+     * to bail out now if we can */
+    /* Check to see if we haven't changed workspace or screen */
+    if(panel->workspace == workspace_num && panel->screen == screen_num)
+    {
+        /* do we support monitor names? */
+        if(panel->monitor_name != NULL || monitor_name != NULL) {
+            /* Check if we haven't changed monitors (by name) */
+            if(g_strcmp0(panel->monitor_name, monitor_name) == 0) {
+                g_free(monitor_name);
+                return;
+            }
+        } else {
+            /* Check if we haven't changed monitors (by number) */
+            if(panel->monitor == monitor_num) {
+                return;
+            }
+        }
     }
 
     TRACE("screen, monitor, or workspace changed");
 
-    /* remove the old bindings */
-    if(panel->monitor != -1 && panel->workspace != -1) {
+    /* remove the old bindings if there are any */
+    if(panel->color1_btn_id || panel->color2_btn_id) {
+        DBG("removing old bindings");
         xfdesktop_settings_background_tab_change_bindings(panel,
                                                           TRUE);
     }
@@ -1218,10 +1352,83 @@ cb_workspace_changed(WnckScreen *screen,
                      gpointer user_data)
 {
     AppearancePanel *panel = user_data;
+    WnckWorkspace *active_workspace;
+    gint new_num = -1;
+
+    g_return_if_fail(WNCK_IS_SCREEN(screen));
+
+    /* Update the current workspace number */
+    active_workspace = wnck_screen_get_active_workspace(screen);
+    if(WNCK_IS_WORKSPACE(active_workspace))
+        new_num = wnck_workspace_get_number(active_workspace);
+
+    /* This will sometimes fail to update */
+    if(new_num != -1)
+        panel->active_workspace = new_num;
+
+    DBG("active_workspace now %d", panel->active_workspace);
+
+    /* Call cb_update_background_tab in case this is a pinned window */
+    if(panel->wnck_window != NULL)
+        cb_update_background_tab(panel->wnck_window, panel);
+}
+
+static void
+cb_workspace_count_changed(WnckScreen *screen,
+                           WnckWorkspace *workspace,
+                           gpointer user_data)
+{
+    AppearancePanel *panel = user_data;
 
     /* Update background because the single workspace mode may have
      * changed due to the addition/removal of a workspace */
-    cb_update_background_tab(panel->wnck_window, user_data);
+    if(panel->wnck_window != NULL)
+        cb_update_background_tab(panel->wnck_window, user_data);
+}
+
+static void
+cb_window_opened(WnckScreen *screen,
+                 WnckWindow *window,
+                 gpointer user_data)
+{
+    AppearancePanel *panel = user_data;
+    GtkWidget *toplevel;
+    WnckWorkspace *workspace;
+
+    /* If we already found our window, exit */
+    if(panel->wnck_window != NULL)
+        return;
+
+    toplevel = gtk_widget_get_toplevel(panel->image_iconview);
+
+    /* If they don't match then it's not our window, exit */
+    if(wnck_window_get_xid(window) != 
GDK_WINDOW_XID(gtk_widget_get_window(toplevel)))
+        return;
+
+    DBG("Found our window");
+    panel->wnck_window = window;
+
+    /* These callbacks are for updating the image_iconview when the window
+     * moves to another monitor or workspace */
+    g_signal_connect(panel->wnck_window, "geometry-changed",
+                     G_CALLBACK(cb_update_background_tab), panel);
+    g_signal_connect(panel->wnck_window, "workspace-changed",
+                     G_CALLBACK(cb_update_background_tab), panel);
+
+    workspace = wnck_window_get_workspace(window);
+
+    /* Update the active workspace number */
+    cb_workspace_changed(screen, workspace, panel);
+
+    /* Update the background settings */
+    cb_update_background_tab(window, panel);
+
+    /* If it's a pinned window get the active workspace */
+    if(workspace == NULL)
+        workspace = wnck_screen_get_workspace(screen, panel->active_workspace);
+
+    /* Update the frame name */
+    xfdesktop_settings_update_iconview_frame_name(panel, workspace);
 }
 
 static void
@@ -1292,8 +1499,7 @@ xfdesktop_settings_setup_image_iconview(AppearancePanel 
*panel)
 static void
 xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml,
                                      XfconfChannel *channel,
-                                     GdkScreen *screen,
-                                     gulong window_xid)
+                                     GdkScreen *screen)
 {
     GtkWidget *appearance_container, *chk_custom_font_size,
               *spin_font_size, *w, *box, *spin_icon_size,
@@ -1357,34 +1563,24 @@ xfdesktop_settings_dialog_setup_tabs(GtkBuilder 
*main_gxml,
     panel->channel = channel;
     panel->screen = gdk_screen_get_number(screen);
 
-    /* We have to force wnck to initialize */
     wnck_screen = wnck_screen_get(panel->screen);
-    wnck_screen_force_update(wnck_screen);
-    panel->wnck_window = wnck_window_get(window_xid);
-
-    if(panel->wnck_window == NULL)
-        panel->wnck_window = wnck_screen_get_active_window(wnck_screen);
 
-    /* These callbacks are for updating the image_iconview when the window
-     * moves to another monitor or workspace */
-    g_signal_connect(panel->wnck_window, "geometry-changed",
-                     G_CALLBACK(cb_update_background_tab), panel);
-    g_signal_connect(panel->wnck_window, "workspace-changed",
-                     G_CALLBACK(cb_update_background_tab), panel);
+    /* watch for workspace changes */
     g_signal_connect(wnck_screen, "workspace-created",
-                     G_CALLBACK(cb_workspace_changed), panel);
+                     G_CALLBACK(cb_workspace_count_changed), panel);
     g_signal_connect(wnck_screen, "workspace-destroyed",
-                     G_CALLBACK(cb_workspace_changed), panel);
+                     G_CALLBACK(cb_workspace_count_changed), panel);
     g_signal_connect(wnck_screen, "active-workspace-changed",
-                    G_CALLBACK(cb_workspace_changed), panel);
+                     G_CALLBACK(cb_workspace_changed), panel);
+
+    /* watch for window-opened so we can find our window and track it's 
changes */
+    g_signal_connect(wnck_screen, "window-opened",
+                     G_CALLBACK(cb_window_opened), panel);
+
+    /* watch for monitor changes */
     g_signal_connect(G_OBJECT(screen), "monitors-changed",
                      G_CALLBACK(cb_monitor_changed), panel);
 
-    /* send invalid numbers so that the update_background_tab will update 
everything */
-    panel->monitor = -1;
-    panel->workspace = -1;
-    panel->monitor_name = NULL;
-
     appearance_gxml = gtk_builder_new();
     if(!gtk_builder_add_from_string(appearance_gxml,
                                     xfdesktop_settings_appearance_frame_ui,
@@ -1445,8 +1641,8 @@ xfdesktop_settings_dialog_setup_tabs(GtkBuilder 
*main_gxml,
                      panel);
 
     /* Pick the first entries so something shows up */
-    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->image_style_combo), 
XFCE_BACKDROP_IMAGE_SCALED);
-    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->color_style_combo), 0);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->image_style_combo), 
XFCE_BACKDROP_IMAGE_STRETCHED);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->color_style_combo), 
XFCE_BACKDROP_COLOR_SOLID);
 
     /* Use these settings for all workspaces checkbox */
     panel->chk_apply_to_all =  
GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
@@ -1567,6 +1763,7 @@ main(int argc, char **argv)
 {
     XfconfChannel *channel;
     GtkBuilder *gxml;
+    GdkScreen *screen;
     GError *error = NULL;
 
 #ifdef G_ENABLE_DEBUG
@@ -1580,7 +1777,6 @@ main(int argc, char **argv)
 #if !GLIB_CHECK_VERSION(2, 32, 0)
     g_thread_init(NULL);
 #endif
-    gdk_threads_init();
 
     if(!gtk_init_with_args(&argc, &argv, "", option_entries, PACKAGE, &error)) 
{
         if(G_LIKELY(error)) {
@@ -1634,14 +1830,12 @@ main(int argc, char **argv)
         g_signal_connect(dialog, "response",
                          G_CALLBACK(xfdesktop_settings_response), NULL);
         gtk_window_present(GTK_WINDOW (dialog));
-        xfdesktop_settings_dialog_setup_tabs(gxml, channel,
-                                             gtk_widget_get_screen(dialog),
-                                             
GDK_WINDOW_XID(gtk_widget_get_window(dialog)));
+
+        screen = gtk_widget_get_screen(dialog);
 
         /* To prevent the settings dialog to be saved in the session */
         gdk_x11_set_sm_client_id("FAKE ID");
 
-        gtk_main();
     } else {
         GtkWidget *plug, *plug_child;
 
@@ -1655,13 +1849,14 @@ main(int argc, char **argv)
         plug_child = GTK_WIDGET(gtk_builder_get_object(gxml, "alignment1"));
         gtk_widget_reparent(plug_child, plug);
         gtk_widget_show(plug_child);
-        xfdesktop_settings_dialog_setup_tabs(gxml, channel,
-                                             gtk_widget_get_screen(plug),
-                                             
GDK_WINDOW_XID(gtk_widget_get_window(plug_child)));
 
-        gtk_main();
+        screen = gtk_widget_get_screen(plug);
     }
 
+    xfdesktop_settings_dialog_setup_tabs(gxml, channel, screen);
+
+    gtk_main();
+
     g_object_unref(G_OBJECT(gxml));
 
     g_object_unref(G_OBJECT(channel));
diff --git a/settings/xfce-backdrop-settings.desktop.in 
b/settings/xfce-backdrop-settings.desktop.in
index ce87ed2..e20ac18 100644
--- a/settings/xfce-backdrop-settings.desktop.in
+++ b/settings/xfce-backdrop-settings.desktop.in
@@ -9,6 +9,6 @@ Type=Application
 
Categories=XFCE;GTK;Settings;DesktopSettings;X-XFCE-SettingsDialog;X-XFCE-PersonalSettings;
 OnlyShowIn=XFCE;
 StartupNotify=true
-X-XfcePluggable=true
+X-XfcePluggable=false
 X-XfceHelpComponent=xfdesktop
 X-XfceHelpPage=preferences
diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c
index c4827a9..ff0d784 100644
--- a/src/xfce-backdrop.c
+++ b/src/xfce-backdrop.c
@@ -267,12 +267,14 @@ xfce_backdrop_class_init(XfceBackdropClass *klass)
                                 | G_PARAM_STATIC_NICK \
                                 | G_PARAM_STATIC_BLURB)
 
+    /* Defaults to an invalid color style so that
+     * xfce_workspace_migrate_backdrop_color_style can handle it properly */
     g_object_class_install_property(gobject_class, PROP_COLOR_STYLE,
                                     g_param_spec_enum("color-style",
                                                       "color style",
                                                       "color style",
                                                       
XFCE_TYPE_BACKDROP_COLOR_STYLE,
-                                                      
XFCE_BACKDROP_COLOR_SOLID,
+                                                      
XFCE_BACKDROP_COLOR_INVALID,
                                                       XFDESKTOP_PARAM_FLAGS));
 
     g_object_class_install_property(gobject_class, PROP_COLOR1,
@@ -289,19 +291,23 @@ xfce_backdrop_class_init(XfceBackdropClass *klass)
                                                        GDK_TYPE_COLOR,
                                                        XFDESKTOP_PARAM_FLAGS));
 
+    /* Defaults to an invalid image style so that
+     * xfce_workspace_migrate_backdrop_image_style can handle it properly */
     g_object_class_install_property(gobject_class, PROP_IMAGE_STYLE,
                                     g_param_spec_enum("image-style",
                                                       "image style",
                                                       "image style",
                                                       
XFCE_TYPE_BACKDROP_IMAGE_STYLE,
-                                                      
XFCE_BACKDROP_IMAGE_SCALED,
+                                                      
XFCE_BACKDROP_IMAGE_INVALID,
                                                       XFDESKTOP_PARAM_FLAGS));
 
+    /* The DEFAULT_BACKDROP is provided in the function
+     * xfce_workspace_migrate_backdrop_image instead of here */
     g_object_class_install_property(gobject_class, PROP_IMAGE_FILENAME,
                                     g_param_spec_string("image-filename",
                                                         "image filename",
                                                         "image filename",
-                                                        DEFAULT_BACKDROP,
+                                                        NULL,
                                                         
XFDESKTOP_PARAM_FLAGS));
 
     g_object_class_install_property(gobject_class, PROP_BACKDROP_CYCLE_ENABLE,
@@ -553,8 +559,8 @@ xfce_backdrop_set_color_style(XfceBackdrop *backdrop,
         XfceBackdropColorStyle style)
 {
     g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
-    g_return_if_fail((int)style >= 0 && style <= 
XFCE_BACKDROP_COLOR_TRANSPARENT);
-    
+    g_return_if_fail((int)style >= -1 && style <= 
XFCE_BACKDROP_COLOR_TRANSPARENT);
+
     if(style != backdrop->priv->color_style) {
         xfce_backdrop_clear_cached_image(backdrop);
         backdrop->priv->color_style = style;
@@ -651,8 +657,7 @@ xfce_backdrop_get_second_color(XfceBackdrop *backdrop,
  * @backdrop: An #XfceBackdrop.
  * @style: An XfceBackdropImageStyle.
  *
- * Sets the image style to be used for the #XfceBackdrop.  "AUTO" attempts to
- * pick the best of "TILED" or "STRETCHED" based on the image size.
+ * Sets the image style to be used for the #XfceBackdrop.
  * "STRETCHED" will stretch the image to the full width and height of the
  * #XfceBackdrop, while "SCALED" will resize the image to fit the desktop
  * while maintaining the image's aspect ratio.
@@ -692,7 +697,7 @@ xfce_backdrop_set_image_filename(XfceBackdrop *backdrop, 
const gchar *filename)
 {
     g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
 
-    TRACE("entering");
+    TRACE("entering, filename %s", filename);
 
     g_free(backdrop->priv->image_path);
     
@@ -769,6 +774,14 @@ xfce_backdrop_get_cycle_timer(XfceBackdrop *backdrop)
     return backdrop->priv->cycle_timer;
 }
 
+/**
+ * xfce_backdrop_set_cycle_backdrop:
+ * @backdrop: An #XfceBackdrop.
+ * @cycle_backdrop: True to cycle backdrops every cycle_timer minutes
+ *
+ * Setting cycle_backdrop to TRUE will begin cycling this backdrop based on
+ * the cycle_timer value set in xfce_backdrop_set_cycle_timer.
+ **/
 void
 xfce_backdrop_set_cycle_backdrop(XfceBackdrop *backdrop,
                                  gboolean cycle_backdrop)
@@ -793,6 +806,16 @@ xfce_backdrop_get_cycle_backdrop(XfceBackdrop *backdrop)
     return backdrop->priv->cycle_backdrop;
 }
 
+/**
+ * xfce_backdrop_set_random_order:
+ * @backdrop: An #XfceBackdrop.
+ * @random_order: When TRUE and the backdrops are set to cycle, a random image
+ *                image will be choosen when it cycles.
+ *
+ * When cycling backdrops, they will either be show sequentially (and this 
value
+ * will be FALSE) or they will be selected at random. The images are choosen 
from
+ * the same folder the current backdrop image file is in.
+ **/
 void
 xfce_backdrop_set_random_order(XfceBackdrop *backdrop,
                                gboolean random_order)
@@ -821,6 +844,12 @@ xfce_backdrop_generate_canvas(XfceBackdrop *backdrop)
     w = backdrop->priv->width;
     h = backdrop->priv->height;
 
+    /* In case we somehow end up here, give a warning and apply a temp fix */
+    if(backdrop->priv->color_style == XFCE_BACKDROP_COLOR_INVALID) {
+        g_warning("xfce_backdrop_generate_canvas: Invalid color style");
+        backdrop->priv->color_style = XFCE_BACKDROP_COLOR_SOLID;
+    }
+
     if(backdrop->priv->color_style == XFCE_BACKDROP_COLOR_SOLID)
         final_image = create_solid(&backdrop->priv->color1, w, h, FALSE, 0xff);
     else if(backdrop->priv->color_style == XFCE_BACKDROP_COLOR_TRANSPARENT) {
@@ -862,9 +891,14 @@ xfce_backdrop_image_data_release(XfceBackdropImageData 
*image_data)
 
 }
 
-/* Returns the composited backdrop image if one has been generated. If it
+/**
+ * xfce_backdrop_get_pixbuf:
+ * @backdrop: An #XfceBackdrop.
+ *
+ * Returns the composited backdrop image if one has been generated. If it
  * returns NULL, call xfce_backdrop_generate_async to create the pixbuf.
- * Free with g_object_unref() when you are finished. */
+ * Free with g_object_unref() when you are finished.
+ **/
 GdkPixbuf *
 xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
 {
@@ -876,13 +910,19 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
     return NULL;
 }
 
-/* Generates the final composited, resized image from the #XfceBackdrop.
- * Emits the "ready" signal when the image has been created */
+/**
+ * xfce_backdrop_generate_async:
+ * @backdrop: An #XfceBackdrop.
+ *
+ * Generates the final composited, resized image from the #XfceBackdrop.
+ * Emits the "ready" signal when the image has been created.
+ **/
 void
 xfce_backdrop_generate_async(XfceBackdrop *backdrop)
 {
     GFile *file;
     XfceBackdropImageData *image_data = NULL;
+    const gchar *image_path;
 
     TRACE("entering");
 
@@ -897,16 +937,22 @@ xfce_backdrop_generate_async(XfceBackdrop *backdrop)
     }
 
     /* If we aren't going to display an image then just create the canvas */
-    if(backdrop->priv->image_style == XFCE_BACKDROP_IMAGE_NONE
-       || !backdrop->priv->image_path) {
+    if(backdrop->priv->image_style == XFCE_BACKDROP_IMAGE_NONE) {
         backdrop->priv->pix = xfce_backdrop_generate_canvas(backdrop);
         g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_READY], 0);
         return;
     }
 
-    file = g_file_new_for_path(backdrop->priv->image_path);
-    image_data = g_new0(XfceBackdropImageData, 1);
+    /* If we're trying to display an image, attempt to use the one the user
+     * set. If there's none set at all, fall back to our default */
+    if(backdrop->priv->image_path != NULL)
+        image_path = backdrop->priv->image_path;
+    else
+        image_path = DEFAULT_BACKDROP;
+
+    file = g_file_new_for_path(image_path);
 
+    image_data = g_new0(XfceBackdropImageData, 1);
     backdrop->priv->image_data = image_data;
 
     image_data->backdrop = backdrop;
@@ -937,6 +983,11 @@ xfce_backdrop_loader_size_prepared_cb(GdkPixbufLoader 
*loader,
 
     TRACE("entering");
 
+    if(backdrop->priv->image_style == XFCE_BACKDROP_IMAGE_INVALID) {
+        g_warning("Invalid image style, setting to 
XFCE_BACKDROP_IMAGE_STRETCHED");
+        backdrop->priv->image_style = XFCE_BACKDROP_IMAGE_STRETCHED;
+    }
+
     switch(backdrop->priv->image_style) {
         case XFCE_BACKDROP_IMAGE_CENTERED:
         case XFCE_BACKDROP_IMAGE_TILED:
diff --git a/src/xfce-backdrop.h b/src/xfce-backdrop.h
index 1aba049..8a46927 100644
--- a/src/xfce-backdrop.h
+++ b/src/xfce-backdrop.h
@@ -40,6 +40,7 @@ typedef struct _XfceBackdropPriv XfceBackdropPriv;
 
 typedef enum
 {
+    XFCE_BACKDROP_IMAGE_INVALID = -1,
     XFCE_BACKDROP_IMAGE_NONE = 0,
     XFCE_BACKDROP_IMAGE_CENTERED,
     XFCE_BACKDROP_IMAGE_TILED,
@@ -51,6 +52,7 @@ typedef enum
 
 typedef enum
 {
+    XFCE_BACKDROP_COLOR_INVALID = -1,
     XFCE_BACKDROP_COLOR_SOLID = 0,
     XFCE_BACKDROP_COLOR_HORIZ_GRADIENT,
     XFCE_BACKDROP_COLOR_VERT_GRADIENT,
diff --git a/src/xfce-desktop.c b/src/xfce-desktop.c
index aeebd57..4bd7040 100644
--- a/src/xfce-desktop.c
+++ b/src/xfce-desktop.c
@@ -326,8 +326,12 @@ create_bg_pixmap(GdkScreen *gscreen, gpointer user_data)
 
     g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), NULL);
 
-    if(desktop->priv->workspaces == NULL)
+    /* If the workspaces haven't been created yet there's no need to do the
+     * background pixmap */
+    if(desktop->priv->workspaces == NULL) {
+        DBG("exiting, desktop->priv->workspaces == NULL");
         return NULL;
+    }
 
     w = gdk_screen_get_width(gscreen);
     h = gdk_screen_get_height(gscreen);
@@ -603,7 +607,7 @@ workspace_changed_cb(WnckScreen *wnck_screen,
             current_backdrop = 
xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], i);
             new_backdrop = 
xfce_workspace_get_backdrop(desktop->priv->workspaces[new_workspace], i);
 
-            if(!xfce_backdrop_compare_backdrops(current_backdrop, 
new_backdrop)) {
+            if(!xfce_backdrop_compare_backdrops(current_backdrop, 
new_backdrop) || !desktop->priv->bg_pixmap) {
                 /* only update monitors that require it */
                 backdrop_changed_cb(new_backdrop, user_data);
             }
@@ -1007,17 +1011,15 @@ xfce_desktop_realize(GtkWidget *widget)
     wnck_screen = 
wnck_screen_get(gdk_screen_get_number(desktop->priv->gscreen));
     desktop->priv->wnck_screen = wnck_screen;
 
+    /* Watch for single workspace setting changes */
     xfconf_g_property_bind(desktop->priv->channel,
                            SINGLE_WORKSPACE_MODE, G_TYPE_BOOLEAN,
                            G_OBJECT(desktop), "single-workspace-mode");
-
     xfconf_g_property_bind(desktop->priv->channel,
                            SINGLE_WORKSPACE_NUMBER, G_TYPE_INT,
                            G_OBJECT(desktop), "single-workspace-number");
 
-    /* Start with an invalid workspace so it updates */
-    desktop->priv->current_workspace = -1;
-
+    /* watch for workspace changes */
     g_signal_connect(desktop->priv->wnck_screen, "active-workspace-changed",
                      G_CALLBACK(workspace_changed_cb), desktop);
     g_signal_connect(desktop->priv->wnck_screen, "workspace-created",
@@ -1025,8 +1027,7 @@ xfce_desktop_realize(GtkWidget *widget)
     g_signal_connect(desktop->priv->wnck_screen, "workspace-destroyed",
                      G_CALLBACK(workspace_destroyed_cb), desktop);
 
-    xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop);
-    
+    /* watch for screen changes */
     g_signal_connect(G_OBJECT(desktop->priv->gscreen), "size-changed",
             G_CALLBACK(screen_size_changed_cb), desktop);
     g_signal_connect(G_OBJECT(desktop->priv->gscreen), "composited-changed",
@@ -1495,8 +1496,10 @@ xfce_desktop_set_single_workspace_mode(XfceDesktop 
*desktop,
 
     DBG("single_workspace_mode now %s", single_workspace ? "TRUE" : "FALSE");
 
-    /* Fake a screen size changed to update the backdrop */
-    screen_size_changed_cb(desktop->priv->gscreen, desktop);
+    /* If the desktop has been realized then fake a screen size change to
+     * update the backdrop. There's no reason to if there's no desktop yet */
+    if(gtk_widget_get_realized(GTK_WIDGET(desktop)))
+        screen_size_changed_cb(desktop->priv->gscreen, desktop);
 }
 
 static void
diff --git a/src/xfce-workspace.c b/src/xfce-workspace.c
index 70796d8..936b960 100644
--- a/src/xfce-workspace.c
+++ b/src/xfce-workspace.c
@@ -314,6 +314,149 @@ xfce_workspace_get_property(GObject *object,
     }
 }
 
+/* Attempts to get the backdrop colors from the xfdesktop pre-4.11 format */
+static void
+xfce_workspace_migrate_backdrop_color_style(XfceWorkspace *workspace,
+                                            XfceBackdrop *backdrop,
+                                            guint monitor)
+{
+    XfconfChannel *channel = workspace->priv->channel;
+    char buf[1024];
+    gint pp_len;
+    GValue value = { 0, };
+
+    TRACE("entering");
+
+    /* Use the old property format */
+    g_snprintf(buf, sizeof(buf), "%smonitor%d/",
+               workspace->priv->property_prefix, monitor);
+    pp_len = strlen(buf);
+
+    /* Color style */
+    buf[pp_len] = 0;
+    g_strlcat(buf, "color-style", sizeof(buf));
+    xfconf_channel_get_property(channel, buf, &value);
+
+    if(G_VALUE_HOLDS_INT(&value)) {
+        xfce_backdrop_set_color_style(backdrop, g_value_get_int(&value));
+        g_value_unset(&value);
+    }
+
+    /* first color */
+    buf[pp_len] = 0;
+    g_strlcat(buf, "color1", sizeof(buf));
+    xfconf_channel_get_property(channel, buf, &value);
+
+    if(G_VALUE_HOLDS_BOXED(&value)) {
+        xfce_backdrop_set_first_color(backdrop, g_value_get_boxed(&value));
+        g_value_unset(&value);
+    }
+
+    /* second color */
+    buf[pp_len] = 0;
+    g_strlcat(buf, "color2", sizeof(buf));
+    xfconf_channel_get_property(channel, buf, &value);
+
+    if(G_VALUE_HOLDS_BOXED(&value)) {
+        xfce_backdrop_set_second_color(backdrop, g_value_get_boxed(&value));
+        g_value_unset(&value);
+    }
+
+    /* Fallback to solid if nothing was set anywhere */
+    if(xfce_backdrop_get_color_style(backdrop) == XFCE_BACKDROP_COLOR_INVALID)
+        xfce_backdrop_set_color_style(backdrop, XFCE_BACKDROP_COLOR_SOLID);
+}
+
+/* Attempts to get the backdrop image from the xfdesktop pre-4.11 format */
+static void
+xfce_workspace_migrate_backdrop_image(XfceWorkspace *workspace,
+                                      XfceBackdrop *backdrop,
+                                      guint monitor)
+{
+    XfconfChannel *channel = workspace->priv->channel;
+    char buf[1024];
+    gint pp_len;
+    GValue value = { 0, };
+    const gchar *filename;
+
+    TRACE("entering");
+
+    /* Use the old property format */
+    g_snprintf(buf, sizeof(buf), "%smonitor%d/",
+               workspace->priv->property_prefix, monitor);
+    pp_len = strlen(buf);
+
+    /* Try the old backdrop */
+    buf[pp_len] = 0;
+    g_strlcat(buf, "image-path", sizeof(buf));
+    xfconf_channel_get_property(channel, buf, &value);
+
+    /* Either there was a backdrop to migrate from or we use the backdrop
+     * we provide as a default */
+    if(G_VALUE_HOLDS_STRING(&value))
+        filename = g_value_get_string(&value);
+    else
+        filename = DEFAULT_BACKDROP;
+
+    xfce_backdrop_set_image_filename(backdrop, filename);
+
+    if(G_VALUE_HOLDS_STRING(&value))
+        g_value_unset(&value);
+}
+
+/* Attempts to get the image style from the xfdesktop pre-4.11 format */
+static void
+xfce_workspace_migrate_backdrop_image_style(XfceWorkspace *workspace,
+                                            XfceBackdrop *backdrop,
+                                            guint monitor)
+{
+    XfconfChannel *channel = workspace->priv->channel;
+    char buf[1024];
+    gint pp_len;
+    GValue value = { 0, };
+
+    TRACE("entering");
+
+    /* Use the old property format */
+    g_snprintf(buf, sizeof(buf), "%smonitor%d/",
+               workspace->priv->property_prefix, monitor);
+    pp_len = strlen(buf);
+
+    /* show image */
+    buf[pp_len] = 0;
+    g_strlcat(buf, "image-show", sizeof(buf));
+    xfconf_channel_get_property(channel, buf, &value);
+
+    if(G_VALUE_HOLDS_BOOLEAN(&value)) {
+        gboolean show_image = g_value_get_boolean(&value);
+
+        /* if we aren't showing the image, set the style and exit the function
+         * so we don't set the style to something else */
+        if(!show_image) {
+             xfce_backdrop_set_image_style(backdrop, XFCE_BACKDROP_IMAGE_NONE);
+             g_value_unset(&value);
+             return;
+        }
+
+        g_value_unset(&value);
+    }
+
+    /* image style */
+    buf[pp_len] = 0;
+    g_strlcat(buf, "image-style", sizeof(buf));
+    xfconf_channel_get_property(channel, buf, &value);
+
+    if(G_VALUE_HOLDS_INT(&value)) {
+        XfceBackdropImageStyle style;
+        style = xfce_translate_image_styles(g_value_get_int(&value));
+        xfce_backdrop_set_image_style(backdrop, style);
+        g_value_unset(&value);
+    } else {
+    /* If no value was ever set default to stretched */
+    xfce_backdrop_set_image_style(backdrop, XFCE_BACKDROP_IMAGE_STRETCHED);
+    }
+}
+
 static void
 xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace,
                                          XfceBackdrop *backdrop,
@@ -378,6 +521,18 @@ xfce_workspace_connect_backdrop_settings(XfceWorkspace 
*workspace,
     xfconf_g_property_bind(channel, buf, G_TYPE_STRING,
                            G_OBJECT(backdrop), "image-filename");
 
+    /* If we didn't get a filename try to load one from a previous version */
+    if(xfce_backdrop_get_image_filename(backdrop) == NULL)
+        xfce_workspace_migrate_backdrop_image(workspace, backdrop, monitor);
+
+    /* If we didn't get a proper color style, attempt to get the old one */
+    if(xfce_backdrop_get_color_style(backdrop) == XFCE_BACKDROP_COLOR_INVALID)
+        xfce_workspace_migrate_backdrop_color_style(workspace, backdrop, 
monitor);
+
+    /* Same for image style, this also deals with 'Auto' */
+    if(xfce_backdrop_get_image_style(backdrop) == XFCE_BACKDROP_IMAGE_INVALID)
+        xfce_workspace_migrate_backdrop_image_style(workspace, backdrop, 
monitor);
+
     g_free(monitor_name);
 }
 
_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
https://mail.xfce.org/mailman/listinfo/xfce4-commits

Reply via email to