diff -bEru xfdesktop-4.7.2-orig/common/xfdesktop-common.c xfdesktop-4.7.2/common/xfdesktop-common.c --- xfdesktop-4.7.2-orig/common/xfdesktop-common.c 2010-11-04 20:18:00.000000000 +0100 +++ xfdesktop-4.7.2/common/xfdesktop-common.c 2010-11-08 19:19:24.000000000 +0100 @@ -253,6 +253,40 @@ return file; } +gchar * +xfdesktop_backdrop_list_choose_index(const gchar *filename, gint index, + GError **error) +{ + gchar **files, *file = NULL; + gint n_items = 0, i, chosen_item = 0; + + g_return_val_if_fail(filename && (!error || !*error), NULL); + + files = xfdesktop_backdrop_list_load(filename, &n_items, error); + if(!files) + return NULL; + if(!n_items) { + if(error) { + g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_FAILED, + _("Backdrop list file is not valid")); + } + g_strfreev(files); + return NULL; + } + + chosen_item = index%n_items; /* if requested index is too high, loop in the list */ + + file = files[chosen_item]; + /* don't use strfreev() and avoid an extra alloc */ + for(i = 0; files[i]; ++i) { + if(i != chosen_item) + g_free(files[i]); + } + g_free(files); + + return file; +} + static void pixbuf_loader_size_cb(GdkPixbufLoader *loader, gint width, gint height, gpointer user_data) diff -bEru xfdesktop-4.7.2-orig/common/xfdesktop-common.h xfdesktop-4.7.2/common/xfdesktop-common.h --- xfdesktop-4.7.2-orig/common/xfdesktop-common.h 2010-11-04 20:18:00.000000000 +0100 +++ xfdesktop-4.7.2/common/xfdesktop-common.h 2010-11-08 19:19:24.000000000 +0100 @@ -79,6 +79,8 @@ GError **error); gchar *xfdesktop_backdrop_list_choose_random(const gchar *filename, GError **error); +gchar *xfdesktop_backdrop_list_choose_index(const gchar *filename, gint index, + GError **error); gboolean xfdesktop_backdrop_list_is_valid(const gchar *filename); gboolean xfdesktop_image_file_is_valid(const gchar *filename); diff -bEru xfdesktop-4.7.2-orig/src/xfce-backdrop.c xfdesktop-4.7.2/src/xfce-backdrop.c --- xfdesktop-4.7.2-orig/src/xfce-backdrop.c 2010-11-04 20:18:00.000000000 +0100 +++ xfdesktop-4.7.2/src/xfce-backdrop.c 2010-11-11 13:21:03.000000000 +0100 @@ -676,7 +676,8 @@ * * Sets the image that should be used with the #XfceBackdrop. The image will * be composited on top of the color (or color gradient). To clear the image, - * use this call with a @filename argument of %NULL. + * use this call with a @filename argument of %NULL. To specify multiple images, + * which will be shown in each workspace, give here a backdrop list file. **/ void xfce_backdrop_set_image_filename(XfceBackdrop *backdrop, const gchar *filename) @@ -755,7 +756,7 @@ * Return value: A #GdkPixbuf. **/ GdkPixbuf * -xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) +xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop, gint image_index) { GdkPixbuf *final_image, *image = NULL, *tmp; gint i, j; @@ -768,7 +769,20 @@ g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), NULL); if(backdrop->priv->show_image && backdrop->priv->image_path) { + + /* Manage multiple images case */ + if( xfdesktop_backdrop_list_is_valid(backdrop->priv->image_path) ) { + gchar *backdrop_file; + GError *error = NULL; + + backdrop_file = xfdesktop_backdrop_list_choose_index(backdrop->priv->image_path, image_index, + &error); + image = gdk_pixbuf_new_from_file(backdrop_file, NULL); + } + else { image = gdk_pixbuf_new_from_file(backdrop->priv->image_path, NULL); + } + if(image) { iw = gdk_pixbuf_get_width(image); ih = gdk_pixbuf_get_height(image); diff -bEru xfdesktop-4.7.2-orig/src/xfce-backdrop.h xfdesktop-4.7.2/src/xfce-backdrop.h --- xfdesktop-4.7.2-orig/src/xfce-backdrop.h 2010-11-04 20:18:00.000000000 +0100 +++ xfdesktop-4.7.2/src/xfce-backdrop.h 2010-11-11 13:15:24.000000000 +0100 @@ -121,7 +121,7 @@ gdouble saturation); gdouble xfce_backdrop_get_saturation (XfceBackdrop *backdrop); -GdkPixbuf *xfce_backdrop_get_pixbuf (XfceBackdrop *backdrop); +GdkPixbuf *xfce_backdrop_get_pixbuf (XfceBackdrop *backdrop, gint image_index); G_END_DECLS diff -bEru xfdesktop-4.7.2-orig/src/xfce-desktop.c xfdesktop-4.7.2/src/xfce-desktop.c --- xfdesktop-4.7.2-orig/src/xfce-desktop.c 2010-11-04 20:18:00.000000000 +0100 +++ xfdesktop-4.7.2/src/xfce-desktop.c 2010-11-09 17:55:41.000000000 +0100 @@ -73,6 +73,7 @@ # endif #endif +#include #include #include @@ -96,6 +97,7 @@ XfceBackdrop **backdrops; gboolean xinerama_stretch; + gboolean multiple_backdrop_images; SessionLogoutFunc session_logout_func; @@ -126,6 +128,7 @@ PROP_ICON_FONT_SIZE, PROP_ICON_FONT_SIZE_SET, #endif + PROP_SEPARATE_BACKGROUNDS, }; @@ -310,6 +313,8 @@ GdkRectangle rect; guint i; gint monitor = -1; + WnckScreen *wnck_screen; + gint active_workspace_number = 0; TRACE("entering"); @@ -329,8 +334,13 @@ if(monitor == -1) return; + /* retrieve the current workspace number */ + wnck_screen = wnck_screen_get(gdk_screen_get_number(gscreen)); + wnck_screen_force_update (wnck_screen); + active_workspace_number = wnck_screen_get_workspace_index(wnck_screen, wnck_screen_get_active_workspace(wnck_screen)); /*TO CHECK*/ + /* create/get the composited backdrop pixmap */ - pix = xfce_backdrop_get_pixbuf(backdrop); + pix = xfce_backdrop_get_pixbuf(backdrop, active_workspace_number); if(!pix) return; @@ -352,14 +362,48 @@ gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y, rect.width, rect.height); + gchar *actual_backdrop_filename = NULL; + if( desktop->priv->multiple_backdrop_images ) + { + GError *error = NULL; + actual_backdrop_filename = xfdesktop_backdrop_list_choose_index(xfce_backdrop_get_image_filename(backdrop), active_workspace_number, + &error); + } + else + { + actual_backdrop_filename = g_strdup(xfce_backdrop_get_image_filename(backdrop)); + } set_imgfile_root_property(desktop, - xfce_backdrop_get_image_filename(backdrop), + actual_backdrop_filename, monitor); + g_free(actual_backdrop_filename); /* do this again so apps watching the root win notice the update */ set_real_root_window_pixmap(gscreen, pmap); } + +static void +xfce_desktop_active_workspace_changed(WnckScreen *screen, WnckWorkspace *previously_active_workspace, gpointer user_data) +{ + XfceDesktop *desktop = XFCE_DESKTOP(user_data); + g_return_if_fail(XFCE_IS_DESKTOP(desktop)); + + /* Simply do as if the backdrop image has changed */ + if(desktop->priv->multiple_backdrop_images) + { + /* special case for 1 backdrop to handle xinerama stretching */ + if(desktop->priv->xinerama_stretch) { + backdrop_changed_cb(desktop->priv->backdrops[0], desktop); + } else { + guint i; + for(i = 0; i < desktop->priv->nbackdrops; i++) { + backdrop_changed_cb(desktop->priv->backdrops[i], desktop); + } + } + } +} + static void screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data) { @@ -595,6 +639,14 @@ FALSE, XFDESKTOP_PARAM_FLAGS)); #endif + + g_object_class_install_property(gobject_class, PROP_SEPARATE_BACKGROUNDS, + g_param_spec_boolean("separate-backgrounds", + "separate backgrounds", + "separate backgrounds", + FALSE, + XFDESKTOP_PARAM_FLAGS)); + #undef XFDESKTOP_PARAM_FLAGS } @@ -656,6 +708,10 @@ break; #endif + case PROP_SEPARATE_BACKGROUNDS: + xfce_desktop_set_multiple_backdrop_images(desktop, + g_value_get_boolean(value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -693,6 +749,10 @@ break; #endif + case PROP_SEPARATE_BACKGROUNDS: + g_value_set_boolean(value, desktop->priv->multiple_backdrop_images); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -708,6 +768,7 @@ Window xid; GdkDisplay *gdpy; GdkWindow *groot; + WnckScreen *wnck_screen; TRACE("entering"); @@ -723,6 +784,13 @@ desktop); } + /* be warned if the user changes current workspace */ + wnck_screen = wnck_screen_get(gdk_screen_get_number(desktop->priv->gscreen)); + g_signal_connect(G_OBJECT(wnck_screen), + "active-workspace-changed", + G_CALLBACK(xfce_desktop_active_workspace_changed), + desktop); + /* chain up */ GTK_WIDGET_CLASS(xfce_desktop_parent_class)->realize(widget); @@ -963,6 +1031,11 @@ #undef ICONS_PREFIX #endif + g_strlcpy(buf, desktop->priv->property_prefix, sizeof(buf)); + g_strlcat(buf, "separate-backgrounds", sizeof(buf)); + xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, + G_OBJECT(desktop), "separate-backgrounds"); + xfce_desktop_thaw_updates(desktop); } @@ -995,7 +1068,7 @@ else filename = g_value_get_string(value); if(G_LIKELY(filename && *filename)) { - if(xfdesktop_backdrop_list_is_valid(filename)) { + if(!desktop->priv->multiple_backdrop_images && xfdesktop_backdrop_list_is_valid(filename)) { gchar *backdrop_file; GError *error = NULL; @@ -1148,6 +1221,32 @@ } void +xfce_desktop_set_multiple_backdrop_images(XfceDesktop *desktop, + gboolean multiple_images) +{ + g_return_if_fail(XFCE_IS_DESKTOP(desktop)); + + if(multiple_images == desktop->priv->multiple_backdrop_images) + return; + + desktop->priv->multiple_backdrop_images = multiple_images; + + /* Do as if the user just changed the monitors configuration */ + if(!desktop->priv->updates_frozen) + { + xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop); + } +} + +gboolean +xfce_desktop_get_multiple_backdrop_images(XfceDesktop *desktop) +{ + g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), FALSE); + return desktop->priv->multiple_backdrop_images; +} + + +void xfce_desktop_set_xinerama_stretch(XfceDesktop *desktop, gboolean stretch) { diff -bEru xfdesktop-4.7.2-orig/src/xfce-desktop.h xfdesktop-4.7.2/src/xfce-desktop.h --- xfdesktop-4.7.2-orig/src/xfce-desktop.h 2010-11-04 20:18:00.000000000 +0100 +++ xfdesktop-4.7.2/src/xfce-desktop.h 2010-11-09 08:15:10.000000000 +0100 @@ -86,6 +86,10 @@ gboolean stretch); gboolean xfce_desktop_get_xinerama_stretch(XfceDesktop *desktop); +void xfce_desktop_set_multiple_backdrop_images(XfceDesktop *desktop, + gboolean multiple_images); +gboolean xfce_desktop_get_multiple_backdrop_images(XfceDesktop *desktop); + void xfce_desktop_set_icon_style(XfceDesktop *desktop, XfceDesktopIconStyle style); XfceDesktopIconStyle xfce_desktop_get_icon_style(XfceDesktop *desktop);