summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Koegel <eric.koegel@gmail.com>2013-08-04 11:33:51 +0300
committerEric Koegel <eric.koegel@gmail.com>2013-08-04 11:33:51 +0300
commitbf859f1caef83338e4c5c5725b55009abe68457d (patch)
treef72e5d235f50881db335c18bde83d7790c9804cc
parentb54644715e6ff06af40559f2de9f7f4c5028e3ba (diff)
parent799811c5b53c53552067af5418f2ae7b7ceddff9 (diff)
downloadxfdesktop-bf859f1caef83338e4c5c5725b55009abe68457d.tar.gz
Merge branch 'eric/wallpaper-and-settings-improvements'
Conflicts: src/xfce-backdrop.c Removed brightness code that was causing the conflict and isn't used anymore.
-rw-r--r--common/xfdesktop-common.c61
-rw-r--r--common/xfdesktop-common.h5
-rw-r--r--common/xfdesktop-thumbnailer.c49
-rw-r--r--common/xfdesktop-thumbnailer.h3
-rw-r--r--settings/main.c820
-rw-r--r--settings/xfdesktop-settings-appearance-frame-ui.glade488
-rw-r--r--settings/xfdesktop-settings-ui.glade4
-rw-r--r--src/xfce-backdrop.c210
-rw-r--r--src/xfce-backdrop.h8
-rw-r--r--src/xfce-desktop.c344
-rw-r--r--src/xfce-workspace.c180
-rw-r--r--src/xfdesktop-file-icon-manager.c116
12 files changed, 1458 insertions, 830 deletions
diff --git a/common/xfdesktop-common.c b/common/xfdesktop-common.c
index 344611ac..755e273b 100644
--- a/common/xfdesktop-common.c
+++ b/common/xfdesktop-common.c
@@ -188,13 +188,70 @@ xfdesktop_backdrop_choose_random(const gchar *filename)
return file;
}
+gchar *
+xfdesktop_get_file_mimetype(const gchar *file)
+{
+ GFile *temp_file;
+ GFileInfo *file_info;
+ gchar *mime_type = NULL;
+
+ g_return_val_if_fail(file != NULL, NULL);
+
+ temp_file = g_file_new_for_path(file);
+
+ g_return_val_if_fail(temp_file != NULL, NULL);
+
+ file_info = g_file_query_info(temp_file,
+ "standard::content-type",
+ 0,
+ NULL,
+ NULL);
+
+ if(file_info != NULL) {
+ mime_type = g_strdup(g_file_info_get_content_type(file_info));
+
+ g_object_unref(file_info);
+ }
+
+ g_object_unref(temp_file);
+
+ return mime_type;
+}
+
gboolean
xfdesktop_image_file_is_valid(const gchar *filename)
{
+ static GSList *pixbuf_formats = NULL;
+ GSList *l;
+ gboolean image_valid = FALSE;
+ gchar *file_mimetype;
+
g_return_val_if_fail(filename, FALSE);
- /* if gdk can get pixbuf info from the file then it's an image file */
- return (gdk_pixbuf_get_file_info(filename, NULL, NULL) == NULL ? FALSE : TRUE);
+ if(pixbuf_formats == NULL) {
+ pixbuf_formats = gdk_pixbuf_get_formats();
+ }
+
+ file_mimetype = xfdesktop_get_file_mimetype(filename);
+
+ if(file_mimetype == NULL)
+ return FALSE;
+
+ /* Every pixbuf format has a list of mime types we can compare against */
+ for(l = pixbuf_formats; l != NULL && image_valid == FALSE; l = g_slist_next(l)) {
+ gint i;
+ gchar ** mimetypes = gdk_pixbuf_format_get_mime_types(l->data);
+
+ for(i = 0; mimetypes[i] != NULL && image_valid == FALSE; i++) {
+ if(g_strcmp0(file_mimetype, mimetypes[i]) == 0)
+ image_valid = TRUE;
+ }
+ g_strfreev(mimetypes);
+ }
+
+ g_free(file_mimetype);
+
+ return image_valid;
}
gboolean
diff --git a/common/xfdesktop-common.h b/common/xfdesktop-common.h
index 7c7570d0..b34d7b53 100644
--- a/common/xfdesktop-common.h
+++ b/common/xfdesktop-common.h
@@ -49,6 +49,9 @@
#define ARRANGE_MESSAGE "arrange"
#define QUIT_MESSAGE "quit"
+#define SINGLE_WORKSPACE_MODE "/backdrop/single-workspace-mode"
+#define SINGLE_WORKSPACE_NUMBER "/backdrop/single-workspace-number"
+
/**
* File information namespaces queried for #GFileInfo objects.
*/
@@ -76,6 +79,8 @@ gchar *xfdesktop_backdrop_choose_random(const gchar *filename);
gboolean xfdesktop_image_file_is_valid(const gchar *filename);
+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);
diff --git a/common/xfdesktop-thumbnailer.c b/common/xfdesktop-thumbnailer.c
index 8f39fe9a..2c735df6 100644
--- a/common/xfdesktop-thumbnailer.c
+++ b/common/xfdesktop-thumbnailer.c
@@ -41,6 +41,7 @@
#include <libxfce4util/libxfce4util.h>
#include "xfdesktop-thumbnailer.h"
#include "xfdesktop-marshal.h"
+#include "xfdesktop-common.h"
static void xfdesktop_thumbnailer_init(GObject *);
static void xfdesktop_thumbnailer_class_init(GObjectClass *);
@@ -257,34 +258,14 @@ xfdesktop_thumbnailer_new(void)
return thumbnailer_object;
}
-static gchar *
-xfdesktop_get_file_mimetype(gchar *file)
+gboolean xfdesktop_thumbnailer_service_available(XfdesktopThumbnailer *thumbnailer)
{
- GFile *temp_file;
- GFileInfo *file_info;
- gchar *mime_type = NULL;
-
- g_return_val_if_fail(file != NULL, NULL);
-
- temp_file = g_file_new_for_path(file);
-
- g_return_val_if_fail(temp_file != NULL, NULL);
-
- file_info = g_file_query_info(temp_file,
- "standard::content-type",
- 0,
- NULL,
- NULL);
-
- if(file_info != NULL) {
- mime_type = g_strdup(g_file_info_get_content_type(file_info));
+ g_return_val_if_fail(XFDESKTOP_IS_THUMBNAILER(thumbnailer), FALSE);
- g_object_unref(file_info);
- }
+ if(thumbnailer->priv->proxy == NULL)
+ return FALSE;
- g_object_unref(temp_file);
-
- return mime_type;
+ return TRUE;
}
gboolean
@@ -370,6 +351,12 @@ xfdesktop_thumbnailer_queue_thumbnail(XfdesktopThumbnailer *thumbnailer,
return TRUE;
}
+static void
+xfdesktop_thumbnailer_dequeue_foreach(gpointer data, gpointer user_data)
+{
+ xfdesktop_thumbnailer_dequeue_thumbnail(user_data, data);
+}
+
/**
* xfdesktop_thumbnailer_dequeue_thumbnail:
*
@@ -402,9 +389,8 @@ xfdesktop_thumbnailer_dequeue_thumbnail(XfdesktopThumbnailer *thumbnailer,
}
if(g_slist_find(thumbnailer->priv->queue, file) != NULL) {
- thumbnailer->priv->queue = g_slist_remove_all(
- thumbnailer->priv->queue,
- file);
+ thumbnailer->priv->queue = g_slist_remove_all(thumbnailer->priv->queue,
+ file);
}
thumbnailer->priv->request_timer_id = g_timeout_add_full(
@@ -415,6 +401,13 @@ xfdesktop_thumbnailer_dequeue_thumbnail(XfdesktopThumbnailer *thumbnailer,
NULL);
}
+void xfdesktop_thumbnailer_dequeue_all_thumbnails(XfdesktopThumbnailer *thumbnailer)
+{
+ g_return_if_fail(XFDESKTOP_IS_THUMBNAILER(thumbnailer));
+
+ g_slist_foreach(thumbnailer->priv->queue, (GFunc)xfdesktop_thumbnailer_dequeue_foreach, thumbnailer);
+}
+
static gboolean
xfdesktop_thumbnailer_queue_request_timer(XfdesktopThumbnailer *thumbnailer)
{
diff --git a/common/xfdesktop-thumbnailer.h b/common/xfdesktop-thumbnailer.h
index 842f1555..c7ea4c56 100644
--- a/common/xfdesktop-thumbnailer.h
+++ b/common/xfdesktop-thumbnailer.h
@@ -60,6 +60,8 @@ XfdesktopThumbnailer * xfdesktop_thumbnailer_new(void);
GType xfdesktop_thumbnailer_get_type(void);
+gboolean xfdesktop_thumbnailer_service_available(XfdesktopThumbnailer *thumbnailer);
+
gboolean xfdesktop_thumbnailer_is_supported(XfdesktopThumbnailer *thumbnailer,
gchar *file);
@@ -67,6 +69,7 @@ gboolean xfdesktop_thumbnailer_queue_thumbnail(XfdesktopThumbnailer *thumbnailer
gchar *file);
void xfdesktop_thumbnailer_dequeue_thumbnail(XfdesktopThumbnailer *thumbnailer,
gchar *file);
+void xfdesktop_thumbnailer_dequeue_all_thumbnails(XfdesktopThumbnailer *thumbnailer);
void xfdesktop_thumbnailer_delete_thumbnail(XfdesktopThumbnailer *thumbnailer,
gchar *src_file);
diff --git a/settings/main.c b/settings/main.c
index 441bcdc3..675809c3 100644
--- a/settings/main.c
+++ b/settings/main.c
@@ -50,12 +50,12 @@
#include <libwnck/libwnck.h>
#include "xfdesktop-common.h"
+#include "xfdesktop-thumbnailer.h"
#include "xfdesktop-settings-ui.h"
#include "xfdesktop-settings-appearance-frame-ui.h"
-#define PREVIEW_HEIGHT 48
-#define MAX_ASPECT_RATIO 3.0f
-#define PREVIEW_WIDTH 128
+#define PREVIEW_HEIGHT 96
+#define MAX_ASPECT_RATIO 1.5f
#define SHOW_DESKTOP_MENU_PROP "/desktop-menu/show"
#define DESKTOP_MENU_SHOW_ICONS_PROP "/desktop-menu/show-icons"
@@ -77,6 +77,15 @@
#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
+{
+ GtkTreeModel *model;
+ GtkTreeIter *iter;
+} PreviewData;
typedef struct
{
@@ -87,9 +96,12 @@ typedef struct
gchar *monitor_name;
gulong image_list_loaded:1;
+ WnckWindow *wnck_window;
+
GtkWidget *frame_image_list;
GtkWidget *image_iconview;
GtkWidget *btn_folder;
+ GtkWidget *chk_apply_to_all;
GtkWidget *image_style_combo;
GtkWidget *color_style_combo;
GtkWidget *color1_btn;
@@ -103,14 +115,32 @@ typedef struct
GtkWidget *random_backdrop_order_chkbox;
GThread *preview_thread;
+ GAsyncQueue *preview_queue;
+
+ XfdesktopThumbnailer *thumbnailer;
+
+ GFile *selected_folder;
+ GCancellable *cancel_enumeration;
+ guint add_dir_idle_id;
} AppearancePanel;
+typedef struct
+{
+ GFileEnumerator *file_enumerator;
+ GtkListStore *ls;
+ GtkTreeIter *selected_iter;
+ gchar *last_image;
+ gchar *file_path;
+ AppearancePanel *panel;
+} AddDirData;
+
enum
{
COL_PIX = 0,
COL_NAME,
COL_FILENAME,
+ COL_THUMBNAIL,
COL_COLLATE_KEY,
N_COLS,
};
@@ -124,22 +154,33 @@ enum
N_ICON_COLS,
};
+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);
+
-/* assumes gdk lock is held on function enter, and should be held
- * on function exit */
static void
xfdesktop_settings_do_single_preview(GtkTreeModel *model,
GtkTreeIter *iter)
{
- gchar *name = NULL, *new_name = NULL, *filename = NULL;
+ gchar *filename = NULL, *thumbnail = NULL;
GdkPixbuf *pix, *pix_scaled = NULL;
+ GDK_THREADS_ENTER ();
gtk_tree_model_get(model, iter,
- COL_NAME, &name,
COL_FILENAME, &filename,
+ COL_THUMBNAIL, &thumbnail,
-1);
+ GDK_THREADS_LEAVE ();
+
+ if(thumbnail == NULL) {
+ pix = gdk_pixbuf_new_from_file(filename, NULL);
+ } else {
+ pix = gdk_pixbuf_new_from_file(thumbnail, NULL);
+ g_free(thumbnail);
+ }
- pix = gdk_pixbuf_new_from_file(filename, NULL);
g_free(filename);
if(pix) {
gint width, height;
@@ -147,10 +188,6 @@ xfdesktop_settings_do_single_preview(GtkTreeModel *model,
width = gdk_pixbuf_get_width(pix);
height = gdk_pixbuf_get_height(pix);
- /* no need to escape markup; it's already done for us */
- new_name = g_strdup_printf(_("%s\n<i>Size: %dx%d</i>"),
- name, width, height);
-
aspect = (gdouble)width / height;
/* Keep the aspect ratio sensible otherwise the treeview looks bad */
@@ -165,57 +202,132 @@ xfdesktop_settings_do_single_preview(GtkTreeModel *model,
g_object_unref(G_OBJECT(pix));
}
- g_free(name);
-
- if(new_name) {
- gtk_list_store_set(GTK_LIST_STORE(model), iter,
- COL_NAME, new_name,
- -1);
- g_free(new_name);
- }
if(pix_scaled) {
+ GDK_THREADS_ENTER ();
gtk_list_store_set(GTK_LIST_STORE(model), iter,
COL_PIX, pix_scaled,
-1);
+ GDK_THREADS_LEAVE ();
g_object_unref(G_OBJECT(pix_scaled));
}
}
+static void
+xfdesktop_settings_free_pdata(gpointer data)
+{
+ PreviewData *pdata = data;
+ g_object_unref(G_OBJECT(pdata->model));
+ gtk_tree_iter_free(pdata->iter);
+ g_free(pdata);
+}
+
static gpointer
-xfdesktop_settings_create_all_previews(gpointer data)
+xfdesktop_settings_create_previews(gpointer data)
{
- GtkTreeModel *model = data;
- GtkTreeView *tree_view;
- GtkTreeIter iter;
+ AppearancePanel *panel = data;
- GDK_THREADS_ENTER ();
+ while(panel->preview_queue != NULL) {
+ PreviewData *pdata = NULL;
- if(gtk_tree_model_get_iter_first(model, &iter)) {
- do {
- xfdesktop_settings_do_single_preview(model, &iter);
- } while(gtk_tree_model_iter_next(model, &iter));
+ /* Block and wait for another preview to create */
+ pdata = g_async_queue_pop(panel->preview_queue);
+
+ xfdesktop_settings_do_single_preview(pdata->model, pdata->iter);
+
+ xfdesktop_settings_free_pdata(pdata);
}
- /* if possible, scroll to the selected image */
- tree_view = g_object_get_data(G_OBJECT(model), "xfdesktop-tree-view");
- if(tree_view) {
- GtkTreeSelection *selection = gtk_tree_view_get_selection(tree_view);
+ return NULL;
+}
- if(gtk_tree_selection_get_mode(selection) != GTK_SELECTION_MULTIPLE
- && gtk_tree_selection_get_selected(selection, NULL, &iter))
+static void
+xfdesktop_settings_add_file_to_queue(AppearancePanel *panel, PreviewData *pdata)
+{
+ TRACE("entering");
+
+ g_return_if_fail(panel != NULL);
+ g_return_if_fail(pdata != NULL);
+
+ /* Create the queue if it doesn't exist */
+ if(panel->preview_queue == NULL) {
+ panel->preview_queue = g_async_queue_new_full(xfdesktop_settings_free_pdata);
+ }
+
+ g_async_queue_push(panel->preview_queue, pdata);
+
+ /* Create the thread if it doesn't exist */
+ if(panel->preview_thread == NULL) {
+ panel->preview_thread = g_thread_try_new("xfdesktop_settings_create_previews",
+ xfdesktop_settings_create_previews,
+ panel, NULL);
+ if(panel->preview_thread == NULL)
{
- GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
- gtk_tree_view_scroll_to_cell(tree_view, path, NULL, TRUE, 0.0, 0.0);
+ g_critical("Unable to create thread for image previews.");
+ /* Don't block but try to remove the data from the queue
+ * since we won't be creating previews */
+ if(g_async_queue_try_pop(panel->preview_queue))
+ xfdesktop_settings_free_pdata(pdata);
}
}
- g_object_set_data(G_OBJECT(model), "xfdesktop-tree-view", NULL);
+}
- GDK_THREADS_LEAVE ();
+static void
+cb_thumbnail_ready(XfdesktopThumbnailer *thumbnailer,
+ gchar *src_file, gchar *thumb_file,
+ gpointer user_data)
+{
+ AppearancePanel *panel = user_data;
+ GtkTreeModel *model = gtk_icon_view_get_model(GTK_ICON_VIEW(panel->image_iconview));
+ GtkTreeIter iter;
+ PreviewData *pdata = NULL;
- g_object_unref(G_OBJECT(model));
+ if(gtk_tree_model_get_iter_first(model, &iter)) {
+ do {
+ gchar *filename = NULL;
+ gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1);
- return NULL;
+ /* We're looking for the src_file */
+ if(g_strcmp0(filename, src_file) == 0) {
+ /* Add the thumb_file to it */
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter,
+ COL_THUMBNAIL, thumb_file, -1);
+
+ pdata = g_new0(PreviewData, 1);
+ pdata->model = g_object_ref(G_OBJECT(model));
+ pdata->iter = gtk_tree_iter_copy(&iter);
+
+ /* Create the preview image */
+ xfdesktop_settings_add_file_to_queue(panel, pdata);
+
+ g_free(filename);
+ return;
+ }
+
+ g_free(filename);
+ } while(gtk_tree_model_iter_next(model, &iter));
+ }
+}
+
+static void
+xfdesktop_settings_queue_preview(GtkTreeModel *model,
+ GtkTreeIter *iter,
+ AppearancePanel *panel)
+{
+ gchar *filename;
+
+ gtk_tree_model_get(model, iter, COL_FILENAME, &filename, -1);
+
+ /* Attempt to use the thumbnailer if possible */
+ if(!xfdesktop_thumbnailer_queue_thumbnail(panel->thumbnailer, filename)) {
+ /* Thumbnailing not possible, add it to the queue to be loaded manually */
+ PreviewData *pdata;
+ pdata = g_new0(PreviewData, 1);
+ pdata->model = g_object_ref(G_OBJECT(model));
+ pdata->iter = gtk_tree_iter_copy(iter);
+
+ xfdesktop_settings_add_file_to_queue(panel, pdata);
+ }
}
static void
@@ -332,7 +444,7 @@ image_list_compare(GtkTreeModel *model,
gchar *key_b = NULL;
gint ret;
- gtk_tree_model_get(model, b, COL_NAME, &key_b, -1);
+ gtk_tree_model_get(model, b, COL_COLLATE_KEY, &key_b, -1);
ret = g_strcmp0(a, key_b);
@@ -343,48 +455,60 @@ image_list_compare(GtkTreeModel *model,
static GtkTreeIter *
xfdesktop_settings_image_iconview_add(GtkTreeModel *model,
- const char *path)
+ const char *path,
+ GFileInfo *info,
+ AppearancePanel *panel)
{
gboolean added = FALSE, found = FALSE, valid = FALSE;
GtkTreeIter iter, search_iter;
- gchar *name = NULL, *name_utf8 = NULL, *name_markup = NULL;
- gchar *lower = NULL;
+ gchar *name = NULL, *name_utf8 = NULL, *name_markup = NULL, *size_string = NULL;
+ gchar *collate_key = NULL;
+ gint position = 0;
+ const gchar *content_type = g_file_info_get_content_type(info);
+ goffset file_size = g_file_info_get_size(info);
if(!xfdesktop_image_file_is_valid(path))
return NULL;
name = g_path_get_basename(path);
if(name) {
- name_utf8 = g_filename_to_utf8(name, strlen(name),
+ guint name_length = strlen(name);
+ name_utf8 = g_filename_to_utf8(name, name_length,
NULL, NULL, NULL);
if(name_utf8) {
- name_markup = g_markup_printf_escaped("<b>%s</b>",
- name_utf8);
+#if GLIB_CHECK_VERSION (2, 30, 0)
+ size_string = g_format_size(file_size);
+#else
+ size_string = g_format_size_for_display(file_size);
+#endif
- lower = g_utf8_strdown(name_utf8, -1);
+ /* Display the file name, file type, and file size in the tooltip. */
+ name_markup = g_markup_printf_escaped(_("<b>%s</b>\nType: %s\nSize: %s"),
+ name_utf8, content_type, size_string);
+
+ /* create a case sensitive collation key for sorting filenames like
+ * Thunar does */
+ collate_key = g_utf8_collate_key_for_filename(name, name_length);
/* Insert sorted */
valid = gtk_tree_model_get_iter_first(model, &search_iter);
while(valid && !found) {
- if(image_list_compare(model, name_markup, &search_iter) <= 0) {
+ if(image_list_compare(model, collate_key, &search_iter) <= 0) {
found = TRUE;
} else {
valid = gtk_tree_model_iter_next(model, &search_iter);
+ position++;
}
}
- if(!found) {
- gtk_list_store_append(GTK_LIST_STORE(model), &iter);
- } else {
- gtk_list_store_insert_before(GTK_LIST_STORE(model), &iter, &search_iter);
- }
-
-
- gtk_list_store_set(GTK_LIST_STORE(model), &iter,
- COL_NAME, name_markup,
- COL_FILENAME, path,
- COL_COLLATE_KEY, lower,
- -1);
+ gtk_list_store_insert_with_values(GTK_LIST_STORE(model),
+ &iter,
+ position,
+ COL_NAME, name_markup,
+ COL_FILENAME, path,
+ COL_COLLATE_KEY, collate_key,
+ -1);
+ xfdesktop_settings_queue_preview(model, &iter, panel);
added = TRUE;
}
@@ -393,7 +517,8 @@ xfdesktop_settings_image_iconview_add(GtkTreeModel *model,
g_free(name);
g_free(name_utf8);
g_free(name_markup);
- g_free(lower);
+ g_free(size_string);
+ g_free(collate_key);
if(added)
return gtk_tree_iter_copy(&iter);
@@ -401,40 +526,120 @@ xfdesktop_settings_image_iconview_add(GtkTreeModel *model,
return NULL;
}
-static GtkTreeIter *
-xfdesktop_image_list_add_dir(GtkListStore *ls,
- const char *path,
- const char *cur_image_file)
+static void
+cb_destroy_add_dir_enumeration(gpointer user_data)
{
- GDir *dir;
- gboolean needs_slash = TRUE;
- const gchar *file;
- GtkTreeIter *iter, *iter_ret = NULL;
- gchar buf[PATH_MAX];
-
- dir = g_dir_open(path, 0, 0);
- if(!dir)
- return NULL;
+ AddDirData *dir_data = user_data;
+ AppearancePanel *panel = dir_data->panel;
+
+ TRACE("entering");
+
+ g_free(dir_data->file_path);
+ g_free(dir_data->last_image);
+
+ if(G_IS_FILE_ENUMERATOR(dir_data->file_enumerator))
+ g_object_unref(dir_data->file_enumerator);
- if(path[strlen(path)-1] == '/')
- needs_slash = FALSE;
+ g_free(dir_data);
- while((file = g_dir_read_name(dir))) {
- g_snprintf(buf, sizeof(buf), needs_slash ? "%s/%s" : "%s%s",
- path, file);
+ if(panel->cancel_enumeration) {
+ g_object_unref(panel->cancel_enumeration);
+ panel->cancel_enumeration = NULL;
+ }
+}
+
+static gboolean
+xfdesktop_image_list_add_item(gpointer user_data)
+{
+ AddDirData *dir_data = user_data;
+ AppearancePanel *panel = dir_data->panel;
+ GFileInfo *info;
+ GtkTreeIter *iter;
- iter = xfdesktop_settings_image_iconview_add(GTK_TREE_MODEL(ls), buf);
+ /* If the enumeration gets canceled/destroyed return and
+ * cb_destroy_add_dir_enumeration will get called to clean up */
+ if(!G_IS_FILE_ENUMERATOR(dir_data->file_enumerator))
+ return FALSE;
+
+ /* Add one item to the icon view at a time so we don't block the UI */
+ if((info = g_file_enumerator_next_file(dir_data->file_enumerator, NULL, NULL))) {
+ const gchar *file_name = g_file_info_get_name(info);
+ gchar *buf = g_strconcat(dir_data->file_path, "/", file_name, NULL);
+
+ iter = xfdesktop_settings_image_iconview_add(GTK_TREE_MODEL(dir_data->ls), buf, info, panel);
if(iter) {
- if(cur_image_file && !iter_ret && !strcmp(buf, cur_image_file))
- iter_ret = iter;
- else
+ if(!dir_data->selected_iter &&
+ !strcmp(buf, dir_data->last_image))
+ {
+ dir_data->selected_iter = iter;
+ } else {
gtk_tree_iter_free(iter);
+ }
}
+
+ g_free(buf);
+ g_object_unref(info);
+
+ /* continue on the next idle callback so the user's events get priority */
+ return TRUE;
}
- g_dir_close(dir);
+ /* If we get here we're done enumerating files in the directory */
+
+ gtk_icon_view_set_model(GTK_ICON_VIEW(panel->image_iconview),
+ GTK_TREE_MODEL(dir_data->ls));
+
+ /* last_image is in the directory added then it should be selected */
+ if(dir_data->selected_iter) {
+ GtkTreePath *path;
+ path = gtk_tree_model_get_path(GTK_TREE_MODEL(dir_data->ls), dir_data->selected_iter);
+ if(path) {
+ gtk_icon_view_select_path(GTK_ICON_VIEW(panel->image_iconview), path);
+ gtk_tree_iter_free(dir_data->selected_iter);
+ gtk_tree_path_free(path);
+ }
+ }
+
+ /* cb_destroy_add_dir_enumeration will get called to clean up */
+ return FALSE;
+}
+
+static void
+xfdesktop_image_list_add_dir(GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ AppearancePanel *panel = user_data;
+ gchar *property;
+ AddDirData *dir_data = g_new0(AddDirData, 1);
+
+ TRACE("entering");
+
+ dir_data->panel = panel;
+
+ dir_data->ls = gtk_list_store_new(N_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ /* 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->file_path = g_file_get_path(panel->selected_folder);
+
+ dir_data->file_enumerator = g_file_enumerate_children_finish(panel->selected_folder,
+ res,
+ NULL);
+
+ /* Individual items are added in an idle callback so everything is more
+ * responsive */
+ panel->add_dir_idle_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
+ xfdesktop_image_list_add_item,
+ dir_data,
+ cb_destroy_add_dir_enumeration);
- return iter_ret;
+ g_free(property);
}
static void
@@ -447,16 +652,44 @@ xfdesktop_settings_update_iconview_frame_name(AppearancePanel *panel,
if(panel->monitor < 0 && panel->workspace < 0)
return;
+ if(wnck_workspace == NULL) {
+ WnckScreen *wnck_screen = wnck_window_get_screen(panel->wnck_window);
+ wnck_workspace = wnck_screen_get_active_workspace(wnck_screen);
+ }
+
workspace_name = g_strdup(wnck_workspace_get_name(wnck_workspace));
- if(panel->monitor_name) {
- g_snprintf(buf, sizeof(buf),
- _("Wallpaper for %s on Monitor %d (%s)"),
- workspace_name, panel->monitor, panel->monitor_name);
- } else
- g_snprintf(buf, sizeof(buf),
- _("Wallpaper for %s on Monitor %d"),
- workspace_name, panel->monitor);
+ 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))) {
+ /* Multi-monitor single workspace */
+ if(panel->monitor_name) {
+ g_snprintf(buf, sizeof(buf),
+ _("Wallpaper for Monitor %d (%s)"),
+ panel->monitor, panel->monitor_name);
+ } else {
+ g_snprintf(buf, sizeof(buf), _("Wallpaper for Monitor %d"), panel->monitor);
+ }
+ } else {
+ /* Multi-monitor per workspace wallpaper */
+ if(panel->monitor_name) {
+ g_snprintf(buf, sizeof(buf),
+ _("Wallpaper for %s on Monitor %d (%s)"),
+ workspace_name, panel->monitor, panel->monitor_name);
+ } else {
+ g_snprintf(buf, sizeof(buf),
+ _("Wallpaper for %s on Monitor %d"),
+ workspace_name, panel->monitor);
+ }
+ }
+ } else {
+ if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->chk_apply_to_all))) {
+ /* Single monitor and single workspace */
+ g_snprintf(buf, sizeof(buf), _("Wallpaper for my desktop"));
+ } else {
+ /* Single monitor and per workspace wallpaper */
+ g_snprintf(buf, sizeof(buf), _("Wallpaper for %s"), workspace_name);
+ }
+ }
gtk_frame_set_label(GTK_FRAME(panel->frame_image_list), buf);
@@ -480,6 +713,8 @@ xfdesktop_settings_generate_per_workspace_binding_string(AppearancePanel *panel,
property);
}
+ DBG("name %s", buf);
+
return buf;
}
@@ -528,11 +763,52 @@ cb_image_selection_changed(GtkIconView *icon_view,
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);
}
+static gint
+xfdesktop_settings_get_active_workspace(AppearancePanel *panel,
+ WnckWindow *wnck_window)
+{
+ WnckWorkspace *wnck_workspace;
+ gboolean single_workspace;
+ gint workspace_num, single_workspace_num;
+ WnckScreen *wnck_screen = wnck_window_get_screen(wnck_window);
+
+ wnck_workspace = wnck_window_get_workspace(wnck_window);
+
+ 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));
+ }
+
+
+ single_workspace = xfconf_channel_get_bool(panel->channel,
+ SINGLE_WORKSPACE_MODE,
+ TRUE);
+
+ /* If we're in single_workspace mode we need to return the workspace that
+ * it was set to, if that workspace exists, otherwise return the current
+ * workspace and turn off the single workspace mode */
+ if(single_workspace) {
+ single_workspace_num = xfconf_channel_get_int(panel->channel,
+ SINGLE_WORKSPACE_NUMBER,
+ 0);
+ if(single_workspace_num < wnck_screen_get_workspace_count(wnck_screen)) {
+ return single_workspace_num;
+ } else {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->chk_apply_to_all),
+ FALSE);
+ }
+ }
+
+ return workspace_num;
+}
+
static void
cb_xfdesktop_chk_custom_font_size_toggled(GtkCheckButton *button,
gpointer user_data)
@@ -602,61 +878,125 @@ cb_xfdesktop_spin_icon_size_changed(GtkSpinButton *button,
}
static void
+xfdesktop_settings_stop_image_loading(AppearancePanel *panel)
+{
+ /* stop any thumbnailing in progress */
+ xfdesktop_thumbnailer_dequeue_all_thumbnails(panel->thumbnailer);
+
+ /* Remove the previews in the message queue */
+ if(panel->preview_queue != NULL) {
+ while(g_async_queue_length(panel->preview_queue) > 0) {
+ gpointer data = g_async_queue_try_pop(panel->preview_queue);
+ if(data)
+ xfdesktop_settings_free_pdata(data);
+ }
+ }
+
+ /* Cancel any file enumeration that's running */
+ if(panel->cancel_enumeration != NULL) {
+ g_cancellable_cancel(panel->cancel_enumeration);
+ g_object_unref(panel->cancel_enumeration);
+ panel->cancel_enumeration = NULL;
+ }
+
+ /* Cancel the file enumeration for populating the icon view */
+ if(panel->add_dir_idle_id != 0) {
+ g_source_remove(panel->add_dir_idle_id);
+ panel->add_dir_idle_id = 0;
+ }
+}
+
+static void
+cb_xfdesktop_bnt_exit_clicked(GtkButton *button, gpointer user_data)
+{
+ AppearancePanel *panel = user_data;
+
+ xfdesktop_settings_stop_image_loading(panel);
+}
+
+static void
cb_folder_selection_changed(GtkWidget *button,
gpointer user_data)
{
AppearancePanel *panel = user_data;
gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(button));
- GtkListStore *ls;
- GtkTreeIter *iter;
- GtkTreePath *path;
- gchar *last_image, *property;
+ gchar *previous_filename = NULL;
TRACE("entering");
- ls = gtk_list_store_new(N_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING,
- G_TYPE_STRING, G_TYPE_STRING);
+ if(panel->selected_folder != NULL)
+ previous_filename = g_file_get_path(panel->selected_folder);
- property = xfdesktop_settings_generate_per_workspace_binding_string(panel, "last-image");
+ /* Check to see if the folder actually did change */
+ if(g_strcmp0(filename, previous_filename) == 0) {
+ DBG("filename %s, previous_filename %s. Nothing changed",
+ filename == NULL ? "NULL" : filename,
+ previous_filename == NULL ? "NULL" : previous_filename);
+ g_free(filename);
+ g_free(previous_filename);
+ return;
+ }
- last_image = xfconf_channel_get_string(panel->channel, property, NULL);
+ TRACE("folder changed to: %s", filename);
- if(last_image == NULL)
- last_image = DEFAULT_BACKDROP;
+ if(panel->selected_folder != NULL)
+ g_object_unref(panel->selected_folder);
- iter = xfdesktop_image_list_add_dir(ls, filename, last_image);
+ panel->selected_folder = g_file_new_for_path(filename);
- gtk_icon_view_set_model(GTK_ICON_VIEW(panel->image_iconview),
- GTK_TREE_MODEL(ls));
-
- /* last_image is in the directory added then it should be selected */
- if(iter) {
- path = gtk_tree_model_get_path(GTK_TREE_MODEL(ls), iter);
- if(path) {
- gtk_icon_view_select_path(GTK_ICON_VIEW(panel->image_iconview), path);
- gtk_tree_iter_free(iter);
- }
- }
+ /* Stop any previous loading since something changed */
+ xfdesktop_settings_stop_image_loading(panel);
- /* remove any preview threads that may still be running since we've probably
- * changed to a new monitor/workspace */
- if(panel->preview_thread != NULL) {
- g_thread_unref(panel->preview_thread);
- panel->preview_thread = NULL;
- }
+ panel->cancel_enumeration = g_cancellable_new();
- /* generate previews of each image -- the new thread will own
- * the reference on the list store, so let's not unref it here */
- panel->preview_thread = g_thread_try_new("xfdesktop_settings_create_all_previews",
- xfdesktop_settings_create_all_previews,
- ls, NULL);
+ g_file_enumerate_children_async(panel->selected_folder,
+ XFDESKTOP_FILE_INFO_NAMESPACE,
+ G_FILE_QUERY_INFO_NONE,
+ G_PRIORITY_DEFAULT,
+ panel->cancel_enumeration,
+ xfdesktop_image_list_add_dir,
+ panel);
- if(panel->preview_thread == NULL) {
- g_critical("Failed to spawn thread; backdrop previews will be unavailable.");
- g_object_unref(G_OBJECT(ls));
- }
+ g_free(filename);
+ g_free(previous_filename);
+}
- g_free(property);
+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) {
+ /* No wallpaper so set the iconview to insensitive so the user doesn't
+ * pick wallpapers that have no effect. Stop popping up tooltips for
+ * the now insensitive iconview and provide a tooltip explaining why
+ * the iconview is insensitive. */
+ gtk_widget_set_sensitive(panel->image_iconview, FALSE);
+ g_object_set(G_OBJECT(panel->image_iconview),
+ "tooltip-column", -1,
+ NULL);
+ gtk_widget_set_tooltip_text(panel->image_iconview,
+ _("Image selection is unavailable while the image style is set to None."));
+ } else {
+ gint tooltip_column;
+
+ /* We are expected to provide a wallpaper so make the iconview active.
+ * Additionally, if we were insensitive then we need to remove the
+ * global iconview tooltip and enable the individual tooltips again. */
+ gtk_widget_set_sensitive(panel->image_iconview, TRUE);
+ g_object_get(G_OBJECT(panel->image_iconview),
+ "tooltip-column", &tooltip_column,
+ NULL);
+ if(tooltip_column == -1) {
+ gtk_widget_set_tooltip_text(panel->image_iconview, NULL);
+ g_object_set(G_OBJECT(panel->image_iconview),
+ "tooltip-column", COL_NAME,
+ NULL);
+ }
+ }
}
static void
@@ -688,22 +1028,22 @@ cb_xfdesktop_combo_color_changed(GtkComboBox *combo,
static void
xfdesktop_settings_update_iconview_folder(AppearancePanel *panel)
{
- gchar *current_folder, *prop_last;
+ gchar *current_folder, *prop_last, *dirname;
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);
+ dirname = g_path_get_dirname(current_folder);
- current_folder = xfconf_channel_get_string(panel->channel, prop_last, NULL);
-
- if(current_folder == NULL)
- current_folder = g_strdup(DEFAULT_BACKDROP);
+ gtk_file_chooser_set_current_folder((GtkFileChooser*)panel->btn_folder, dirname);
- gtk_file_chooser_set_current_folder((GtkFileChooser*)panel->btn_folder,
- g_path_get_dirname(current_folder));
+ /* Workaround for a bug in GTK */
+ cb_folder_selection_changed(panel->btn_folder, panel);
g_free(current_folder);
g_free(prop_last);
+ g_free(dirname);
}
/* This function is to add or remove all the bindings for the background
@@ -723,6 +1063,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 +1076,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 +1101,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 +1134,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
@@ -810,21 +1150,24 @@ cb_update_background_tab(WnckWindow *wnck_window,
{
AppearancePanel *panel = user_data;
gint screen_num, monitor_num, workspace_num;
+ gchar *monitor_name = NULL;
WnckWorkspace *wnck_workspace = NULL;
GdkScreen *screen;
screen = gtk_widget_get_screen(panel->image_iconview);
wnck_workspace = wnck_window_get_workspace(wnck_window);
- workspace_num = wnck_workspace_get_number(wnck_workspace);
+ workspace_num = xfdesktop_settings_get_active_workspace(panel, wnck_window);
screen_num = gdk_screen_get_number(screen);
monitor_num = gdk_screen_get_monitor_at_window(screen,
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 == monitor_num) {
+ panel->monitor_name != NULL &&
+ g_strcmp0(panel->monitor_name, monitor_name) == 0) {
return;
}
@@ -844,23 +1187,75 @@ 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),
+ XFCE_BACKDROP_IMAGE_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
+cb_workspace_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);
+}
+
+static void
+cb_monitor_changed(GdkScreen *gscreen,
+ gpointer user_data)
+{
+ AppearancePanel *panel = user_data;
+
+ /* Update background because the monitor we're on may have changed */
+ cb_update_background_tab(panel->wnck_window, user_data);
+
+ /* Update the frame name because we may change from/to a single monitor */
+ xfdesktop_settings_update_iconview_frame_name(panel, wnck_window_get_workspace(panel->wnck_window));
+}
+
+static void
+cb_xfdesktop_chk_apply_to_all(GtkCheckButton *button,
+ gpointer user_data)
+{
+ AppearancePanel *panel = user_data;
+ gboolean active;
+ active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+
+ TRACE("entering");
+
+ xfconf_channel_set_bool(panel->channel,
+ SINGLE_WORKSPACE_MODE,
+ active);
+
+ if(active) {
+ xfconf_channel_set_int(panel->channel,
+ SINGLE_WORKSPACE_NUMBER,
+ panel->workspace);
+ } else {
+ cb_update_background_tab(panel->wnck_window, panel);
}
+
+ /* update the frame name to since we changed to/from single workspace mode */
+ xfdesktop_settings_update_iconview_frame_name(panel, wnck_window_get_workspace(panel->wnck_window));
}
static void
@@ -870,36 +1265,52 @@ xfdesktop_settings_setup_image_iconview(AppearancePanel *panel)
TRACE("entering");
+ panel->thumbnailer = xfdesktop_thumbnailer_new();
+
g_object_set(G_OBJECT(iconview),
"pixbuf-column", COL_PIX,
- "item-width", PREVIEW_WIDTH,
"tooltip-column", COL_NAME,
+ "selection-mode", GTK_SELECTION_BROWSE,
+ "column-spacing", 1,
+ "row-spacing", 1,
+ "item-padding", 10,
+ "margin", 2,
NULL);
g_signal_connect(G_OBJECT(iconview), "selection-changed",
G_CALLBACK(cb_image_selection_changed), panel);
+
+ g_signal_connect(panel->thumbnailer, "thumbnail-ready",
+ G_CALLBACK(cb_thumbnail_ready), 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,
- *chk_show_thumbnails, *chk_single_click, *appearance_settings;
+ *chk_show_thumbnails, *chk_single_click, *appearance_settings,
+ *bnt_exit;
GtkBuilder *appearance_gxml;
AppearancePanel *panel = g_new0(AppearancePanel, 1);
GError *error = NULL;
GtkFileFilter *filter;
WnckScreen *wnck_screen;
- WnckWindow *wnck_window = NULL;
TRACE("entering");
appearance_container = GTK_WIDGET(gtk_builder_get_object(main_gxml,
"notebook_screens"));
+ bnt_exit = GTK_WIDGET(gtk_builder_get_object(main_gxml, "bnt_exit"));
+
+ g_signal_connect(G_OBJECT(bnt_exit), "clicked",
+ G_CALLBACK(cb_xfdesktop_bnt_exit_clicked),
+ panel);
+
/* Icons tab */
/* icon size */
spin_icon_size = GTK_WIDGET(gtk_builder_get_object(main_gxml, "spin_icon_size"));
@@ -944,10 +1355,25 @@ 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)));
+ panel->wnck_window = wnck_window_get(window_xid);
+
+ if(panel->wnck_window == NULL)
+ panel->wnck_window = wnck_screen_get_active_window(wnck_screen);
- g_signal_connect(wnck_window, "geometry-changed",
+ /* 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);
+ g_signal_connect(wnck_screen, "workspace-created",
+ G_CALLBACK(cb_workspace_changed), panel);
+ g_signal_connect(wnck_screen, "workspace-destroyed",
+ G_CALLBACK(cb_workspace_changed), panel);
+ g_signal_connect(wnck_screen, "active-workspace-changed",
+ G_CALLBACK(cb_workspace_changed), panel);
+ 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;
@@ -975,25 +1401,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 +1419,42 @@ 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), XFCE_BACKDROP_IMAGE_SCALED);
+ gtk_combo_box_set_active(GTK_COMBO_BOX(panel->color_style_combo), 0);
+
+ /* Use these settings for all workspaces checkbox */
+ panel->chk_apply_to_all = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
+ "chk_apply_to_all"));
+
+ if(xfconf_channel_get_bool(channel, SINGLE_WORKSPACE_MODE, TRUE)) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->chk_apply_to_all), TRUE);
+ }
+
+ g_signal_connect(G_OBJECT(panel->chk_apply_to_all), "toggled",
+ G_CALLBACK(cb_xfdesktop_chk_apply_to_all),
+ panel);
+
/* background cycle timer */
panel->backdrop_cycle_chkbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml,
"chk_cycle_backdrop"));
@@ -1094,6 +1537,7 @@ xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml,
"active");
setup_special_icon_list(main_gxml, channel);
+ cb_update_background_tab(panel->wnck_window, panel);
}
static void
@@ -1118,11 +1562,12 @@ main(int argc, char **argv)
{
XfconfChannel *channel;
GtkBuilder *gxml;
- GtkWidget *dialog;
GError *error = NULL;
xfce_textdomain(GETTEXT_PACKAGE, LOCALEDIR, "UTF-8");
+ gdk_threads_init();
+
if(!gtk_init_with_args(&argc, &argv, "", option_entries, PACKAGE, &error)) {
if(G_LIKELY(error)) {
g_printerr("%s: %s.\n", G_LOG_DOMAIN, error->message);
@@ -1137,7 +1582,7 @@ main(int argc, char **argv)
if(G_UNLIKELY(opt_version)) {
g_print("%s %s (Xfce %s)\n\n", G_LOG_DOMAIN, VERSION, xfce_version_string());
- g_print("%s\n", "Copyright (c) 2004-2008");
+ g_print("%s\n", "Copyright (c) 2004-2013");
g_print("\t%s\n\n", _("The Xfce development team. All rights reserved."));
g_print(_("Please report bugs to <%s>."), PACKAGE_BUGREPORT);
g_print("\n");
@@ -1170,12 +1615,14 @@ main(int argc, char **argv)
channel = xfconf_channel_new(XFDESKTOP_CHANNEL);
if(opt_socket_id == 0) {
+ GtkWidget *dialog;
dialog = GTK_WIDGET(gtk_builder_get_object(gxml, "prefs_dialog"));
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));
+ 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 +1635,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 9a5ac568..32e10c06 100644
--- a/settings/xfdesktop-settings-appearance-frame-ui.glade
+++ b/settings/xfdesktop-settings-appearance-frame-ui.glade
@@ -34,245 +34,297 @@
<property name="border_width">12</property>
<property name="left_padding">6</property>
<child>
- <object class="GtkVBox" id="vbox1">
+ <object class="GtkFrame" id="frame_image_list">
<property name="visible">True</property>
- <property name="spacing">6</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">GTK_SHADOW_NONE</property>
<child>
- <object class="GtkHBox" id="hbox1">
+ <object class="GtkAlignment" id="top_padding_alignment">
<property name="visible">True</property>
- <property name="spacing">12</property>
+ <property name="top_padding">6</property>
<child>
- <object class="GtkFrame" id="frame_image_list">
+ <object class="GtkVBox" id="background_tab_vbox">
<property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="shadow_type">GTK_SHADOW_NONE</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkAlignment" id="alignment7">
+ <object class="GtkScrolledWindow" id="iconview_imagelist_scrolled_window">
<property name="visible">True</property>
- <property name="top_padding">6</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
+ <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
<child>
- <object class="GtkVBox" id="vbox3">
+ <object class="GtkIconView" id="iconview_imagelist">
<property name="visible">True</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkScrolledWindow" id="scrolledwindow1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
- <child>
- <object class="GtkIconView" id="iconview_imagelist">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- </object>
- </child>
- </object>
- </child>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="folder_color_and_image_style_table">
+ <property name="visible">True</property>
+ <property name="n-columns">8</property>
+ <property name="n-rows">2</property>
+ <property name="row-spacing">6</property>
+ <property name="column-spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="label_folder">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Folder:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="right-attach">1</property>
+ <property name="top-attach">0</property>
+ <property name="bottom-attach">1</property>
+ <property name="x-options">GTK_SHRINK</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkFileChooserButton" id="btn_folder">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Add an image to the list</property>
+ <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
+ </object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="right-attach">2</property>
+ <property name="top-attach">0</property>
+ <property name="bottom-attach">1</property>
+ <property name="x-options">GTK_FILL|GTK_EXPAND</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkAlignment" id="alignment_spacer">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">4</property>
+ <property name="right-attach">5</property>
+ <property name="top-attach">0</property>
+ <property name="bottom-attach">1</property>
+ <property name="x-options">GTK_FILL|GTK_EXPAND</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_style">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">St_yle:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">combo_style</property>
+ </object>
+ <packing>
+ <property name="left-attach">5</property>
+ <property name="right-attach">6</property>
+ <property name="top-attach">0</property>
+ <property name="bottom-attach">1</property>
+ <property name="x-options">GTK_SHRINK</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBoxText" id="combo_style">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Specify how the image will be resized to fit the screen</property>
+ <signal handler="image_style_changed" name="changed"/>
+ <items>
+ <item translatable="yes">None</item>
+ <item translatable="yes">Centered</item>
+ <item translatable="yes">Tiled</item>
+ <item translatable="yes">Stretched</item>
+ <item translatable="yes">Scaled</item>
+ <item translatable="yes">Zoomed</item>
+ <item translatable="yes">Spanning Screens</item>
+ </items>
+ </object>
+ <packing>
+ <property name="left-attach">6</property>
+ <property name="right-attach">7</property>
+ <property name="top-attach">0</property>
+ <property name="bottom-attach">1</property>
+ <property name="x-options">GTK_FILL</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label_color">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Color:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">0</property>
+ <property name="right-attach">1</property>
+ <property name="top-attach">1</property>
+ <property name="bottom-attach">2</property>
+ <property name="x-options">GTK_SHRINK</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkComboBox" id="combo_colors">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Specify the style of the color drawn behind the backdrop image</property>
+ <signal handler="color_style_changed" name="changed"/>
+ <property name="model">model2</property>
<child>
- <object class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">3</property>
- <child>
- <object class="GtkLabel" id="label_folder">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Folder:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkAlignment" id="alignment_btn_folder">
- <property name="visible">True</property>
- <property name="xalign">0.0</property>
- <property name="xscale">0.5</property>
- <child>
- <object class="GtkFileChooserButton" id="btn_folder">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Add an image to the list</property>
- <property name="action">GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkComboBoxText" id="combo_style">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Specify how the image will be resized to fit the screen</property>
- <signal handler="image_style_changed" name="changed"/>
- <items>
- <item translatable="yes">None</item>
- <item translatable="yes">Centered</item>
- <item translatable="yes">Tiled</item>
- <item translatable="yes">Stretched</item>
- <item translatable="yes">Scaled</item>
- <item translatable="yes">Zoomed</item>
- </items>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="pack-type">GTK_PACK_END</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="label_style">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">St_yle:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">combo_style</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="pack-type">GTK_PACK_END</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">1</property>
- </packing>
+ <object class="GtkCellRendererText" id="renderer2"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
</child>
</object>
+ <packing>
+ <property name="left-attach">1</property>
+ <property name="right-attach">2</property>
+ <property name="top-attach">1</property>
+ <property name="bottom-attach">2</property>
+ <property name="x-options">GTK_FILL|GTK_EXPAND</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkColorButton" id="color1_btn">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Specifies the solid color, or the "left" or "top" color of the gradient</property>
+ <property name="title" translatable="yes">Select First Color</property>
+ <property name="color">#151522223333</property>
+ <signal handler="color1_changed" name="color_set"/>
+ </object>
+ <packing>
+ <property name="left-attach">2</property>
+ <property name="right-attach">3</property>
+ <property name="top-attach">1</property>
+ <property name="bottom-attach">2</property>
+ <property name="x-options">GTK_SHRINK</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkColorButton" id="color2_btn">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="tooltip-text" translatable="yes">Specifies the "right" or "bottom" color of the gradient</property>
+ <property name="title" translatable="yes">Select Second Color</property>
+ <property name="color">#151522223333</property>
+ <signal handler="color2_changed" name="color_set"/>
+ </object>
+ <packing>
+ <property name="left-attach">3</property>
+ <property name="right-attach">4</property>
+ <property name="top-attach">1</property>
+ <property name="bottom-attach">2</property>
+ <property name="x-options">GTK_SHRINK</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="chk_apply_to_all">
+ <property name="visible">True</property>
+ <property name="sensitive">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">Apply to all _workspaces</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left-attach">6</property>
+ <property name="right-attach">7</property>
+ <property name="top-attach">1</property>
+ <property name="bottom-attach">2</property>
+ <property name="x-options">GTK_SHRINK</property>
+ <property name="y-options">GTK_SHRINK</property>
+ </packing>
</child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
</child>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkHBox" id="hbox_colors">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <child>
- <object class="GtkLabel" id="label_color">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">Color:</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkComboBox" id="combo_colors">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Specify the style of the color drawn behind the backdrop image</property>
- <signal handler="color_style_changed" name="changed"/>
- <property name="model">model2</property>
<child>
- <object class="GtkCellRendererText" id="renderer2"/>
- <attributes>
- <attribute name="text">0</attribute>
- </attributes>
+ <object class="GtkHBox" id="cycle_options_hbox">
+ <property name="visible">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkCheckButton" id="chk_cycle_backdrop">
+ <property name="visible">True</property>
+ <property name="sensitive">True</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">_Change the background (in minutes):</property>
+ <property name="tooltip-text" translatable="yes">Automatically select a different background from the current directory after a set number of minutes.</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkSpinButton" id="spin_backdrop_time_minutes">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="adjustment">adjustment3</property>
+ <property name="tooltip-text" translatable="yes">Number of minutes before a different background is selected.</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="chk_random_backdrop_order">
+ <property name="visible">True</property>
+ <property name="sensitive">False</property>
+ <property name="can_focus">True</property>
+ <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="label" translatable="yes">_Random Order</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkColorButton" id="color1_btn">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Specifies the solid color, or the "left" or "top" color of the gradient</property>
- <property name="title" translatable="yes">Select First Color</property>
- <property name="color">#151522223333</property>
- <signal handler="color1_changed" name="color_set"/>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkColorButton" id="color2_btn">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="tooltip-text" translatable="yes">Specifies the "right" or "bottom" color of the gradient</property>
- <property name="title" translatable="yes">Select Second Color</property>
- <property name="color">#151522223333</property>
- <signal handler="color2_changed" name="color_set"/>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- </packing>
</child>
- <child>
- <object class="GtkHBox" id="hbox9">
- <property name="visible">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="spacing">4</property>
- <child>
- <object class="GtkCheckButton" id="chk_cycle_backdrop">
- <property name="visible">True</property>
- <property name="sensitive">True</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">_Change the background (in minutes):</property>
- <property name="tooltip-text" translatable="yes">Automatically select a different background from the current directory after a set number of minutes.</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- <child>
- <object class="GtkSpinButton" id="spin_backdrop_time_minutes">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="adjustment">adjustment3</property>
- <property name="tooltip-text" translatable="yes">Number of minutes before a different background is selected.</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkCheckButton" id="chk_random_backdrop_order">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
- <property name="label" translatable="yes">_Random Order</property>
- <property name="use_underline">True</property>
- <property name="draw_indicator">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="position">2</property>
- </packing>
- </child>
</object>
</child>
</object>
diff --git a/settings/xfdesktop-settings-ui.glade b/settings/xfdesktop-settings-ui.glade
index 7bccb6bd..b69fe4b8 100644
--- a/settings/xfdesktop-settings-ui.glade
+++ b/settings/xfdesktop-settings-ui.glade
@@ -769,7 +769,7 @@
</object>
</child>
<child>
- <object class="GtkButton" id="button1">
+ <object class="GtkButton" id="bnt_exit">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
@@ -791,7 +791,7 @@
</child>
<action-widgets>
<action-widget response="-11">button2</action-widget>
- <action-widget response="-3">button1</action-widget>
+ <action-widget response="-3">bnt_exit</action-widget>
</action-widgets>
</object>
</interface>
diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c
index a2bd53b5..a8aa8342 100644
--- a/src/xfce-backdrop.c
+++ b/src/xfce-backdrop.c
@@ -60,7 +60,9 @@ struct _XfceBackdropPriv
{
gint width, height;
gint bpp;
-
+
+ GdkPixbuf *pix;
+
XfceBackdropColorStyle color_style;
GdkColor color1;
GdkColor color2;
@@ -68,8 +70,6 @@ struct _XfceBackdropPriv
XfceBackdropImageStyle image_style;
gchar *image_path;
- gint brightness;
-
gboolean cycle_backdrop;
guint cycle_timer;
guint cycle_timer_id;
@@ -102,52 +102,6 @@ static guint backdrop_signals[LAST_SIGNAL] = { 0, };
/* helper functions */
static GdkPixbuf *
-adjust_brightness(GdkPixbuf *src, gint amount)
-{
- GdkPixbuf *newpix;
- GdkPixdata pdata;
- gboolean has_alpha = FALSE;
- gint i, len;
- GError *err = NULL;
-
- g_return_val_if_fail(src != NULL, NULL);
- if(amount == 0)
- return src;
-
- gdk_pixdata_from_pixbuf(&pdata, src, FALSE);
- has_alpha = (pdata.pixdata_type & GDK_PIXDATA_COLOR_TYPE_RGBA);
- if(pdata.length < 1)
- len = pdata.width * pdata.height * (has_alpha?4:3);
- else
- len = pdata.length - GDK_PIXDATA_HEADER_LENGTH;
-
- for(i = 0; i < len; i++) {
- gshort scaled;
-
- if(has_alpha && (i+1)%4)
- continue;
-
- scaled = pdata.pixel_data[i] + amount;
- if(scaled > 255)
- scaled = 255;
- if(scaled < 0)
- scaled = 0;
- pdata.pixel_data[i] = scaled;
- }
-
- newpix = gdk_pixbuf_from_pixdata(&pdata, TRUE, &err);
- if(!newpix) {
- g_warning("%s: Unable to modify image brightness: %s", PACKAGE,
- err->message);
- g_error_free(err);
- return src;
- }
- g_object_unref(G_OBJECT(src));
-
- return newpix;
-}
-
-static GdkPixbuf *
create_solid(GdkColor *color,
gint width,
gint height,
@@ -227,6 +181,19 @@ create_gradient(GdkColor *color1, GdkColor *color2, gint width, gint height,
return pix;
}
+static void
+xfce_backdrop_clear_cached_image(XfceBackdrop *backdrop)
+{
+ g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
+
+ if(backdrop->priv->pix == NULL)
+ return;
+
+ g_object_unref(backdrop->priv->pix);
+ backdrop->priv->pix = NULL;
+}
+
+
/* gobject-related functions */
@@ -296,13 +263,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",
@@ -358,6 +318,8 @@ xfce_backdrop_finalize(GObject *object)
backdrop->priv->cycle_timer_id = 0;
}
+ xfce_backdrop_clear_cached_image(backdrop);
+
G_OBJECT_CLASS(xfce_backdrop_parent_class)->finalize(object);
}
@@ -396,10 +358,6 @@ xfce_backdrop_set_property(GObject *object,
g_value_get_string(value));
break;
- case PROP_BRIGHTNESS:
- xfce_backdrop_set_brightness(backdrop, g_value_get_int(value));
- break;
-
case PROP_BACKDROP_CYCLE_ENABLE:
xfce_backdrop_set_cycle_backdrop(backdrop, g_value_get_boolean(value));
break;
@@ -448,10 +406,6 @@ xfce_backdrop_get_property(GObject *object,
xfce_backdrop_get_image_filename(backdrop));
break;
- case PROP_BRIGHTNESS:
- g_value_set_int(value, xfce_backdrop_get_brightness(backdrop));
- break;
-
case PROP_BACKDROP_CYCLE_ENABLE:
g_value_set_boolean(value, xfce_backdrop_get_cycle_backdrop(backdrop));
break;
@@ -537,9 +491,13 @@ void
xfce_backdrop_set_size(XfceBackdrop *backdrop, gint width, gint height)
{
g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
-
- backdrop->priv->width = width;
- backdrop->priv->height = height;
+
+ if(backdrop->priv->width != width ||
+ backdrop->priv->height != height) {
+ xfce_backdrop_clear_cached_image(backdrop);
+ backdrop->priv->width = width;
+ backdrop->priv->height = height;
+ }
}
/**
@@ -557,6 +515,7 @@ xfce_backdrop_set_color_style(XfceBackdrop *backdrop,
g_return_if_fail((int)style >= 0 && style <= XFCE_BACKDROP_COLOR_TRANSPARENT);
if(style != backdrop->priv->color_style) {
+ xfce_backdrop_clear_cached_image(backdrop);
backdrop->priv->color_style = style;
g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CHANGED], 0);
}
@@ -591,6 +550,7 @@ xfce_backdrop_set_first_color(XfceBackdrop *backdrop,
|| color->green != backdrop->priv->color1.green
|| color->blue != backdrop->priv->color1.blue)
{
+ xfce_backdrop_clear_cached_image(backdrop);
backdrop->priv->color1.red = color->red;
backdrop->priv->color1.green = color->green;
backdrop->priv->color1.blue = color->blue;
@@ -627,6 +587,7 @@ xfce_backdrop_set_second_color(XfceBackdrop *backdrop,
|| color->green != backdrop->priv->color2.green
|| color->blue != backdrop->priv->color2.blue)
{
+ xfce_backdrop_clear_cached_image(backdrop);
backdrop->priv->color2.red = color->red;
backdrop->priv->color2.green = color->green;
backdrop->priv->color2.blue = color->blue;
@@ -662,6 +623,7 @@ xfce_backdrop_set_image_style(XfceBackdrop *backdrop,
g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
if(style != backdrop->priv->image_style) {
+ xfce_backdrop_clear_cached_image(backdrop);
backdrop->priv->image_style = style;
g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CHANGED], 0);
}
@@ -697,7 +659,9 @@ xfce_backdrop_set_image_filename(XfceBackdrop *backdrop, const gchar *filename)
backdrop->priv->image_path = g_strdup(filename);
else
backdrop->priv->image_path = NULL;
-
+
+ xfce_backdrop_clear_cached_image(backdrop);
+
g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CHANGED], 0);
}
@@ -708,33 +672,6 @@ xfce_backdrop_get_image_filename(XfceBackdrop *backdrop)
return backdrop->priv->image_path;
}
-/**
- * xfce_backdrop_set_brightness:
- * @backdrop: An #XfceBackdrop.
- * @brightness: A brightness value.
- *
- * Modifies the brightness of the backdrop using a value between -128 and 127.
- * A value of 0 indicates that the brightness should not be changed. This value
- * is applied to the entire image, after compositing.
- **/
-void
-xfce_backdrop_set_brightness(XfceBackdrop *backdrop, gint brightness)
-{
- g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
-
- if(brightness != backdrop->priv->brightness) {
- backdrop->priv->brightness = brightness;
- g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CHANGED], 0);
- }
-}
-
-gint
-xfce_backdrop_get_brightness(XfceBackdrop *backdrop)
-{
- g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), 0);
- return backdrop->priv->brightness;
-}
-
static gboolean
xfce_backdrop_timer(XfceBackdrop *backdrop)
{
@@ -742,7 +679,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;
}
@@ -853,9 +792,16 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
gint dx, dy, xo, yo;
gdouble xscale, yscale;
GdkInterpType interp;
-
+
+ TRACE("entering");
+
g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), NULL);
-
+
+ if(backdrop->priv->pix != NULL) {
+ DBG("pixbuf cached");
+ return g_object_ref(backdrop->priv->pix);
+ }
+
if(backdrop->priv->image_style != XFCE_BACKDROP_IMAGE_NONE &&
backdrop->priv->image_path) {
format = gdk_pixbuf_get_file_info(backdrop->priv->image_path, &iw, &ih);
@@ -884,12 +830,8 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
final_image = create_solid(&backdrop->priv->color1, w, h, FALSE, 0xff);
}
- if(!apply_backdrop_image) {
- if(backdrop->priv->brightness != 0)
- final_image = adjust_brightness(final_image, backdrop->priv->brightness);
-
+ if(!apply_backdrop_image)
return final_image;
- }
istyle = backdrop->priv->image_style;
@@ -929,6 +871,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;
@@ -938,7 +886,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);
}
@@ -950,7 +898,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,
@@ -981,6 +928,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) {
@@ -1006,9 +954,53 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop)
if(image)
g_object_unref(G_OBJECT(image));
-
- if(backdrop->priv->brightness != 0)
- final_image = adjust_brightness(final_image, backdrop->priv->brightness);
-
+
+ /* cache it */
+ backdrop->priv->pix = g_object_ref(final_image);
+
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;
+ }
+
+ /* Every color style uses color1 except for transparent which does not need
+ * a color check */
+ if(backdrop_a->priv->color_style != XFCE_BACKDROP_COLOR_TRANSPARENT &&
+ !gdk_color_equal(&backdrop_a->priv->color1, &backdrop_b->priv->color1)) {
+ DBG("colors different");
+ return FALSE;
+ }
+
+ /* When the style is set to gradient then we should check color2 as well */
+ if((backdrop_a->priv->color_style == XFCE_BACKDROP_COLOR_HORIZ_GRADIENT ||
+ backdrop_a->priv->color_style == XFCE_BACKDROP_COLOR_VERT_GRADIENT) &&
+ !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 6c013c35..ab26d453 100644
--- a/src/xfce-backdrop.h
+++ b/src/xfce-backdrop.h
@@ -111,11 +111,6 @@ void xfce_backdrop_set_image_filename (XfceBackdrop *backdrop,
G_CONST_RETURN gchar *xfce_backdrop_get_image_filename
(XfceBackdrop *backdrop);
-
-void xfce_backdrop_set_brightness (XfceBackdrop *backdrop,
- gint brightness);
-gint xfce_backdrop_get_brightness (XfceBackdrop *backdrop);
-
void xfce_backdrop_set_cycle_backdrop (XfceBackdrop *backdrop,
gboolean cycle_backdrop);
gboolean xfce_backdrop_get_cycle_backdrop(XfceBackdrop *backdrop);
@@ -130,6 +125,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 95c30f6d..149a833c 100644
--- a/src/xfce-desktop.c
+++ b/src/xfce-desktop.c
@@ -101,7 +101,10 @@ struct _XfceDesktopPriv
gint nworkspaces;
XfceWorkspace **workspaces;
gint current_workspace;
-
+
+ gboolean single_workspace_mode;
+ gint single_workspace_num;
+
SessionLogoutFunc session_logout_func;
#ifdef ENABLE_DESKTOP_ICONS
@@ -130,6 +133,8 @@ enum
PROP_ICON_FONT_SIZE,
PROP_ICON_FONT_SIZE_SET,
#endif
+ PROP_SINGLE_WORKSPACE_MODE,
+ PROP_SINGLE_WORKSPACE_NUMBER,
};
@@ -156,6 +161,12 @@ static gboolean xfce_desktop_delete_event(GtkWidget *w,
static void xfce_desktop_style_set(GtkWidget *w,
GtkStyle *old_style);
+static void xfce_desktop_set_single_workspace_mode(XfceDesktop *desktop,
+ gboolean single_workspace);
+static void xfce_desktop_set_single_workspace_number(XfceDesktop *desktop,
+ gint workspace_num);
+
+static gboolean xfce_desktop_get_single_workspace_mode(XfceDesktop *desktop);
static gint xfce_desktop_get_current_workspace(XfceDesktop *desktop);
static guint signals[N_SIGNALS] = { 0, };
@@ -307,9 +318,8 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
XfceDesktop *desktop = XFCE_DESKTOP(user_data);
GdkPixmap *pmap = desktop->priv->bg_pixmap;
GdkScreen *gscreen = desktop->priv->gscreen;
- cairo_t *cr;
- GdkPixbuf *pix;
GdkRectangle rect;
+ GdkRegion *clip_region = NULL;
gint i, monitor = -1, current_workspace;
TRACE("entering");
@@ -323,6 +333,7 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data)
current_workspace = xfce_desktop_get_current_workspace(desktop);
+ /* Find out which monitor the backdrop is on */
for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
if(backdrop == xfce_workspace_get_backdrop(desktop->priv->workspaces[current_workspace], i)) {
monitor = i;
@@ -336,13 +347,9 @@ 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])) {
+ /* Spanning screens */
GdkRectangle monitor_rect;
gdk_screen_get_monitor_geometry(gscreen, 0, &rect);
@@ -360,26 +367,87 @@ 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);
}
- cr = gdk_cairo_create(GDK_DRAWABLE(pmap));
- gdk_cairo_set_source_pixbuf(cr, pix, rect.x, rect.y);
- cairo_paint(cr);
- g_object_unref(G_OBJECT(pix));
- cairo_destroy(cr);
-
- /* tell gtk to redraw the repainted area */
- gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y,
- rect.width, rect.height);
-
- set_imgfile_root_property(desktop,
- xfce_backdrop_get_image_filename(backdrop),
- monitor);
-
- /* do this again so apps watching the root win notice the update */
- set_real_root_window_pixmap(gscreen, pmap);
+ xfce_backdrop_set_size(backdrop, rect.width, rect.height);
+
+ if(monitor > 0
+ && !xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) {
+ clip_region = gdk_region_rectangle(&rect);
+
+ DBG("clip_region: x: %d, y: %d, w: %d, h: %d",
+ rect.x, rect.y, rect.width, rect.height);
+
+ /* If we are not monitor 0 on a multi-monitor setup we need to subtract
+ * all the previous monitor regions so we don't draw over them. This
+ * should prevent the overlap and double backdrop drawing bugs.
+ */
+ for(i = 0; i < monitor; i++) {
+ GdkRectangle previous_monitor;
+ GdkRegion *previous_region;
+ gdk_screen_get_monitor_geometry(gscreen, i, &previous_monitor);
+
+ DBG("previous_monitor: x: %d, y: %d, w: %d, h: %d",
+ previous_monitor.x, previous_monitor.y,
+ previous_monitor.width, previous_monitor.height);
+
+ previous_region = gdk_region_rectangle(&previous_monitor);
+
+ gdk_region_subtract(clip_region, previous_region);
+
+ gdk_region_destroy(previous_region);
+ }
+ }
+
+ if(clip_region != NULL) {
+ /* Update the area to redraw to limit the icons/area painted */
+ gdk_region_get_clipbox(clip_region, &rect);
+ DBG("area to update: x: %d, y: %d, w: %d, h: %d",
+ rect.x, rect.y, rect.width, rect.height);
+ }
+
+ if(rect.width != 0 && rect.height != 0) {
+ /* create/get the composited backdrop pixmap */
+ GdkPixbuf *pix = xfce_backdrop_get_pixbuf(backdrop);
+ cairo_t *cr;
+
+ if(!pix)
+ return;
+
+ cr = gdk_cairo_create(GDK_DRAWABLE(pmap));
+ gdk_cairo_set_source_pixbuf(cr, pix, rect.x, rect.y);
+
+ /* clip the area so we don't draw over a previous wallpaper */
+ if(clip_region != NULL) {
+ gdk_cairo_region(cr, clip_region);
+ cairo_clip(cr);
+ }
+
+ cairo_paint(cr);
+
+ /* tell gtk to redraw the repainted area */
+ gtk_widget_queue_draw_area(GTK_WIDGET(desktop), rect.x, rect.y,
+ rect.width, rect.height);
+
+ set_imgfile_root_property(desktop,
+ xfce_backdrop_get_image_filename(backdrop),
+ monitor);
+
+ /* do this again so apps watching the root win notice the update */
+ set_real_root_window_pixmap(gscreen, pmap);
+
+ g_object_unref(G_OBJECT(pix));
+ cairo_destroy(cr);
+ }
+
+ if(clip_region != NULL)
+ gdk_region_destroy(clip_region);
}
static void
@@ -387,12 +455,13 @@ screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data)
{
XfceDesktop *desktop = user_data;
gint w, h, current_workspace;
- XfceBackdrop *current_backdrop;
TRACE("entering");
g_return_if_fail(XFCE_IS_DESKTOP(desktop));
- g_return_if_fail(desktop->priv->workspaces);
+
+ if(desktop->priv->workspaces == NULL)
+ return;
w = gdk_screen_get_width(gscreen);
h = gdk_screen_get_height(gscreen);
@@ -413,19 +482,18 @@ screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data)
if(desktop->priv->nworkspaces <= current_workspace)
return;
+ if(current_workspace < 0)
+ return;
+
/* 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);
+ XfceBackdrop *current_backdrop;
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);
}
}
@@ -470,7 +538,7 @@ workspace_backdrop_changed_cb(XfceWorkspace *workspace,
g_return_if_fail(XFCE_IS_WORKSPACE(workspace) && XFCE_IS_BACKDROP(backdrop));
- if(desktop->priv->current_workspace == xfce_workspace_get_workspace_num(workspace))
+ if(xfce_desktop_get_current_workspace(desktop) == xfce_workspace_get_workspace_num(workspace))
backdrop_changed_cb(backdrop, user_data);
}
@@ -480,14 +548,43 @@ workspace_changed_cb(WnckScreen *wnck_screen,
gpointer user_data)
{
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 = xfce_desktop_get_current_workspace(desktop);
- /* fake a screen size changed, so the background is properly set */
- screen_size_changed_cb(desktop->priv->gscreen, user_data);
+ if(new_workspace < 0 || new_workspace >= desktop->priv->nworkspaces)
+ return;
+
+ desktop->priv->current_workspace = new_workspace;
+
+ DBG("current_workspace %d, new_workspace %d",
+ current_workspace, new_workspace);
+
+ for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) {
+ /* We want to compare the current workspace backdrop with the new one
+ * and see if we can avoid changing them if they are the same image/style */
+ if(current_workspace < desktop->priv->nworkspaces) {
+ 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);
+ }
+ } else {
+ /* If current_workspace was removed, get the new backdrop and apply it */
+ new_backdrop = xfce_workspace_get_backdrop(desktop->priv->workspaces[new_workspace], i);
+ backdrop_changed_cb(new_backdrop, user_data);
+ }
+
+ /* When we're spanning screens we only care about the first monitor */
+ if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[new_workspace]))
+ break;
+ }
}
static void
@@ -549,6 +646,10 @@ workspace_destroyed_cb(WnckScreen *wnck_screen,
/* deallocate it */
desktop->priv->workspaces = g_realloc(desktop->priv->workspaces,
desktop->priv->nworkspaces * sizeof(XfceWorkspace *));
+
+ /* Make sure we stay within bounds now that we removed a workspace */
+ if(desktop->priv->current_workspace > desktop->priv->nworkspaces)
+ desktop->priv->current_workspace = desktop->priv->nworkspaces;
}
static void
@@ -686,6 +787,20 @@ xfce_desktop_class_init(XfceDesktopClass *klass)
"icon font size set",
FALSE,
XFDESKTOP_PARAM_FLAGS));
+
+ g_object_class_install_property(gobject_class, PROP_SINGLE_WORKSPACE_MODE,
+ g_param_spec_boolean("single-workspace-mode",
+ "single-workspace-mode",
+ "single-workspace-mode",
+ TRUE,
+ XFDESKTOP_PARAM_FLAGS));
+
+ g_object_class_install_property(gobject_class, PROP_SINGLE_WORKSPACE_NUMBER,
+ g_param_spec_int("single-workspace-number",
+ "single-workspace-number",
+ "single-workspace-number",
+ 0, G_MAXINT16, 0,
+ XFDESKTOP_PARAM_FLAGS));
#endif
#undef XFDESKTOP_PARAM_FLAGS
}
@@ -743,6 +858,16 @@ xfce_desktop_set_property(GObject *object,
break;
#endif
+ case PROP_SINGLE_WORKSPACE_MODE:
+ xfce_desktop_set_single_workspace_mode(desktop,
+ g_value_get_boolean(value));
+ break;
+
+ case PROP_SINGLE_WORKSPACE_NUMBER:
+ xfce_desktop_set_single_workspace_number(desktop,
+ g_value_get_int(value));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
@@ -776,6 +901,14 @@ xfce_desktop_get_property(GObject *object,
break;
#endif
+ case PROP_SINGLE_WORKSPACE_MODE:
+ g_value_set_boolean(value, desktop->priv->single_workspace_mode);
+ break;
+
+ case PROP_SINGLE_WORKSPACE_NUMBER:
+ g_value_set_int(value, desktop->priv->single_workspace_num);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
break;
@@ -791,7 +924,6 @@ xfce_desktop_realize(GtkWidget *widget)
Window xid;
GdkWindow *groot;
WnckScreen *wnck_screen;
- WnckWorkspace *wnck_workspace;
TRACE("entering");
@@ -841,9 +973,16 @@ xfce_desktop_realize(GtkWidget *widget)
wnck_screen_force_update(wnck_screen);
desktop->priv->wnck_screen = wnck_screen;
+ 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");
+
/* Get the current workspace number */
- wnck_workspace = wnck_screen_get_active_workspace(wnck_screen);
- desktop->priv->current_workspace = wnck_workspace_get_number(wnck_workspace);
+ desktop->priv->current_workspace = xfce_desktop_get_current_workspace(desktop);
desktop->priv->nworkspaces = wnck_screen_get_workspace_count(wnck_screen);
desktop->priv->workspaces = g_realloc(desktop->priv->workspaces,
@@ -1088,52 +1227,44 @@ 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)
+static gboolean
+xfce_desktop_get_single_workspace_mode(XfceDesktop *desktop)
{
- XfceDesktop *desktop = user_data;
- gchar *p;
- const gchar *filename;
- gint monitor, current_workspace;
- XfceBackdrop *backdrop;
-
- TRACE("entering");
-
- p = strstr(property, "/monitor");
- if(!p)
- return;
+ g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), TRUE);
- 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);
+ return desktop->priv->single_workspace_mode;
}
static gint
xfce_desktop_get_current_workspace(XfceDesktop *desktop)
{
+ WnckWorkspace *wnck_workspace;
+ gint workspace_num, current_workspace;
+
g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1);
- return desktop->priv->current_workspace;
+ wnck_workspace = wnck_screen_get_active_workspace(desktop->priv->wnck_screen);
+
+ if(wnck_workspace != NULL) {
+ workspace_num = wnck_workspace_get_number(wnck_workspace);
+ } else {
+ workspace_num = desktop->priv->nworkspaces;
+ }
+
+ /* If we're in single_workspace mode we need to return the workspace that
+ * it was set to, if possible, otherwise return the current workspace */
+ if(xfce_desktop_get_single_workspace_mode(desktop) &&
+ desktop->priv->single_workspace_num < desktop->priv->nworkspaces) {
+ current_workspace = desktop->priv->single_workspace_num;
+ } else {
+ current_workspace = workspace_num;
+ }
+
+ DBG("workspace_num %d, single_workspace_num %d, current_workspace %d, max workspaces %d",
+ workspace_num, desktop->priv->single_workspace_num, current_workspace,
+ desktop->priv->nworkspaces);
+
+ return current_workspace;
}
/* public api */
@@ -1294,6 +1425,42 @@ xfce_desktop_set_use_icon_font_size(XfceDesktop *desktop,
#endif
}
+static void
+xfce_desktop_set_single_workspace_mode(XfceDesktop *desktop,
+ gboolean single_workspace)
+{
+ g_return_if_fail(XFCE_IS_DESKTOP(desktop));
+
+ if(single_workspace == desktop->priv->single_workspace_mode)
+ return;
+
+ desktop->priv->single_workspace_mode = single_workspace;
+
+ 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);
+}
+
+static void
+xfce_desktop_set_single_workspace_number(XfceDesktop *desktop,
+ gint workspace_num)
+{
+ g_return_if_fail(XFCE_IS_DESKTOP(desktop));
+
+ if(workspace_num == desktop->priv->single_workspace_num)
+ return;
+
+ DBG("single_workspace_num now %d", workspace_num);
+
+ desktop->priv->single_workspace_num = workspace_num;
+
+ if(xfce_desktop_get_single_workspace_mode(desktop)) {
+ /* Fake a screen size changed to update the backdrop */
+ screen_size_changed_cb(desktop->priv->gscreen, desktop);
+ }
+}
+
void
xfce_desktop_set_session_logout_func(XfceDesktop *desktop,
SessionLogoutFunc logout_func)
@@ -1394,33 +1561,22 @@ 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));
if(!gtk_widget_get_realized(GTK_WIDGET(desktop)))
return;
- 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, };
+ current_workspace = xfce_desktop_get_current_workspace(desktop);
- 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 ba9f3278..d6368eac 100644
--- a/src/xfce-workspace.c
+++ b/src/xfce-workspace.c
@@ -82,7 +82,11 @@ struct _XfceWorkspacePriv
guint workspace_num;
guint nbackdrops;
+ gboolean xinerama_stretch;
XfceBackdrop **backdrops;
+
+ gulong *first_color_id;
+ gulong *second_color_id;
};
enum
@@ -106,6 +110,11 @@ static void xfce_workspace_get_property(GObject *object,
static void xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace,
XfceBackdrop *backdrop,
guint monitor);
+static void xfce_workspace_disconnect_backdrop_settings(XfceWorkspace *workspace,
+ XfceBackdrop *backdrop,
+ guint monitor);
+
+static void xfce_workspace_remove_backdrops(XfceWorkspace *workspace);
G_DEFINE_TYPE(XfceWorkspace, xfce_workspace, G_TYPE_OBJECT)
@@ -148,14 +157,34 @@ backdrop_cycle_cb(XfceBackdrop *backdrop, gpointer user_data)
if(g_strcmp0(backdrop_file, new_backdrop) != 0) {
xfce_backdrop_set_image_filename(backdrop, new_backdrop);
g_free(new_backdrop);
- g_signal_emit(G_OBJECT(user_data), signals[WORKSPACE_BACKDROP_CHANGED], 0, backdrop);
}
}
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);
}
@@ -165,72 +194,52 @@ xfce_workspace_monitors_changed(XfceWorkspace *workspace,
GdkScreen *gscreen)
{
guint i;
+ guint n_monitors;
+ GdkVisual *vis = NULL;
TRACE("entering");
- if(workspace->priv->nbackdrops > 1
- && xfce_workspace_get_xinerama_stretch(workspace)) {
- /* for xinerama stretch we only need one backdrop */
- if(workspace->priv->nbackdrops > 1) {
- for(i = 1; i < workspace->priv->nbackdrops; ++i)
- g_object_unref(G_OBJECT(workspace->priv->backdrops[i]));
- }
+ vis = gdk_screen_get_rgba_visual(gscreen);
+ if(vis == NULL)
+ vis = gdk_screen_get_system_visual(gscreen);
- if(workspace->priv->nbackdrops != 1) {
- workspace->priv->backdrops = g_realloc(workspace->priv->backdrops,
- sizeof(XfceBackdrop *));
- if(!workspace->priv->nbackdrops) {
- GdkVisual *vis = gdk_screen_get_rgba_visual(gscreen);
- if(vis == NULL)
- vis = gdk_screen_get_system_visual(gscreen);
-
- workspace->priv->backdrops[0] = xfce_backdrop_new(vis);
- xfce_workspace_connect_backdrop_settings(workspace,
- workspace->priv->backdrops[0],
- 0);
- g_signal_connect(G_OBJECT(workspace->priv->backdrops[0]),
- "changed",
- G_CALLBACK(backdrop_changed_cb), workspace);
- g_signal_connect(G_OBJECT(workspace->priv->backdrops[0]),
- "cycle",
- G_CALLBACK(backdrop_cycle_cb), workspace);
- }
- workspace->priv->nbackdrops = 1;
- }
+ if(workspace->priv->nbackdrops > 0 &&
+ xfce_workspace_get_xinerama_stretch(workspace)) {
+ /* When spanning screens we only need one backdrop */
+ n_monitors = 1;
} 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]));
- }
+ n_monitors = gdk_screen_get_n_monitors(gscreen);
+ }
- 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;
- }
+ /* Remove all backdrops so that the correct monitor is added/removed and
+ * things stay in the correct order */
+ xfce_workspace_remove_backdrops(workspace);
+
+ /* Allocate space for the backdrops and their color properties so they
+ * can correctly be removed */
+ workspace->priv->backdrops = g_realloc(workspace->priv->backdrops,
+ sizeof(XfceBackdrop *) * n_monitors);
+ workspace->priv->first_color_id = g_realloc(workspace->priv->first_color_id,
+ sizeof(gulong) * n_monitors);
+ workspace->priv->second_color_id = g_realloc(workspace->priv->second_color_id,
+ sizeof(gulong) * 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;
}
static void
@@ -267,9 +276,13 @@ xfce_workspace_finalize(GObject *object)
{
XfceWorkspace *workspace = XFCE_WORKSPACE(object);
+ xfce_workspace_remove_backdrops(workspace);
+
g_object_unref(G_OBJECT(workspace->priv->channel));
g_free(workspace->priv->property_prefix);
-
+ g_free(workspace->priv->backdrops);
+ g_free(workspace->priv->first_color_id);
+ g_free(workspace->priv->second_color_id);
}
static void
@@ -321,19 +334,21 @@ 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");
buf[pp_len] = 0;
g_strlcat(buf, "color1", sizeof(buf));
- xfconf_g_property_bind_gdkcolor(channel, buf,
- G_OBJECT(backdrop), "first-color");
+ workspace->priv->first_color_id[monitor] = xfconf_g_property_bind_gdkcolor(channel, buf,
+ G_OBJECT(backdrop), "first-color");
buf[pp_len] = 0;
g_strlcat(buf, "color2", sizeof(buf));
- xfconf_g_property_bind_gdkcolor(channel, buf,
- G_OBJECT(backdrop), "second-color");
+ workspace->priv->second_color_id[monitor] = xfconf_g_property_bind_gdkcolor(channel, buf,
+ G_OBJECT(backdrop), "second-color");
buf[pp_len] = 0;
g_strlcat(buf, "image-style", sizeof(buf));
@@ -341,11 +356,6 @@ xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace,
G_OBJECT(backdrop), "image-style");
buf[pp_len] = 0;
- g_strlcat(buf, "brightness", sizeof(buf));
- xfconf_g_property_bind(channel, buf, G_TYPE_INT,
- G_OBJECT(backdrop), "brightness");
-
- buf[pp_len] = 0;
g_strlcat(buf, "backdrop-cycle-enable", sizeof(buf));
xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN,
G_OBJECT(backdrop), "backdrop-cycle-enable");
@@ -368,7 +378,37 @@ xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace,
g_free(monitor_name);
}
+static void
+xfce_workspace_disconnect_backdrop_settings(XfceWorkspace *workspace,
+ XfceBackdrop *backdrop,
+ guint monitor)
+{
+ TRACE("entering");
+
+ g_return_if_fail(XFCE_IS_BACKDROP(backdrop));
+
+ xfconf_g_property_unbind_all(G_OBJECT(backdrop));
+}
+static void
+xfce_workspace_remove_backdrops(XfceWorkspace *workspace)
+{
+ guint i;
+ guint n_monitors;
+
+ g_return_if_fail(XFCE_IS_WORKSPACE(workspace));
+
+ n_monitors = gdk_screen_get_n_monitors(workspace->priv->gscreen);
+
+ for(i = 0; i < n_monitors && i < workspace->priv->nbackdrops; ++i) {
+ xfce_workspace_disconnect_backdrop_settings(workspace,
+ workspace->priv->backdrops[i],
+ i);
+ g_object_unref(G_OBJECT(workspace->priv->backdrops[i]));
+ workspace->priv->backdrops[i] = NULL;
+ }
+ workspace->priv->nbackdrops = 0;
+}
/* public api */
diff --git a/src/xfdesktop-file-icon-manager.c b/src/xfdesktop-file-icon-manager.c
index d68ff735..8f4d72a8 100644
--- a/src/xfdesktop-file-icon-manager.c
+++ b/src/xfdesktop-file-icon-manager.c
@@ -1202,122 +1202,6 @@ xfdesktop_file_icon_menu_fill_template_menu(GtkWidget *menu,
g_list_free(files);
return have_templates;
-#if 0
- dp = g_dir_open (absolute_path, 0, NULL);
- g_free (absolute_path);
-
- /* read the directory contents (if opened successfully) */
- if (G_LIKELY (dp != NULL))
- {
- /* process all files within the directory */
- for (;;)
- {
- /* read the name of the next file */
- name = g_dir_read_name (dp);
- if (G_UNLIKELY (name == NULL))
- break;
- else if (name[0] == '.')
- continue;
-
- /* determine the info for that file */
- path = thunar_vfs_path_relative (templates_path, name);
- info = thunar_vfs_info_new_for_path (path, NULL);
- thunar_vfs_path_unref (path);
-
- /* add the info (if any) to our list */
- if (G_LIKELY (info != NULL))
- info_list = g_list_insert_sorted (info_list, info, info_compare);
- }
-
- /* close the directory handle */
- g_dir_close (dp);
- }
-
- /* check if we have any infos */
- if (G_UNLIKELY (info_list == NULL))
- return FALSE;
-
- /* determine the icon theme for the menu */
- icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (menu));
-
- /* add menu items for all infos */
- for (lp = info_list; lp != NULL; lp = lp->next)
- {
- /* determine the info */
- info = lp->data;
-
- /* check if we have a regular file or a directory here */
- if (G_LIKELY (info->type == THUNAR_VFS_FILE_TYPE_REGULAR))
- {
- /* generate a label by stripping off the extension */
- label = g_strdup (info->display_name);
- dot = g_utf8_strrchr (label, -1, '.');
- if (G_LIKELY (dot != NULL))
- *dot = '\0';
-
- /* allocate a new menu item */
- item = gtk_image_menu_item_new_with_label (label);
- g_object_set_data_full (G_OBJECT (item), I_("thunar-vfs-info"), thunar_vfs_info_ref (info), (GDestroyNotify) thunar_vfs_info_unref);
- g_signal_connect (G_OBJECT (item), "activate",
- G_CALLBACK (xfdesktop_file_icon_template_item_activated),
- fmanager);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* lookup the icon for the mime type of that file */
- icon_name = thunar_vfs_mime_info_lookup_icon_name (info->mime_info, icon_theme);
-
- /* generate an image based on the named icon */
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_widget_show (image);
-
- /* cleanup */
- g_free (label);
-
- have_templates = TRUE;
- }
- else if (info->type == THUNAR_VFS_FILE_TYPE_DIRECTORY)
- {
- /* allocate a new submenu for the directory */
- submenu = gtk_menu_new ();
- g_object_ref_sink (G_OBJECT (submenu));
- gtk_menu_set_screen (GTK_MENU (submenu), gtk_widget_get_screen (menu));
-
- /* fill the submenu from the folder contents */
- have_templates = xfdesktop_file_icon_menu_fill_template_menu(submenu,
- info->path,
- fmanager)
- || have_templates;
-
- /* check if any items were added to the submenu */
- if (G_LIKELY (GTK_MENU_SHELL (submenu)->children != NULL))
- {
- /* hook up the submenu */
- item = gtk_image_menu_item_new_with_label (info->display_name);
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-
- /* lookup the icon for the mime type of that file */
- icon_name = thunar_vfs_mime_info_lookup_icon_name (info->mime_info, icon_theme);
-
- /* generate an image based on the named icon */
- image = gtk_image_new_from_icon_name (icon_name, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- gtk_widget_show (image);
- }
-
- /* cleanup */
- g_object_unref (G_OBJECT (submenu));
- }
- }
-
- /* release the info list */
- thunar_vfs_info_list_free (info_list);
-#endif
-
- return have_templates;
}
#ifdef HAVE_THUNARX