[Xfce4-commits] <xfdesktop:eric/wallpaper-and-settings-improvements> Fixes for multi-monitor per-workspace wallpapers

Eric Koegel noreply at xfce.org
Sun Mar 3 06:46:03 CET 2013


Updating branch refs/heads/eric/wallpaper-and-settings-improvements
         to 3cec6972530e4e4af47dbb84358fa8fedcc00f82 (commit)
       from 8674fc7ea9e0acae40db69714be13054053ef44d (commit)

commit 3cec6972530e4e4af47dbb84358fa8fedcc00f82
Author: Eric Koegel <eric.koegel at gmail.com>
Date:   Tue Feb 26 10:50:20 2013 +0300

    Fixes for multi-monitor per-workspace wallpapers
    
    This fixes several issues with the per-workspace backdrop code,
    especially with multi-monitor setups. Selection mode in the settings
    app is set to browse to enforce an item is always selected. Also
    xfdesktop trys to avoid redrawing the wallpaper on a workspace
    change if the backdrops are identical. The --reload option works
    correctly again.

 settings/main.c                                    |  113 +++++++++++++-------
 .../xfdesktop-settings-appearance-frame-ui.glade   |    1 +
 src/xfce-backdrop.c                                |   58 ++++++++--
 src/xfce-backdrop.h                                |    3 +
 src/xfce-desktop.c                                 |  114 ++++++++------------
 src/xfce-workspace.c                               |   81 +++++++++-----
 6 files changed, 220 insertions(+), 150 deletions(-)

diff --git a/settings/main.c b/settings/main.c
index 441bcdc..1308b21 100644
--- a/settings/main.c
+++ b/settings/main.c
@@ -77,6 +77,8 @@
 #define DESKTOP_ICONS_SHOW_FILESYSTEM        "/desktop-icons/file-icons/show-filesystem"
 #define DESKTOP_ICONS_SHOW_REMOVABLE         "/desktop-icons/file-icons/show-removable"
 
+#define IMAGE_STLYE_SPANNING_SCREENS         6
+#define XFCE_BACKDROP_IMAGE_NONE             0
 
 typedef struct
 {
@@ -480,6 +482,8 @@ xfdesktop_settings_generate_per_workspace_binding_string(AppearancePanel *panel,
                               property);
     }
 
+    DBG("name %s", buf);
+
     return buf;
 }
 
@@ -660,6 +664,21 @@ cb_folder_selection_changed(GtkWidget *button,
 }
 
 static void
+cb_xfdesktop_combo_image_style_changed(GtkComboBox *combo,
+                                 gpointer user_data)
+{
+    AppearancePanel *panel = user_data;
+
+    TRACE("entering");
+
+    if(gtk_combo_box_get_active(combo) == XFCE_BACKDROP_IMAGE_NONE) {
+        gtk_widget_set_sensitive(panel->image_iconview, FALSE);
+    } else {
+        gtk_widget_set_sensitive(panel->image_iconview, TRUE);
+    }
+}
+
+static void
 cb_xfdesktop_combo_color_changed(GtkComboBox *combo,
                                  gpointer user_data)
 {
@@ -723,6 +742,8 @@ xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     } else {
         xfconf_g_property_bind(channel, buf, G_TYPE_INT,
                                G_OBJECT(panel->image_style_combo), "active");
+        /* determine if the iconview is sensitive */
+        cb_xfdesktop_combo_image_style_changed(GTK_COMBO_BOX(panel->image_style_combo), panel);
     }
     g_free(buf);
 
@@ -734,12 +755,15 @@ xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     } else {
         xfconf_g_property_bind(channel, buf, G_TYPE_INT,
                                G_OBJECT(panel->color_style_combo), "active");
+        /* update the color button sensitivity */
+        cb_xfdesktop_combo_color_changed(GTK_COMBO_BOX(panel->color_style_combo), panel);
     }
     g_free(buf);
 
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, "color1");
     if(remove_binding) {
         xfconf_g_property_unbind(panel->color1_btn_id);
+    } else {
         panel->color1_btn_id = xfconf_g_property_bind_gdkcolor(channel, buf,
                                                                G_OBJECT(panel->color1_btn),
                                                                "color");
@@ -756,9 +780,6 @@ xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     }
     g_free(buf);
 
-    cb_xfdesktop_combo_color_changed(GTK_COMBO_BOX(panel->color_style_combo),
-                                     panel);
-
     /* Cycle timer options */
     buf = xfdesktop_settings_generate_per_workspace_binding_string(panel, "backdrop-cycle-enable");
     if(remove_binding) {
@@ -792,8 +813,6 @@ xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel,
     }
     g_free(buf);
 
-    cb_xfdesktop_chk_cycle_backdrop_toggled(GTK_CHECK_BUTTON(panel->backdrop_cycle_chkbox),
-                                            panel);
 }
 
 static void
@@ -844,23 +863,24 @@ cb_update_background_tab(WnckWindow *wnck_window,
     panel->monitor = monitor_num;
     panel->monitor_name = gdk_screen_get_monitor_plug_name(screen, panel->monitor);
 
+    /* The first monitor has the option of doing the "spanning screens" style,
+     * but only if there's multiple monitors attached. Remove it in all other cases.
+     *
+     * Remove the spanning screens option before we potentially add it again
+     */
+    gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(panel->image_style_combo),
+                              IMAGE_STLYE_SPANNING_SCREENS);
+    if(panel->monitor == 0 && gdk_screen_get_n_monitors(screen) > 1) {
+        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(panel->image_style_combo),
+                                       _("Spanning screens"));
+    }
+
     /* connect the new bindings */
     xfdesktop_settings_background_tab_change_bindings(panel,
                                                       FALSE);
 
     xfdesktop_settings_update_iconview_frame_name(panel, wnck_workspace);
     xfdesktop_settings_update_iconview_folder(panel);
-
-    /* The first monitor has the option of doing the "spanning screens" style,
-     * but only if there's multiple monitors attached. Make it invisible
-     * in all other cases.
-     * Remove the spanning screens option before we potentially add it again
-     */
-    gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(panel->image_style_combo), 6);
-    if(panel->monitor == 0 && gdk_screen_get_n_monitors(screen) > 1) {
-        gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(panel->image_style_combo),
-                                       6, _("Spanning screens"));
-    }
 }
 
 static void
@@ -874,6 +894,7 @@ xfdesktop_settings_setup_image_iconview(AppearancePanel *panel)
                 "pixbuf-column", COL_PIX,
                 "item-width", PREVIEW_WIDTH,
                 "tooltip-column", COL_NAME,
+                "selection-mode", GTK_SELECTION_BROWSE,
                 NULL);
 
     g_signal_connect(G_OBJECT(iconview), "selection-changed",
@@ -883,7 +904,8 @@ xfdesktop_settings_setup_image_iconview(AppearancePanel *panel)
 static void
 xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml,
                                      XfconfChannel *channel,
-                                     GdkScreen *screen)
+                                     GdkScreen *screen,
+                                     gulong window_xid)
 {
     GtkWidget *appearance_container, *chk_custom_font_size,
               *spin_font_size, *w, *box, *spin_icon_size,
@@ -944,7 +966,10 @@ xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml,
     /* We have to force wnck to initialize */
     wnck_screen = wnck_screen_get(panel->screen);
     wnck_screen_force_update(wnck_screen);
-    wnck_window = wnck_window_get(GDK_WINDOW_XID(gtk_widget_get_window(appearance_container)));
+    wnck_window = wnck_window_get(window_xid);
+
+    if(wnck_window == NULL)
+        wnck_window = wnck_screen_get_active_window(wnck_screen);
 
     g_signal_connect(wnck_window, "geometry-changed",
                      G_CALLBACK(cb_update_background_tab), panel);
@@ -975,25 +1000,6 @@ xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml,
     gtk_table_attach_defaults(GTK_TABLE(appearance_container),
                              appearance_settings, 0,1,0,1);
 
-    panel->image_style_combo = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, "combo_style"));
-
-    panel->color_style_combo = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
-                                                                 "combo_colors"));
-
-    /* Pick the first entries so something shows up */
-    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->image_style_combo), 0);
-    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->color_style_combo), 0);
-
-    g_signal_connect(G_OBJECT(panel->color_style_combo), "changed",
-                     G_CALLBACK(cb_xfdesktop_combo_color_changed),
-                     panel);
-
-    panel->color1_btn = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
-                                                          "color1_btn"));
-
-    panel->color2_btn = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
-                                                          "color2_btn"));
-
     /* icon view area */
     panel->frame_image_list = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
                                                                 "frame_image_list"));
@@ -1012,6 +1018,30 @@ xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml,
     gtk_file_filter_add_pixbuf_formats(filter);
     gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(panel->btn_folder), filter);
 
+    /* Image and color style options */
+    panel->image_style_combo = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, "combo_style"));
+
+    panel->color_style_combo = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
+                                                                 "combo_colors"));
+
+    panel->color1_btn = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
+                                                          "color1_btn"));
+
+    panel->color2_btn = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
+                                                          "color2_btn"));
+
+    g_signal_connect(G_OBJECT(panel->image_style_combo), "changed",
+                     G_CALLBACK(cb_xfdesktop_combo_image_style_changed),
+                     panel);
+
+    g_signal_connect(G_OBJECT(panel->color_style_combo), "changed",
+                     G_CALLBACK(cb_xfdesktop_combo_color_changed),
+                     panel);
+
+    /* Pick the first entries so something shows up */
+    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->image_style_combo), 0);
+    gtk_combo_box_set_active(GTK_COMBO_BOX(panel->color_style_combo), 0);
+
     /* background cycle timer */
     panel->backdrop_cycle_chkbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
                                                                      "chk_cycle_backdrop"));
@@ -1094,6 +1124,7 @@ xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml,
                            "active");
 
     setup_special_icon_list(main_gxml, channel);
+    cb_update_background_tab(wnck_window, panel);
 }
 
 static void
@@ -1175,7 +1206,8 @@ main(int argc, char **argv)
                          G_CALLBACK(xfdesktop_settings_response), NULL);
         gtk_window_present(GTK_WINDOW (dialog));
         xfdesktop_settings_dialog_setup_tabs(gxml, channel,
-                                             gtk_widget_get_screen(dialog));
+                                             gtk_widget_get_screen(dialog),
+                                             GDK_WINDOW_XID(gtk_widget_get_window(dialog)));
 
         /* To prevent the settings dialog to be saved in the session */
         gdk_x11_set_sm_client_id("FAKE ID");
@@ -1188,14 +1220,15 @@ main(int argc, char **argv)
         gtk_widget_show(plug);
         g_signal_connect(G_OBJECT(plug), "delete-event",
                          G_CALLBACK(gtk_main_quit), NULL);
-        xfdesktop_settings_dialog_setup_tabs(gxml, channel,
-                                             gtk_widget_get_screen(plug));
 
         gdk_notify_startup_complete();
 
         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();
     }
diff --git a/settings/xfdesktop-settings-appearance-frame-ui.glade b/settings/xfdesktop-settings-appearance-frame-ui.glade
index 9a5ac56..ee8e334 100644
--- a/settings/xfdesktop-settings-appearance-frame-ui.glade
+++ b/settings/xfdesktop-settings-appearance-frame-ui.glade
@@ -117,6 +117,7 @@
                                   <item translatable="yes">Stretched</item>
                                   <item translatable="yes">Scaled</item>
                                   <item translatable="yes">Zoomed</item>
+                                  <item translatable="yes">Spanning Screens</item>
                                 </items>
                               </object>
                               <packing>
diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c
index 4b3a909..1a63426 100644
--- a/src/xfce-backdrop.c
+++ b/src/xfce-backdrop.c
@@ -296,13 +296,6 @@ xfce_backdrop_class_init(XfceBackdropClass *klass)
                                                         DEFAULT_BACKDROP,
                                                         XFDESKTOP_PARAM_FLAGS));
 
-    g_object_class_install_property(gobject_class, PROP_BRIGHTNESS,
-                                    g_param_spec_int("brightness",
-                                                     "brightness",
-                                                     "brightness",
-                                                     -128, 127, 0,
-                                                     XFDESKTOP_PARAM_FLAGS));
-
     g_object_class_install_property(gobject_class, PROP_BACKDROP_CYCLE_ENABLE,
                                     g_param_spec_boolean("backdrop-cycle-enable",
                                                          "backdrop-cycle-enable",
@@ -742,7 +735,9 @@ xfce_backdrop_timer(XfceBackdrop *backdrop)
 
     g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), FALSE);
 
-    g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CYCLE], 0);
+    /* Don't bother with trying to cycle a backdrop if we're not using images */
+    if(backdrop->priv->image_style != XFCE_BACKDROP_IMAGE_NONE)
+        g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CYCLE], 0);
 
     return TRUE;
 }
@@ -881,7 +876,8 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
     
     /*check if the file exists,
      *and if it doesn't then make the background the single colour*/
-    if(!g_file_test(backdrop->priv->image_path, G_FILE_TEST_EXISTS)) {
+    if(!g_file_test(backdrop->priv->image_path, G_FILE_TEST_EXISTS) ||
+       backdrop->priv->image_style == XFCE_BACKDROP_IMAGE_NONE) {
         if(backdrop->priv->brightness != 0)
             final_image = adjust_brightness(final_image, backdrop->priv->brightness);
         
@@ -926,6 +922,12 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
         case XFCE_BACKDROP_IMAGE_TILED:
             image = gdk_pixbuf_new_from_file(backdrop->priv->image_path, NULL);
             tmp = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, w, h);
+            /* Now that the image has been loaded, recalculate the image
+             * size because gdk_pixbuf_get_file_info doesn't always return
+             * the correct size */
+            iw = gdk_pixbuf_get_width(image);
+            ih = gdk_pixbuf_get_height(image);
+
             for(i = 0; (i * iw) < w; i++) {
                 for(j = 0; (j * ih) < h; j++) {
                     gint newx = iw * i, newy = ih * j;
@@ -935,7 +937,7 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
                         neww = w - newx;
                     if((newy + newh) > h)
                         newh = h - newy;
-                    
+
                     gdk_pixbuf_copy_area(image, 0, 0,
                             neww, newh, tmp, newx, newy);
                 }
@@ -947,7 +949,6 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
             break;
         
         case XFCE_BACKDROP_IMAGE_STRETCHED:
-        case XFCE_BACKDROP_IMAGE_SPANNING_SCREENS:
             image = gdk_pixbuf_new_from_file_at_scale(
                             backdrop->priv->image_path, w, h, FALSE, NULL);
             gdk_pixbuf_composite(image, final_image, 0, 0, w, h,
@@ -978,6 +979,7 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
             break;
         
         case XFCE_BACKDROP_IMAGE_ZOOMED:
+        case XFCE_BACKDROP_IMAGE_SPANNING_SCREENS:
             xscale = (gdouble)w / iw;
             yscale = (gdouble)h / ih;
             if(xscale < yscale) {
@@ -1009,3 +1011,37 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
     
     return final_image;
 }
+
+/* returns TRUE if they have identical settings. */
+gboolean xfce_backdrop_compare_backdrops(XfceBackdrop *backdrop_a,
+                                         XfceBackdrop *backdrop_b)
+{
+    if(g_strcmp0(backdrop_a->priv->image_path, backdrop_b->priv->image_path) != 0) {
+        DBG("filename different");
+        return FALSE;
+    }
+
+    if(backdrop_a->priv->image_style != backdrop_b->priv->image_style) {
+        DBG("image_style different");
+        return FALSE;
+    }
+
+    if(backdrop_a->priv->color_style != backdrop_b->priv->color_style) {
+        DBG("color_style different");
+        return FALSE;
+    }
+
+    if(!gdk_color_equal(&backdrop_a->priv->color1, &backdrop_b->priv->color1) ||
+       !gdk_color_equal(&backdrop_a->priv->color2, &backdrop_b->priv->color2)) {
+        DBG("colors different");
+        return FALSE;
+    }
+
+    if(backdrop_a->priv->cycle_backdrop != backdrop_b->priv->cycle_backdrop ||
+       backdrop_a->priv->cycle_backdrop == TRUE) {
+        DBG("backdrop cycle different");
+        return FALSE;
+    }
+
+    return TRUE;
+}
diff --git a/src/xfce-backdrop.h b/src/xfce-backdrop.h
index 6c013c3..fbb01a9 100644
--- a/src/xfce-backdrop.h
+++ b/src/xfce-backdrop.h
@@ -130,6 +130,9 @@ gboolean xfce_backdrop_get_random_order  (XfceBackdrop *backdrop);
 
 GdkPixbuf *xfce_backdrop_get_pixbuf      (XfceBackdrop *backdrop);
 
+gboolean xfce_backdrop_compare_backdrops (XfceBackdrop *backdrop_a,
+                                          XfceBackdrop *backdrop_b);
+
 G_END_DECLS
 
 #endif
diff --git a/src/xfce-desktop.c b/src/xfce-desktop.c
index 95c30f6..6e12456 100644
--- a/src/xfce-desktop.c
+++ b/src/xfce-desktop.c
@@ -336,11 +336,6 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
     DBG("backdrop changed for workspace %d, monitor %d (%s)",
         current_workspace, monitor, gdk_screen_get_monitor_plug_name(gscreen, monitor));
 
-    /* create/get the composited backdrop pixmap */
-    pix = xfce_backdrop_get_pixbuf(backdrop);
-    if(!pix)
-        return;
-
     if(xfce_desktop_get_n_monitors(desktop) > 1
        && xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) {
         GdkRectangle monitor_rect;
@@ -360,10 +355,21 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
 
         rect.width = gdk_screen_get_width(gscreen);
         rect.height = gdk_screen_get_height(gscreen);
+        DBG("xinerama_stretch x %d, y %d, width %d, height %d",
+            rect.x, rect.y, rect.width, rect.height);
     } else {
         gdk_screen_get_monitor_geometry(gscreen, monitor, &rect);
+        DBG("monitor x %d, y %d, width %d, height %d",
+            rect.x, rect.y, rect.width, rect.height);
     }
 
+    xfce_backdrop_set_size(backdrop, rect.width, rect.height);
+
+    /* create/get the composited backdrop pixmap */
+    pix = xfce_backdrop_get_pixbuf(backdrop);
+    if(!pix)
+        return;
+
     cr = gdk_cairo_create(GDK_DRAWABLE(pmap));
     gdk_cairo_set_source_pixbuf(cr, pix, rect.x, rect.y);
     cairo_paint(cr);
@@ -415,17 +421,12 @@ screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data)
 
     /* special case for 1 backdrop to handle xinerama stretching */
     if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) {
-       xfce_backdrop_set_size(xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], 0), w, h);
        backdrop_changed_cb(xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], 0), desktop);
     } else {
-        GdkRectangle rect;
         gint i;
 
         for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
-            gdk_screen_get_monitor_geometry(gscreen, i, &rect);
             current_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], i);
-
-            xfce_backdrop_set_size(current_backdrop, rect.width, rect.height);
             backdrop_changed_cb(current_backdrop, desktop);
         }
     }
@@ -481,13 +482,37 @@ workspace_changed_cb(WnckScreen *wnck_screen,
 {
     XfceDesktop *desktop = XFCE_DESKTOP(user_data);
     WnckWorkspace *wnck_workspace = wnck_screen_get_active_workspace(wnck_screen);
+    gint current_workspace, new_workspace, i;
+    XfceBackdrop *current_backdrop, *new_backdrop;
 
     TRACE("entering");
 
-    desktop->priv->current_workspace = wnck_workspace_get_number(wnck_workspace);
+    current_workspace = desktop->priv->current_workspace;
+    new_workspace = wnck_workspace_get_number(wnck_workspace);
+    desktop->priv->current_workspace = new_workspace;
 
-    /* fake a screen size changed, so the background is properly set */
-    screen_size_changed_cb(desktop->priv->gscreen, user_data);
+    /* special case for the spanning screen option */
+    if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[new_workspace])) {
+        current_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], 0);
+        new_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[new_workspace], 0);
+
+        if(!xfce_backdrop_compare_backdrops(current_backdrop, new_backdrop)) {
+            backdrop_changed_cb(new_backdrop, user_data);
+            return;
+        }
+    }
+
+    /* We want to compare the current workspace backdrops with the new one
+     * and see if we can avoid changing them if they are the same image/style */
+    for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
+        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)) {
+            /* only update monitors that require it */
+            backdrop_changed_cb(new_backdrop, user_data);
+        }
+    }
 }
 
 static void
@@ -1088,46 +1113,6 @@ xfce_desktop_connect_settings(XfceDesktop *desktop)
     xfce_desktop_thaw_updates(desktop);
 }
 
-static void
-xfce_desktop_image_filename_changed(XfconfChannel *channel,
-                                    const gchar *property,
-                                    const GValue *value,
-                                    gpointer user_data)
-{
-    XfceDesktop *desktop = user_data;
-    gchar *p;
-    const gchar *filename;
-    gint monitor, current_workspace;
-    XfceBackdrop *backdrop;
-
-    TRACE("entering");
-
-    p = strstr(property, "/monitor");
-    if(!p)
-        return;
-
-    monitor = atoi(p + 8);
-    if(monitor < 0 || monitor >= xfce_desktop_get_n_monitors(desktop))
-        return;
-
-    current_workspace = desktop->priv->current_workspace;
-
-    if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])
-       && monitor != 0)
-        return;
-
-    backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace],
-                                           monitor);
-
-    if(!G_VALUE_HOLDS_STRING(value))
-        filename = DEFAULT_BACKDROP;
-    else
-        filename = g_value_get_string(value);
-
-    if(G_LIKELY(filename && *filename))
-        xfce_backdrop_set_image_filename(backdrop, filename);
-}
-
 static gint
 xfce_desktop_get_current_workspace(XfceDesktop *desktop)
 {
@@ -1394,8 +1379,7 @@ xfce_desktop_popup_secondary_root_menu(XfceDesktop *desktop,
 void
 xfce_desktop_refresh(XfceDesktop *desktop)
 {
-    gchar buf[256];
-    gint i, max, current_workspace;
+    gint i, current_workspace;
 
     g_return_if_fail(XFCE_IS_DESKTOP(desktop));
 
@@ -1404,23 +1388,13 @@ xfce_desktop_refresh(XfceDesktop *desktop)
 
     current_workspace = desktop->priv->current_workspace;
 
-    /* reload image */
-    if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace]))
-        max = 1;
-    else
-        max = xfce_desktop_get_n_monitors(desktop);
-    for(i = 0; i < max; ++i) {
-        GValue val = { 0, };
-
-        g_snprintf(buf, sizeof(buf), "%smonitor%d/workspace%d/last-image",
-                   desktop->priv->property_prefix, i, current_workspace);
-        xfconf_channel_get_property(desktop->priv->channel, buf, &val);
+    /* reload backgrounds */
+    for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
+        XfceBackdrop *backdrop;
 
-        xfce_desktop_image_filename_changed(desktop->priv->channel, buf,
-                                            &val, desktop);
+        backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], i);
 
-        if(G_VALUE_TYPE(&val))
-            g_value_unset(&val);
+        backdrop_changed_cb(backdrop, desktop);
     }
 
 #ifdef ENABLE_DESKTOP_ICONS
diff --git a/src/xfce-workspace.c b/src/xfce-workspace.c
index ba9f327..1775fe9 100644
--- a/src/xfce-workspace.c
+++ b/src/xfce-workspace.c
@@ -82,6 +82,7 @@ struct _XfceWorkspacePriv
 
     guint workspace_num;
     guint nbackdrops;
+    gboolean xinerama_stretch;
     XfceBackdrop **backdrops;
 };
 
@@ -155,7 +156,28 @@ backdrop_cycle_cb(XfceBackdrop *backdrop, gpointer user_data)
 static void
 backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
 {
+    XfceWorkspace *workspace = XFCE_WORKSPACE(user_data);
     TRACE("entering");
+
+    /* if we were spanning all the screens and we're not doing it anymore
+     * we need to update all the backdrops for this workspace */
+    if(workspace->priv->xinerama_stretch == TRUE &&
+       xfce_workspace_get_xinerama_stretch(workspace) == FALSE) {
+        guint i;
+
+        for(i = 0; i < workspace->priv->nbackdrops; ++i) {
+            /* skip the current backdrop, we'll get it last */
+            if(workspace->priv->backdrops[i] != backdrop) {
+                g_signal_emit(G_OBJECT(user_data),
+                              signals[WORKSPACE_BACKDROP_CHANGED],
+                              0,
+                              workspace->priv->backdrops[i]);
+            }
+        }
+    }
+
+    workspace->priv->xinerama_stretch = xfce_workspace_get_xinerama_stretch(workspace);
+
     /* Propagate it up */
     g_signal_emit(G_OBJECT(user_data), signals[WORKSPACE_BACKDROP_CHANGED], 0, backdrop);
 }
@@ -200,36 +222,35 @@ xfce_workspace_monitors_changed(XfceWorkspace *workspace,
     } else {
         /* We need one backdrop per monitor */
         guint n_monitors = gdk_screen_get_n_monitors(gscreen);
-
-        if(n_monitors < workspace->priv->nbackdrops) {
-            for(i = n_monitors; i < workspace->priv->nbackdrops; ++i)
-                g_object_unref(G_OBJECT(workspace->priv->backdrops[i]));
-        }
-
-        if(n_monitors != workspace->priv->nbackdrops) {
-            workspace->priv->backdrops = g_realloc(workspace->priv->backdrops,
-                                                 sizeof(XfceBackdrop *) * n_monitors);
-            if(n_monitors > workspace->priv->nbackdrops) {
-                GdkVisual *vis = gdk_screen_get_rgba_visual(gscreen);
-                if(vis == NULL)
-                    vis = gdk_screen_get_system_visual(gscreen);
-
-                for(i = workspace->priv->nbackdrops; i < n_monitors; ++i) {
-                    workspace->priv->backdrops[i] = xfce_backdrop_new(vis);
-                    xfce_workspace_connect_backdrop_settings(workspace,
-                                                           workspace->priv->backdrops[i],
-                                                           i);
-                    g_signal_connect(G_OBJECT(workspace->priv->backdrops[0]),
-                                     "changed",
-                                     G_CALLBACK(backdrop_changed_cb), workspace);
-                    g_signal_connect(G_OBJECT(workspace->priv->backdrops[i]),
-                                     "cycle",
-                                     G_CALLBACK(backdrop_cycle_cb),
-                                     workspace);
-                }
-            }
-            workspace->priv->nbackdrops = n_monitors;
+        GdkVisual *vis = gdk_screen_get_rgba_visual(gscreen);
+
+        if(vis == NULL)
+            vis = gdk_screen_get_system_visual(gscreen);
+
+        /* Remove all backdrops so that the correct montior is added/removed and
+         * things stay in the correct order */
+        for(i = 0; i < workspace->priv->nbackdrops; ++i)
+            g_object_unref(G_OBJECT(workspace->priv->backdrops[i]));
+
+        workspace->priv->backdrops = g_realloc(workspace->priv->backdrops,
+                                               sizeof(XfceBackdrop *) * n_monitors);
+
+        for(i = 0; i < n_monitors; ++i) {
+            DBG("Adding workspace %d backdrop %d", workspace->priv->workspace_num, i);
+
+            workspace->priv->backdrops[i] = xfce_backdrop_new(vis);
+            xfce_workspace_connect_backdrop_settings(workspace,
+                                                   workspace->priv->backdrops[i],
+                                                   i);
+            g_signal_connect(G_OBJECT(workspace->priv->backdrops[i]),
+                             "changed",
+                             G_CALLBACK(backdrop_changed_cb), workspace);
+            g_signal_connect(G_OBJECT(workspace->priv->backdrops[i]),
+                             "cycle",
+                             G_CALLBACK(backdrop_cycle_cb),
+                             workspace);
         }
+        workspace->priv->nbackdrops = n_monitors;
     }
 }
 
@@ -321,6 +342,8 @@ xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace,
     }
     pp_len = strlen(buf);
 
+    DBG("prefix string: %s", buf);
+
     g_strlcat(buf, "color-style", sizeof(buf));
     xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_COLOR_STYLE,
                            G_OBJECT(backdrop), "color-style");


More information about the Xfce4-commits mailing list