From bfa7ccb7043f13dae9c28ca3275c989b483df18c Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Thu, 17 Jan 2013 18:59:05 +0300 Subject: [PATCH] xfdesktop-settings and xfdesktop supports per-workspace wallpapers Additionally xfdesktop-settings includes quite a few of the layout changes from the Xfce Design SIG (i.e. on the background tab the images are displayed in an iconview, the settings window changes depening on which monitor/workspace it is on, etc). --- common/xfdesktop-common.c | 230 +--- common/xfdesktop-common.h | 12 +- settings/Makefile.am | 3 + settings/main.c | 1450 ++++++-------------- .../xfdesktop-settings-appearance-frame-ui.glade | 455 +----- settings/xfdesktop-settings-ui.glade | 111 +- src/Makefile.am | 2 + src/xfce-backdrop.c | 181 +-- src/xfce-backdrop.h | 19 +- src/xfce-desktop.c | 487 +++---- src/xfce-desktop.h | 8 +- src/xfce-workspace.c | 422 ++++++ src/xfce-workspace.h | 78 ++ 13 files changed, 1291 insertions(+), 2167 deletions(-) create mode 100644 src/xfce-workspace.c create mode 100644 src/xfce-workspace.h diff --git a/common/xfdesktop-common.c b/common/xfdesktop-common.c index 64aee8d..52ae3bb 100644 --- a/common/xfdesktop-common.c +++ b/common/xfdesktop-common.c @@ -56,156 +56,96 @@ #define O_BINARY 0 #endif -gboolean -xfdesktop_backdrop_list_is_valid(const gchar *path) +static GList * +list_files_in_dir(const gchar *path) { - FILE *fp; - gchar buf[512]; - gint size; - gboolean is_list = FALSE; + GDir *dir; + gboolean needs_slash = TRUE; + const gchar *file; + GList *files = NULL; + + dir = g_dir_open(path, 0, 0); + if(!dir) + return NULL; - size = sizeof(LIST_TEXT); + if(path[strlen(path)-1] == '/') + needs_slash = FALSE; - if(!(fp = fopen (path, "r"))) - return FALSE; + while((file = g_dir_read_name(dir))) { + gchar *current_file = g_strdup_printf(needs_slash ? "%s/%s" : "%s%s", + path, file); + + files = g_list_insert_sorted(files, current_file, (GCompareFunc)g_strcmp0); + } - if(fgets(buf, size, fp) && !strncmp(LIST_TEXT, buf, size - 1)) - is_list = TRUE; - fclose(fp); + g_dir_close(dir); - return is_list; + return files; } -gchar ** -xfdesktop_backdrop_list_load(const gchar *filename, - gint *n_items, - GError **error) + +gchar * +xfdesktop_backdrop_choose_next(const gchar *filename) { - gchar *contents = NULL, **files = NULL, *p, *q; - gsize length = 0; - gint arr_size = 10, count = 0; + GList *files, *current_file, *start_file; + gchar *file = NULL; - g_return_val_if_fail(filename && (!error || !*error), NULL); + g_return_val_if_fail(filename, NULL); - if(!g_file_get_contents(filename, &contents, &length, error)) + files = list_files_in_dir(g_path_get_dirname(filename)); + if(!files) return NULL; - if(strncmp(LIST_TEXT, contents, sizeof(LIST_TEXT) - 1)) { - if(error) { - g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - _("Backdrop list file is not valid")); - } - g_free(contents); - return NULL; - } + /* Get the our current background in the list */ + current_file = g_list_find_custom(files, filename, (GCompareFunc)g_strcmp0); - /* i'd use g_strsplit() here, but then counting is slower. we can - * also filter out blank lines */ - files = g_malloc(sizeof(gchar *) * (arr_size+1)); - p = contents + sizeof(LIST_TEXT); - while(p && *p) { - q = strstr(p, "\n"); - if(q) { - if(p == q) /* blank line */ - continue; - *q = 0; - } else - q = contents + length; /* assume no trailing '\n' at EOF */ - - if(count == arr_size) { - arr_size += 10; - files = g_realloc(files, sizeof(gchar *) * (arr_size+1)); - } + /* if somehow we don't have a valid file, grab the first one available */ + if(current_file == NULL) + current_file = g_list_first(files); - files[count++] = g_strdup(p); - if(q != contents + length) - p = q + 1; - } - files[count] = NULL; - files = g_realloc(files, sizeof(gchar *) * (count+1)); + start_file = current_file; - if(n_items) - *n_items = count; + /* We want the next valid image file in the dir while making sure + * we don't loop on ourselves */ + do { + current_file = g_list_next(current_file); - g_free(contents); + /* we hit the end of the list */ + if(current_file == NULL) + current_file = g_list_first(files); - return files; -} + /* We went through every item in the list */ + if(g_strcmp0(start_file->data, current_file->data) == 0) + break; -gboolean -xfdesktop_backdrop_list_save(const gchar *filename, - gchar * const *files, - GError **error) -{ - gboolean ret = FALSE; - gchar *filename_new; - FILE *fp; - gint i; - - g_return_val_if_fail(filename && (!error || !*error), FALSE); - - filename_new = g_strconcat(filename, ".new", NULL); - fp = fopen(filename_new, "w"); - if(fp) { - fprintf(fp, "%s\n", LIST_TEXT); - if(files) { - for(i = 0; files[i]; ++i) - fprintf(fp, "%s\n", files[i]); - } - if(!fclose(fp)) { - if(!rename(filename_new, filename)) - ret = TRUE; - else { - if(error) { - g_set_error(error, G_FILE_ERROR, - g_file_error_from_errno(errno), - "%s", g_strerror(errno)); - } - unlink(filename_new); - } - } else { - if(error) { - g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), - "%s", g_strerror(errno)); - } - unlink(filename_new); - } - } else if(error) { - g_set_error(error, G_FILE_ERROR, g_file_error_from_errno(errno), - "%s", g_strerror(errno)); - } + } while(!xfdesktop_image_file_is_valid(current_file->data)); - g_free(filename_new); + file = g_strdup(current_file->data); + g_list_free_full(files, g_free); - return ret; + return file; } gchar * -xfdesktop_backdrop_list_choose_random(const gchar *filename, - GError **error) +xfdesktop_backdrop_choose_random(const gchar *filename) { static gboolean __initialized = FALSE; static gint previndex = -1; - gchar **files, *file = NULL; - gint n_items = 0, cur_file, i, tries = 0; + GList *files; + gchar *file = NULL; + gint n_items = 0, cur_file, tries = 0; - g_return_val_if_fail(filename && (!error || !*error), NULL); + g_return_val_if_fail(filename, NULL); - files = xfdesktop_backdrop_list_load(filename, &n_items, error); + files = list_files_in_dir(g_path_get_dirname(filename)); if(!files) return NULL; - if(!n_items) { - if(error) { - g_set_error(error, G_FILE_ERROR, G_FILE_ERROR_FAILED, - _("Backdrop list file is not valid")); - } - g_strfreev(files); - return NULL; - } + + n_items = g_list_length(files); if(1 == n_items) { - file = g_strdup(files[0]); - g_strfreev(files); + file = g_strdup(g_list_first(files)->data); + g_list_free_full(files, g_free); return file; } @@ -226,7 +166,7 @@ xfdesktop_backdrop_list_choose_random(const gchar *filename, /* this isn't precise, but if we've failed to get a good * image after all this time, let's just give up */ g_warning("Unable to find good image from list; giving up"); - g_strfreev(files); + g_list_free_full(files, g_free); return NULL; } @@ -238,65 +178,23 @@ xfdesktop_backdrop_list_choose_random(const gchar *filename, #endif } while(cur_file == previndex && G_LIKELY(previndex != -1)); - } while(!xfdesktop_image_file_is_valid(files[cur_file])); + } while(!xfdesktop_image_file_is_valid(g_list_nth(files, cur_file)->data)); previndex = cur_file; - file = files[cur_file]; - /* don't use strfreev() and avoid an extra alloc */ - for(i = 0; files[i]; ++i) { - if(i != cur_file) - g_free(files[i]); - } - g_free(files); + file = g_strdup(g_list_nth(files, cur_file)->data); + g_list_free_full(files, g_free); return file; } -static void -pixbuf_loader_size_cb(GdkPixbufLoader *loader, gint width, gint height, - gpointer user_data) -{ - gboolean *size_read = user_data; - - if(width > 0 && height > 0) - *size_read = TRUE; -} - gboolean xfdesktop_image_file_is_valid(const gchar *filename) { - GdkPixbufLoader *loader; - int fd; - gboolean size_read = FALSE; - guchar buf[4096]; - gssize len; - g_return_val_if_fail(filename, FALSE); - fd = open(filename, O_RDONLY|O_BINARY); - if(fd < 0) - return FALSE; - - loader = gdk_pixbuf_loader_new(); - g_signal_connect(G_OBJECT(loader), "size-prepared", - G_CALLBACK(pixbuf_loader_size_cb), &size_read); - - do { - len = read(fd, buf, sizeof(buf)); - if(len > 0) { - if(!gdk_pixbuf_loader_write(loader, buf, len, NULL)) - break; - if(size_read) - break; - } - } while(len > 0); - - close(fd); - gdk_pixbuf_loader_close(loader, NULL); - g_object_unref(G_OBJECT(loader)); - - return size_read; + /* 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); } gboolean diff --git a/common/xfdesktop-common.h b/common/xfdesktop-common.h index df767f0..7c7570d 100644 --- a/common/xfdesktop-common.h +++ b/common/xfdesktop-common.h @@ -33,7 +33,6 @@ #define XFDESKTOP_CHANNEL "xfce4-desktop" #define DEFAULT_BACKDROP DATADIR "/backgrounds/xfce/xfce-blue.jpg" -#define DEFAULT_BACKDROP_LIST "xfce4/desktop/backdrop.list" #define DEFAULT_ICON_FONT_SIZE 12 #define DEFAULT_ICON_SIZE 32 #define ITHEME_FLAGS (GTK_ICON_LOOKUP_USE_BUILTIN \ @@ -72,15 +71,8 @@ G_BEGIN_DECLS -gchar **xfdesktop_backdrop_list_load(const gchar *filename, - gint *n_items, - GError **error); -gboolean xfdesktop_backdrop_list_save(const gchar *filename, - gchar * const *files, - GError **error); -gchar *xfdesktop_backdrop_list_choose_random(const gchar *filename, - GError **error); -gboolean xfdesktop_backdrop_list_is_valid(const gchar *filename); +gchar *xfdesktop_backdrop_choose_next(const gchar *filename); +gchar *xfdesktop_backdrop_choose_random(const gchar *filename); gboolean xfdesktop_image_file_is_valid(const gchar *filename); diff --git a/settings/Makefile.am b/settings/Makefile.am index 09cff59..640dd6a 100644 --- a/settings/Makefile.am +++ b/settings/Makefile.am @@ -14,8 +14,10 @@ xfdesktop_settings_CFLAGS = \ $(XFCONF_CFLAGS) \ $(GTHREAD_CFLAGS) \ $(LIBX11_CFLAGS) \ + $(LIBWNCK_CFLAGS) \ -DG_LOG_DOMAIN=\"xfdesktop-settings\" \ -DEXO_API_SUBJECT_TO_CHANGE \ + -DWNCK_I_KNOW_THIS_IS_UNSTABLE \ -DLOCALEDIR=\"$(localedir)\" \ -DDATADIR=\"$(datadir)\" \ -DBINDIR=\"$(bindir)\" @@ -26,6 +28,7 @@ xfdesktop_settings_LDADD = \ $(LIBXFCE4UI_LIBS) \ $(LIBEXO_LIBS) \ $(GTHREAD_LIBS) \ + $(LIBWNCK_LIBS) \ $(LIBX11_LIBS) if HAVE_CYGWIN diff --git a/settings/main.c b/settings/main.c index f4ded70..bdb98c6 100644 --- a/settings/main.c +++ b/settings/main.c @@ -42,18 +42,19 @@ #include #include +#include #include #include #include #include +#include #include "xfdesktop-common.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 SHOW_DESKTOP_MENU_PROP "/desktop-menu/show" #define DESKTOP_MENU_SHOW_ICONS_PROP "/desktop-menu/show-icons" @@ -75,47 +76,33 @@ #define DESKTOP_ICONS_SHOW_FILESYSTEM "/desktop-icons/file-icons/show-filesystem" #define DESKTOP_ICONS_SHOW_REMOVABLE "/desktop-icons/file-icons/show-removable" -#define PER_SCREEN_PROP_FORMAT "/backdrop/screen%d/monitor%d" +#define PER_WORKSPACE_PROP_FORMAT "/backdrop/screen%d/monitor%d/workspace%d" typedef struct { XfconfChannel *channel; gint screen; gint monitor; - gulong show_image:1, - image_selector_loaded:1, - image_list_loaded:1; + gint workspace; + gulong image_list_loaded:1; GtkWidget *frame_image_list; - GtkWidget *image_treeview; - GtkWidget *btn_plus; - GtkWidget *btn_minus; - GtkWidget *btn_newlist; + GtkWidget *image_iconview; + GtkWidget *btn_folder; GtkWidget *image_style_combo; - - GtkWidget *radio_singleimage; - GtkWidget *radio_imagelist; - GtkWidget *radio_none; - GtkWidget *color_style_combo; GtkWidget *color1_btn; GtkWidget *color2_btn; - GtkWidget *brightness_slider; - GtkWidget *saturation_slider; + gulong color1_btn_id; + gulong color2_btn_id; GtkWidget *backdrop_cycle_spinbox; GtkWidget *backdrop_cycle_chkbox; + GtkWidget *random_backdrop_order_chkbox; - GtkWidget *chk_xinerama_stretch; } AppearancePanel; -typedef struct -{ - GtkTreeModel *model; - GSList *iters; -} PreviewData; - enum { COL_PIX = 0, @@ -134,125 +121,6 @@ enum N_ICON_COLS, }; -enum -{ - TARGET_TEXT_URI_LIST = 0, -}; - - -/* 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; - GdkPixbuf *pix, *pix_scaled = NULL; - - gtk_tree_model_get(model, iter, - COL_NAME, &name, - COL_FILENAME, &filename, - -1); - - pix = gdk_pixbuf_new_from_file(filename, NULL); - g_free(filename); - if(pix) { - gint width, height; - gdouble aspect; - - 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\nSize: %dx%d"), - name, width, height); - - aspect = (gdouble)width / height; - - /* Keep the aspect ratio sensible otherwise the treeview looks bad */ - if(aspect > MAX_ASPECT_RATIO) { - aspect = MAX_ASPECT_RATIO; - } - - width = PREVIEW_HEIGHT * aspect; - height = PREVIEW_HEIGHT; - pix_scaled = gdk_pixbuf_scale_simple(pix, width, height, - GDK_INTERP_BILINEAR); - - g_object_unref(G_OBJECT(pix)); - } - 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) { - gtk_list_store_set(GTK_LIST_STORE(model), iter, - COL_PIX, pix_scaled, - -1); - g_object_unref(G_OBJECT(pix_scaled)); - } -} - -static gpointer -xfdesktop_settings_create_some_previews(gpointer data) -{ - PreviewData *pdata = data; - GSList *l; - - GDK_THREADS_ENTER (); - - for(l = pdata->iters; l; l = l->next) - xfdesktop_settings_do_single_preview(pdata->model, l->data); - - GDK_THREADS_LEAVE (); - - g_object_unref(G_OBJECT(pdata->model)); - g_slist_foreach(pdata->iters, (GFunc)gtk_tree_iter_free, NULL); - g_slist_free(pdata->iters); - g_free(pdata); - - return NULL; -} - -static gpointer -xfdesktop_settings_create_all_previews(gpointer data) -{ - GtkTreeModel *model = data; - GtkTreeView *tree_view; - GtkTreeIter iter; - - GDK_THREADS_ENTER (); - - 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)); - } - - /* 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); - - if(gtk_tree_selection_get_mode(selection) != GTK_SELECTION_MULTIPLE - && gtk_tree_selection_get_selected(selection, NULL, &iter)) - { - 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_object_set_data(G_OBJECT(model), "xfdesktop-tree-view", NULL); - - GDK_THREADS_LEAVE (); - - g_object_unref(G_OBJECT(model)); - - return NULL; -} static void cb_special_icon_toggled(GtkCellRendererToggle *render, gchar *path, gpointer user_data) @@ -359,41 +227,32 @@ setup_special_icon_list(GtkBuilder *gxml, g_object_unref(G_OBJECT(ls)); } + static gint -image_list_sort(GtkTreeModel *model, - GtkTreeIter *a, - GtkTreeIter *b, - gpointer user_data) +image_list_compare(GtkTreeModel *model, + const gchar *a, + GtkTreeIter *b) { - gchar *key_a = NULL, *key_b = NULL; + gchar *key_b = NULL; gint ret; - gtk_tree_model_get(model, a, COL_COLLATE_KEY, &key_a, -1); - gtk_tree_model_get(model, b, COL_COLLATE_KEY, &key_b, -1); + gtk_tree_model_get(model, b, COL_NAME, &key_b, -1); - if(G_UNLIKELY(!key_a && !key_b)) - ret = 0; - else if(G_UNLIKELY(!key_a)) - ret = -1; - else if(G_UNLIKELY(!key_b)) - ret = 1; - else - ret = strcmp(key_a, key_b); + ret = g_strcmp0(a, key_b); - g_free(key_a); g_free(key_b); return ret; } static GtkTreeIter * -xfdesktop_settings_image_treeview_add(GtkTreeModel *model, +xfdesktop_settings_image_iconview_add(GtkTreeModel *model, const char *path) { - gboolean added = FALSE; - GtkTreeIter iter; + gboolean added = FALSE, found = FALSE, valid = FALSE; + GtkTreeIter iter, search_iter; gchar *name = NULL, *name_utf8 = NULL, *name_markup = NULL; - gchar *lower = NULL, *key = NULL; + gchar *lower = NULL; if(!xfdesktop_image_file_is_valid(path)) return NULL; @@ -407,13 +266,29 @@ xfdesktop_settings_image_treeview_add(GtkTreeModel *model, name_utf8); lower = g_utf8_strdown(name_utf8, -1); - key = g_utf8_collate_key(lower, -1); - gtk_list_store_append(GTK_LIST_STORE(model), &iter); + /* 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) { + found = TRUE; + } else { + valid = gtk_tree_model_iter_next(model, &search_iter); + } + } + + 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_PIX, path, COL_NAME, name_markup, COL_FILENAME, path, - COL_COLLATE_KEY, key, + COL_COLLATE_KEY, lower, -1); added = TRUE; @@ -424,7 +299,6 @@ xfdesktop_settings_image_treeview_add(GtkTreeModel *model, g_free(name_utf8); g_free(name_markup); g_free(lower); - g_free(key); if(added) return gtk_tree_iter_copy(&iter); @@ -454,7 +328,7 @@ xfdesktop_image_list_add_dir(GtkListStore *ls, g_snprintf(buf, sizeof(buf), needs_slash ? "%s/%s" : "%s%s", path, file); - iter = xfdesktop_settings_image_treeview_add(GTK_TREE_MODEL(ls), buf); + iter = xfdesktop_settings_image_iconview_add(GTK_TREE_MODEL(ls), buf); if(iter) { if(cur_image_file && !iter_ret && !strcmp(buf, cur_image_file)) iter_ret = iter; @@ -468,308 +342,78 @@ xfdesktop_image_list_add_dir(GtkListStore *ls, return iter_ret; } -static gboolean -xfdesktop_settings_ensure_backdrop_list(gchar *filename, - GtkWindow *parent) -{ - FILE *fp; - - g_return_val_if_fail(filename && *filename, FALSE); - - if(xfdesktop_backdrop_list_is_valid(filename)) - return TRUE; - - fp = fopen(filename, "w"); - if(!fp) { - gchar *shortfile = g_path_get_basename(filename); - gchar *primary = g_strdup_printf(_("Cannot create backdrop list \"%s\""), - shortfile); - - xfce_message_dialog(parent, - _("Backdrop List Error"), - GTK_STOCK_DIALOG_ERROR, - primary, strerror(errno), - GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, - NULL); - g_free(primary); - g_free(shortfile); - - return FALSE; - } - - fprintf(fp, "%s\n", LIST_TEXT); - fclose(fp); - - return TRUE; -} - -static gchar * -xfdesktop_settings_dialog_create_load_list(AppearancePanel *panel) +static void +xfdesktop_settings_update_iconview_frame_name(AppearancePanel *panel, + WnckWorkspace *wnck_workspace) { - gchar *list_file = NULL; - GtkWindow *parent = GTK_WINDOW(gtk_widget_get_toplevel(panel->image_treeview)); - GtkWidget *chooser; - gchar *path; - - chooser = gtk_file_chooser_dialog_new(_("Create/Load Backdrop List"), - parent, GTK_FILE_CHOOSER_ACTION_SAVE, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); - path = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, - "xfce4/desktop/", TRUE); - if(path) { - gtk_file_chooser_add_shortcut_folder(GTK_FILE_CHOOSER(chooser), - path, NULL); - g_free(path); - } + gchar buf[1024]; + gchar *monitor_name, *workspace_name; + GdkScreen *screen = gtk_widget_get_screen(panel->image_iconview); - for(;;) { - if(GTK_RESPONSE_ACCEPT != gtk_dialog_run(GTK_DIALOG(chooser))) { - gtk_widget_destroy(chooser); - return NULL; - } + if(panel->monitor < 0 && panel->workspace < 0) + return; - list_file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser)); - if(g_file_test(list_file, G_FILE_TEST_EXISTS) - && !xfdesktop_backdrop_list_is_valid(list_file)) - { - gchar *shortfile = g_path_get_basename(list_file); - gchar *primary = g_strdup_printf(_("File \"%s\" is not a valid backdrop list file. Do you wish to overwrite it?"), - shortfile); - gint resp; - - resp = xfce_message_dialog(GTK_WINDOW(chooser), - _("Invalid List File"), - GTK_STOCK_DIALOG_ERROR, - primary, - _("Overwriting the file will cause its contents to be lost."), - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - XFCE_BUTTON_TYPE_MIXED, GTK_STOCK_SAVE, _("Replace"), GTK_RESPONSE_ACCEPT, - NULL); - g_free(primary); - g_free(shortfile); - - if(GTK_RESPONSE_ACCEPT == resp) - break; - else { - g_free(list_file); - list_file = NULL; - } - } else - break; - } + monitor_name = gdk_screen_get_monitor_plug_name(screen, panel->monitor); + workspace_name = g_strdup(wnck_workspace_get_name(wnck_workspace)); - gtk_widget_destroy(chooser); - while(gtk_events_pending()) - gtk_main_iteration(); + if(monitor_name) { + g_snprintf(buf, sizeof(buf), + _("Wallpaper for %s on Monitor %d (%s)"), + workspace_name, panel->monitor, monitor_name); + g_free(monitor_name); + } else + g_snprintf(buf, sizeof(buf), + _("Wallpaper for %s on Monitor %d"), + workspace_name, panel->monitor); - if(!xfdesktop_settings_ensure_backdrop_list(list_file, parent)) { - g_free(list_file); - return NULL; - } + gtk_frame_set_label(GTK_FRAME(panel->frame_image_list), buf); - return list_file; + g_free(workspace_name); } static void -cb_image_selection_changed(GtkTreeSelection *sel, +cb_image_selection_changed(ExoIconView *icon_view, gpointer user_data) { AppearancePanel *panel = user_data; - GtkTreeModel *model = NULL; + GtkTreeModel *model = exo_icon_view_get_model(icon_view); GtkTreeIter iter; - gchar *filename = NULL; + GList *selected_items = NULL; + gchar *filename = NULL, *current_filename = NULL; gchar buf[1024]; TRACE("entering"); - if(panel->image_list_loaded) - return; - - if(!gtk_tree_selection_get_selected(sel, &model, &iter)) + if(panel->image_list_loaded && GTK_IS_TREE_MODEL(model)) return; - gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1); - - DBG("got %s, applying to screen %d monitor %d", filename, panel->screen, panel->monitor); - - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/image-path", - panel->screen, panel->monitor); - xfconf_channel_set_string(panel->channel, buf, filename); - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/last-single-image", - panel->screen, panel->monitor); - xfconf_channel_set_string(panel->channel, buf, filename); -} - -static gboolean -xfdesktop_settings_dialog_populate_image_list(AppearancePanel *panel) -{ - gchar prop_image[1024], prop_last[1024], *image_file; - GtkListStore *ls; - GtkTreeIter *image_file_iter = NULL; - gboolean do_sort = TRUE; - GtkTreeSelection *sel; - - sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(panel->image_treeview)); - ls = gtk_list_store_new(N_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING, - G_TYPE_STRING, G_TYPE_STRING); - - g_snprintf(prop_image, sizeof(prop_image), - PER_SCREEN_PROP_FORMAT "/image-path", - panel->screen, panel->monitor); - image_file = xfconf_channel_get_string(panel->channel, prop_image, NULL); - - if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->radio_imagelist))) { - gchar **images; - - g_snprintf(prop_last, sizeof(prop_last), - PER_SCREEN_PROP_FORMAT "/last-image-list", - panel->screen, panel->monitor); - - if(!image_file || !xfdesktop_backdrop_list_is_valid(image_file)) { - g_free(image_file); - image_file = xfconf_channel_get_string(panel->channel, prop_last, - NULL); - if(!image_file || !xfdesktop_backdrop_list_is_valid(image_file)) { - g_free(image_file); - image_file = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, - DEFAULT_BACKDROP_LIST, - TRUE); - if(!xfdesktop_settings_ensure_backdrop_list(image_file, - GTK_WINDOW(gtk_widget_get_toplevel(panel->image_treeview)))) - { - /* FIXME: go back to single image mode or something */ - g_free(image_file); - return FALSE; - } - } - } - - do_sort = FALSE; - - images = xfdesktop_backdrop_list_load(image_file, NULL, NULL); - if(images) { - gint i; - - xfconf_channel_set_string(panel->channel, prop_image, image_file); - xfconf_channel_set_string(panel->channel, prop_last, image_file); + selected_items = exo_icon_view_get_selected_items(icon_view); - for(i = 0; images[i]; ++i) { - GtkTreeIter *iter = xfdesktop_settings_image_treeview_add(GTK_TREE_MODEL(ls), images[i]); - if(iter) - gtk_tree_iter_free(iter); - } - - g_strfreev(images); - panel->image_list_loaded = TRUE; - panel->image_selector_loaded = FALSE; - gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); - } - } else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->radio_singleimage))) { - GtkTreeIter *tmp; - gchar **backdrop_dirs; - gint i; - - g_snprintf(prop_last, sizeof(prop_last), - PER_SCREEN_PROP_FORMAT "/last-image", - panel->screen, panel->monitor); - - if(!image_file || !xfdesktop_image_file_is_valid(image_file)) { - g_free(image_file); - image_file = xfconf_channel_get_string(panel->channel, prop_last, - NULL); - if(!image_file || !xfdesktop_image_file_is_valid(image_file)) { - g_free(image_file); - image_file = g_strdup(DEFAULT_BACKDROP); - } - } + /* We only care about the first selected item because the iconview + * should be set to single selection mode */ + if(!selected_items || g_list_first(selected_items) == NULL) + return; - xfconf_channel_set_string(panel->channel, prop_image, image_file); - xfconf_channel_set_string(panel->channel, prop_last, image_file); - - /* Add all backdrops in xfce4/backdrops/ for backwards compatibility with 4.8 */ - backdrop_dirs = xfce_resource_lookup_all(XFCE_RESOURCE_DATA, - "xfce4/backdrops/"); - for(i = 0; backdrop_dirs[i]; ++i) { - tmp = xfdesktop_image_list_add_dir(ls, backdrop_dirs[i], - image_file); - if(tmp) - image_file_iter = tmp; - } - g_strfreev(backdrop_dirs); - - /* Add all backdrops in backgrounds/xfce/ */ - backdrop_dirs = xfce_resource_lookup_all(XFCE_RESOURCE_DATA, - "backgrounds/xfce/"); - for(i = 0; backdrop_dirs[i]; ++i) { - tmp = xfdesktop_image_list_add_dir(ls, backdrop_dirs[i], - image_file); - if(tmp) - image_file_iter = tmp; - } - g_strfreev(backdrop_dirs); + if(!gtk_tree_model_get_iter(model, &iter, g_list_first(selected_items)->data)) + return; - if(!image_file_iter) - image_file_iter = xfdesktop_settings_image_treeview_add(GTK_TREE_MODEL(ls), image_file); + gtk_tree_model_get(model, &iter, COL_FILENAME, &filename, -1); - panel->image_list_loaded = FALSE; - panel->image_selector_loaded = TRUE; - gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); - } else { - g_warning("xfdesktop_settings_populate_image_list() called when image style set to 'none'"); - return FALSE; - } + g_snprintf(buf, sizeof(buf), PER_WORKSPACE_PROP_FORMAT "/last-image", + panel->screen, panel->monitor, panel->workspace); - if(do_sort) { - gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(ls), COL_NAME, - image_list_sort, NULL, NULL); - gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(ls), COL_NAME, - GTK_SORT_ASCENDING); - } + current_filename = xfconf_channel_get_string(panel->channel, buf, ""); - gtk_tree_view_set_model(GTK_TREE_VIEW(panel->image_treeview), - GTK_TREE_MODEL(ls)); - if(image_file_iter) { - gtk_tree_selection_select_iter(sel, image_file_iter); - gtk_tree_iter_free(image_file_iter); - - /* remember the tree view to scroll to the selected image in the - * thread that creates all the previews */ - g_object_set_data_full(G_OBJECT(ls), "xfdesktop-tree-view", - g_object_ref(panel->image_treeview), - g_object_unref); - } + /* check to see if the selection actually did change */ + if(g_strcmp0(current_filename, filename) != 0) { + DBG("got %s, applying to screen %d monitor %d workspace %d", filename, + panel->screen, panel->monitor, panel->workspace); - /* generate previews of each image -- the new thread will own - * the reference on the list store, so let's not unref it here */ - if(!g_thread_create(xfdesktop_settings_create_all_previews, ls, FALSE, NULL)) { - g_critical("Failed to spawn thread; backdrop previews will be unavailable."); - g_object_unref(G_OBJECT(ls)); + xfconf_channel_set_string(panel->channel, buf, filename); } - g_free(image_file); - - return TRUE; -} - -static void -newlist_button_clicked(GtkWidget *button, - gpointer user_data) -{ - AppearancePanel *panel = user_data; - gchar *list_file, propname[1024]; - - list_file = xfdesktop_settings_dialog_create_load_list(panel); - if(!list_file) - return; - - g_snprintf(propname, sizeof(propname), PER_SCREEN_PROP_FORMAT "/image-path", - panel->screen, panel->monitor); - xfconf_channel_set_string(panel->channel, propname, list_file); - g_free(list_file); - - xfdesktop_settings_dialog_populate_image_list(panel); + g_list_free(selected_items); + g_free(current_filename); } static void @@ -777,6 +421,9 @@ cb_xfdesktop_chk_custom_font_size_toggled(GtkCheckButton *button, gpointer user_data) { GtkWidget *spin_button = GTK_WIDGET(user_data); + + TRACE("entering"); + gtk_widget_set_sensitive(spin_button, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))); } @@ -786,14 +433,16 @@ cb_xfdesktop_chk_cycle_backdrop_toggled(GtkCheckButton *button, gpointer user_data) { gboolean sensitive = FALSE; - GtkWidget *spin_button = GTK_WIDGET(user_data); + AppearancePanel *panel = user_data; + + TRACE("entering"); - if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) && - gtk_widget_get_sensitive(GTK_WIDGET(button))) { + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->backdrop_cycle_chkbox))) { sensitive = TRUE; } - gtk_widget_set_sensitive(spin_button, sensitive); + gtk_widget_set_sensitive(panel->backdrop_cycle_spinbox, sensitive); + gtk_widget_set_sensitive(panel->random_backdrop_order_chkbox, sensitive); } static gboolean @@ -801,6 +450,8 @@ xfdesktop_spin_icon_size_timer(GtkSpinButton *button) { XfconfChannel *channel = g_object_get_data(G_OBJECT(button), "xfconf-chanel"); + TRACE("entering"); + g_return_val_if_fail(XFCONF_IS_CHANNEL(channel), FALSE); xfconf_channel_set_uint(channel, @@ -816,6 +467,8 @@ cb_xfdesktop_spin_icon_size_changed(GtkSpinButton *button, { guint timer_id = 0; + TRACE("entering"); + g_object_set_data(G_OBJECT(button), "xfconf-chanel", user_data); timer_id = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(button), "timer-id")); @@ -831,172 +484,49 @@ cb_xfdesktop_spin_icon_size_changed(GtkSpinButton *button, g_object_set_data(G_OBJECT(button), "timer-id", GUINT_TO_POINTER(timer_id)); } -static gboolean -xfdesktop_settings_save_backdrop_list(AppearancePanel *panel, - GtkTreeModel *model) -{ - gboolean ret = TRUE; - gint n_images; - gchar **images = NULL, *list_file; - GtkTreeIter iter; - gchar propname[1024]; - GError *error = NULL; - - n_images = gtk_tree_model_iter_n_children(model, NULL); - images = g_new(gchar *, n_images + 1); - images[n_images] = NULL; - - if(gtk_tree_model_get_iter_first(model, &iter)) { - gint i = 0; - - do { - gtk_tree_model_get(model, &iter, - COL_FILENAME, &(images[i++]), - -1); - } while(gtk_tree_model_iter_next(model, &iter)); - } - - g_snprintf(propname, sizeof(propname), - PER_SCREEN_PROP_FORMAT "/last-image-list", - panel->screen, panel->monitor); - list_file = xfconf_channel_get_string(panel->channel, propname, NULL); - if(!list_file) { - list_file = xfce_resource_save_location(XFCE_RESOURCE_CONFIG, - DEFAULT_BACKDROP_LIST, TRUE); - g_warning("Didn't find prop %s when saving backdrop list; using default %s", - propname, list_file); - } - - if(!xfdesktop_backdrop_list_save(list_file, images, &error)) { - gchar *primary = g_strdup_printf(_("Failed to write backdrop list to \"%s\""), - list_file); - - xfce_message_dialog(GTK_WINDOW(gtk_widget_get_toplevel(panel->frame_image_list)), - _("Backdrop List Error"), GTK_STOCK_DIALOG_ERROR, - primary, error->message, - GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, NULL); - - g_free(primary); - g_error_free(error); - ret = FALSE; - } - - g_free(list_file); - g_strfreev(images); - - return ret; -} - static void -add_file_button_clicked(GtkWidget *button, - gpointer user_data) +cb_folder_selection_changed(GtkWidget *button, + gpointer user_data) { AppearancePanel *panel = user_data; - GtkWidget *chooser; - GtkFileFilter *filter; - - chooser = gtk_file_chooser_dialog_new(_("Add Image File(s)"), - GTK_WINDOW(gtk_widget_get_toplevel(button)), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT, - NULL); - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(chooser), TRUE); - - filter = gtk_file_filter_new(); - gtk_file_filter_set_name(filter, _("Image files")); - gtk_file_filter_add_pixbuf_formats(filter); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser), filter); + gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(button)); + GtkListStore *ls; + GtkTreeIter *iter; + GtkTreePath *path; + gchar *last_image; + gchar property[1024]; - filter = gtk_file_filter_new(); - gtk_file_filter_set_name(filter, _("All files")); - gtk_file_filter_add_custom(filter, GTK_FILE_FILTER_FILENAME, - (GtkFileFilterFunc)gtk_true, NULL, NULL); - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(chooser), filter); - - exo_gtk_file_chooser_add_thumbnail_preview(GTK_FILE_CHOOSER(chooser)); - - if(gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_ACCEPT) { - GSList *filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(chooser)); - GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(panel->image_treeview)); - GSList *l; - PreviewData *pdata = g_new0(PreviewData, 1); - pdata->model = g_object_ref(G_OBJECT(model)); - - for(l = filenames; l; l = l->next) { - GtkTreeIter *iter = xfdesktop_settings_image_treeview_add(model, l->data); - if(iter) { - pdata->iters = g_slist_prepend(pdata->iters, iter); - - /* auto-select the first one added */ - if(l == filenames) { - GtkTreeSelection *sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(panel->image_treeview)); - gtk_tree_selection_select_iter(sel, iter); - } - } - } - g_slist_free(filenames); - - if(!pdata->iters - || !g_thread_create(xfdesktop_settings_create_some_previews, - pdata, FALSE, NULL)) - { - if(pdata->iters) - g_critical("Unable to create thread for single image preview."); - g_object_unref(G_OBJECT(pdata->model)); - g_slist_foreach(pdata->iters, (GFunc)gtk_tree_iter_free, NULL); - g_slist_free(pdata->iters); - g_free(pdata); - } + TRACE("entering"); - if(panel->image_list_loaded) { - xfdesktop_settings_save_backdrop_list(panel, model); + ls = gtk_list_store_new(N_COLS, G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING); - /* if we just added the first image, instruct xfdesktop - * to load it */ - if(gtk_tree_model_iter_n_children(model, NULL) == 1) - g_spawn_command_line_async("xfdesktop --reload", NULL); - } - } + g_snprintf(property, sizeof(property), + PER_WORKSPACE_PROP_FORMAT "/last-image", + panel->screen, panel->monitor, panel->workspace); - gtk_widget_destroy(chooser); -} + last_image = xfconf_channel_get_string(panel->channel, property, NULL); -static void -remove_file_button_clicked(GtkWidget *button, - gpointer user_data) -{ - AppearancePanel *panel = user_data; - GtkTreeSelection *sel; - GtkTreeModel *model = NULL; - GList *rows, *l; - - sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(panel->image_treeview)); - rows = gtk_tree_selection_get_selected_rows(sel, &model); - if(rows) { - GSList *rrefs = NULL, *m; - GtkTreeIter iter; - - for(l = rows; l; l = l->next) { - rrefs = g_slist_prepend(rrefs, gtk_tree_row_reference_new(model, - l->data)); - gtk_tree_path_free(l->data); - } - g_list_free(rows); + if(last_image == NULL) + last_image = DEFAULT_BACKDROP; - for(m = rrefs; m; m = m->next) { - GtkTreePath *path = gtk_tree_row_reference_get_path(m->data); + iter = xfdesktop_image_list_add_dir(ls, filename, last_image); - if(gtk_tree_model_get_iter(model, &iter, path)) - gtk_list_store_remove(GTK_LIST_STORE(model), &iter); + exo_icon_view_set_model(EXO_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) { + exo_icon_view_select_path(EXO_ICON_VIEW(panel->image_iconview), path); gtk_tree_path_free(path); - gtk_tree_row_reference_free(m->data); } - g_slist_free(rrefs); - - xfdesktop_settings_save_backdrop_list(panel, model); + gtk_tree_iter_free(iter); } + + /* now that we've set a model to the iconview we can add the search column */ + exo_icon_view_set_search_column(EXO_ICON_VIEW(panel->image_iconview), COL_COLLATE_KEY); } static void @@ -1011,6 +541,8 @@ cb_xfdesktop_combo_color_changed(GtkComboBox *combo, }; AppearancePanel *panel = user_data; + TRACE("entering"); + if(gtk_combo_box_get_active(combo) == COLORS_SOLID) { gtk_widget_set_sensitive(panel->color1_btn, TRUE); gtk_widget_set_sensitive(panel->color2_btn, FALSE); @@ -1024,294 +556,237 @@ cb_xfdesktop_combo_color_changed(GtkComboBox *combo, } static void -cb_image_type_radio_clicked(GtkWidget *w, - gpointer user_data) +xfdesktop_settings_update_iconview_folder(AppearancePanel *panel) { - AppearancePanel *panel = user_data; - gchar prop_image_show[1024], prop_image_path[1024]; + gchar prop_last[1024]; + gchar *current_folder; - if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) - return; + TRACE("entering"); - g_snprintf(prop_image_show, sizeof(prop_image_show), - PER_SCREEN_PROP_FORMAT "/image-show", panel->screen, - panel->monitor); - g_snprintf(prop_image_path, sizeof(prop_image_path), - PER_SCREEN_PROP_FORMAT "/image-path", panel->screen, - panel->monitor); - - if(w == panel->radio_singleimage) { - DBG("widget is singleimage"); - if(!panel->image_selector_loaded) { - DBG("about to populate image list with avail backdrops"); - if(!xfdesktop_settings_dialog_populate_image_list(panel)) { - DBG("show_image=%s", panel->show_image?"true":"false"); - if(panel->show_image) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_imagelist), - TRUE); - } else { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_none), - TRUE); - } - return; - } - } + g_snprintf(prop_last, sizeof(prop_last), + PER_WORKSPACE_PROP_FORMAT "/last-image", + panel->screen, panel->monitor, panel->workspace); - gtk_widget_set_sensitive(panel->btn_minus, FALSE); - gtk_widget_set_sensitive(panel->btn_newlist, FALSE); - gtk_widget_set_sensitive(panel->frame_image_list, TRUE); - gtk_widget_set_sensitive(panel->backdrop_cycle_chkbox, FALSE); - gtk_widget_set_sensitive(panel->backdrop_cycle_spinbox, FALSE); - DBG("show_image=%s", panel->show_image?"true":"false"); - if(!panel->show_image) { - panel->show_image = TRUE; - xfconf_channel_set_bool(panel->channel, prop_image_show, TRUE); - } - } else if(w == panel->radio_imagelist) { - DBG("widget is imagelist"); - if(!panel->image_list_loaded) { - DBG("about to populate image list with backdrop list file"); - if(!xfdesktop_settings_dialog_populate_image_list(panel)) { - DBG("show_image=%s", panel->show_image?"true":"false"); - if(panel->show_image) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_singleimage), - TRUE); - } else { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_none), - TRUE); - } - return; - } - } + 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, + g_path_get_dirname(current_folder)); + + g_free(current_folder); - gtk_widget_set_sensitive(panel->btn_minus, TRUE); - gtk_widget_set_sensitive(panel->btn_newlist, TRUE); - gtk_widget_set_sensitive(panel->frame_image_list, TRUE); - gtk_widget_set_sensitive(panel->backdrop_cycle_chkbox, TRUE); - if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(panel->backdrop_cycle_chkbox))) - gtk_widget_set_sensitive(panel->backdrop_cycle_spinbox, TRUE); - else - gtk_widget_set_sensitive(panel->backdrop_cycle_spinbox, FALSE); - DBG("show_image=%s", panel->show_image?"true":"false"); - if(!panel->show_image) { - panel->show_image = TRUE; - xfconf_channel_set_bool(panel->channel, prop_image_show, TRUE); - } - } else if(w == panel->radio_none) { - DBG("widget is none"); - gtk_widget_set_sensitive(panel->frame_image_list, FALSE); - gtk_widget_set_sensitive(panel->backdrop_cycle_chkbox, FALSE); - gtk_widget_set_sensitive(panel->backdrop_cycle_spinbox, FALSE); - DBG("show_image=%s", panel->show_image?"true":"false"); - if(panel->show_image) { - panel->show_image = FALSE; - xfconf_channel_set_bool(panel->channel, prop_image_show, FALSE); - } - } } +/* This function is to add or remove all the bindings for the background + * tab. It's intended to be used when the app changes monitors or workspaces */ static void -cb_show_image_changed(XfconfChannel *channel, - const gchar *property, - const GValue *value, - gpointer user_data) +xfdesktop_settings_background_tab_change_bindings(AppearancePanel *panel, + gint screen_num, + gint monitor_num, + gint workspace_num, + gboolean remove_binding) { - AppearancePanel *panel = user_data; + gchar buf[1024]; + XfconfChannel *channel = panel->channel; + + /* Style combobox */ + g_snprintf(buf, sizeof(buf), PER_WORKSPACE_PROP_FORMAT "/image-style", + screen_num, monitor_num, workspace_num); + if(remove_binding) { + xfconf_g_property_unbind_by_property(channel, buf, + G_OBJECT(panel->image_style_combo), "active"); + } else { + xfconf_g_property_bind(channel, buf, G_TYPE_INT, + G_OBJECT(panel->image_style_combo), "active"); + } - TRACE("entering, value=%s, panel->show_image=%s", - g_value_get_boolean(value)?"true":"false", - panel->show_image?"true":"false"); - if(g_value_get_boolean(value) == panel->show_image) - return; + /* Color options*/ + g_snprintf(buf, sizeof(buf), PER_WORKSPACE_PROP_FORMAT "/color-style", + screen_num, monitor_num, workspace_num); + if(remove_binding) { + xfconf_g_property_unbind_by_property(channel, buf, + G_OBJECT(panel->color_style_combo), "active"); + } else { + xfconf_g_property_bind(channel, buf, G_TYPE_INT, + G_OBJECT(panel->color_style_combo), "active"); + } - if(g_value_get_boolean(value)) { - gchar propname[1024], *filename; - - g_snprintf(propname, sizeof(propname), - PER_SCREEN_PROP_FORMAT "/image-path", - panel->screen, panel->monitor); - filename = xfconf_channel_get_string(channel, propname, NULL); - if(filename && xfdesktop_backdrop_list_is_valid(filename)) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_imagelist), - TRUE); - } else { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_singleimage), - TRUE); - } - g_free(filename); + g_snprintf(buf, sizeof(buf), PER_WORKSPACE_PROP_FORMAT "/color1", + screen_num, monitor_num, workspace_num); + if(remove_binding) { + xfconf_g_property_unbind(panel->color1_btn_id); } else { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_none), - TRUE); + panel->color1_btn_id = xfconf_g_property_bind_gdkcolor(channel, buf, + G_OBJECT(panel->color1_btn), + "color"); } -} -static void -suboptions_set_sensitive(GtkToggleButton *btn, - gpointer user_data) -{ - GtkWidget *box = user_data; - gtk_widget_set_sensitive(box, gtk_toggle_button_get_active(btn)); + g_snprintf(buf, sizeof(buf), PER_WORKSPACE_PROP_FORMAT "/color2", + screen_num, monitor_num, workspace_num); + if(remove_binding) { + xfconf_g_property_unbind(panel->color2_btn_id); + } else { + panel->color2_btn_id = xfconf_g_property_bind_gdkcolor(channel, buf, + G_OBJECT(panel->color2_btn), + "color"); + } + + cb_xfdesktop_combo_color_changed(GTK_COMBO_BOX(panel->color_style_combo), + panel); + + /* Cycle timer options */ + g_snprintf(buf, sizeof(buf), PER_WORKSPACE_PROP_FORMAT "/backdrop-cycle-enable", + screen_num, monitor_num, workspace_num); + if(remove_binding) { + xfconf_g_property_unbind_by_property(channel, buf, + G_OBJECT(panel->backdrop_cycle_chkbox), "active"); + } else { + xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, + G_OBJECT(panel->backdrop_cycle_chkbox), "active"); + } + + g_snprintf(buf, sizeof(buf), PER_WORKSPACE_PROP_FORMAT "/backdrop-cycle-timer", + screen_num, panel->monitor, workspace_num); + if(remove_binding) { + xfconf_g_property_unbind_by_property(channel, buf, + G_OBJECT(gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(panel->backdrop_cycle_spinbox))), + "value"); + } else { + xfconf_g_property_bind(channel, buf, G_TYPE_UINT, + G_OBJECT(gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(panel->backdrop_cycle_spinbox))), + "value"); + } + + g_snprintf(buf, sizeof(buf), PER_WORKSPACE_PROP_FORMAT "/backdrop-cycle-random-order", + screen_num, monitor_num, workspace_num); + if(remove_binding) { + xfconf_g_property_unbind_by_property(channel, buf, + G_OBJECT(panel->random_backdrop_order_chkbox), "active"); + } else { + xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, + G_OBJECT(panel->random_backdrop_order_chkbox), "active"); + } + + cb_xfdesktop_chk_cycle_backdrop_toggled(GTK_CHECK_BUTTON(panel->backdrop_cycle_chkbox), + panel); } static void -image_treeview_drag_data_received(GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection_data, - guint info, - guint time_, - gpointer user_data) +cb_update_background_tab(WnckWindow *wnck_window, + gpointer user_data) { AppearancePanel *panel = user_data; - gboolean file_added; - gchar *p; - GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget)); - PreviewData *pdata = g_new0(PreviewData, 1); + gint screen_num, monitor_num, workspace_num; + 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); + screen_num = gdk_screen_get_number(screen); + monitor_num = gdk_screen_get_monitor_at_window(screen, + gtk_widget_get_window(panel->image_iconview)); + + /* Check to see if something changed */ + if(panel->workspace == workspace_num && + panel->screen == screen_num && + panel->monitor == monitor_num) { + return; + } - pdata->model = g_object_ref(G_OBJECT(model)); + TRACE("screen, monitor, or workspace changed"); - if(TARGET_TEXT_URI_LIST != info - || selection_data->format != 8 - || selection_data->length <= 0) - { - gtk_drag_finish(context, FALSE, FALSE, time_); - return; + /* remove the old bindings */ + if(panel->monitor != -1 && panel->workspace != -1) { + xfdesktop_settings_background_tab_change_bindings(panel, + panel->screen, + panel->monitor, + panel->workspace, + TRUE); } - p = (gchar *)selection_data->data; - while(*p) { - if(*p != '#') { - gchar *q; - - while(g_ascii_isspace(*p)) - p++; - - q = p; - while(*q && *q != '\n' && *q != '\r') - q++; - - if(q > p) { - q--; - while(g_ascii_isspace(*q)) - q--; - - if(!strncmp(p, "file://", 7)) { - /* we only handle file uris */ - gchar oldq, *filename; - - q++; - oldq = *q; - *q = 0; - - filename = g_filename_from_uri(p, NULL, NULL); - if(filename) { - GtkTreeIter *iter = NULL; - - if(g_file_test(filename, G_FILE_TEST_IS_DIR)) { - GDir *dir = g_dir_open(filename, 0, 0); - - if(dir) { - const gchar *name; - gchar buf[PATH_MAX]; - gboolean needs_slash = TRUE; - - if(filename[strlen(filename)-1] == '/') - needs_slash = FALSE; - - while((name = g_dir_read_name(dir))) { - g_snprintf(buf, sizeof(buf), - needs_slash ? "%s/%s" : "%s%s", - filename, name); - iter = xfdesktop_settings_image_treeview_add(model, buf); - if(iter) - pdata->iters = g_slist_prepend(pdata->iters, iter); - } - g_dir_close(dir); - } - } else if(g_file_test(filename, G_FILE_TEST_EXISTS)) { - iter = xfdesktop_settings_image_treeview_add(model, filename); - if(iter) - pdata->iters = g_slist_prepend(pdata->iters, iter); - } - - g_free(filename); - } - - *q = oldq; - } - } - } + panel->workspace = workspace_num; + panel->screen = screen_num; + panel->monitor = monitor_num; - p = strchr(p, '\n'); - if(p) - p++; - } + /* connect the new bindings */ + xfdesktop_settings_background_tab_change_bindings(panel, + panel->screen, + panel->monitor, + panel->workspace, + FALSE); - file_added = !!pdata->iters; + xfdesktop_settings_update_iconview_frame_name(panel, wnck_workspace); + xfdesktop_settings_update_iconview_folder(panel); - if(!pdata->iters - || !g_thread_create(xfdesktop_settings_create_some_previews, - pdata, FALSE, NULL)) - { - if(pdata->iters) - g_critical("Unable to create thread for single image preview."); - g_object_unref(G_OBJECT(pdata->model)); - g_slist_foreach(pdata->iters, (GFunc)gtk_tree_iter_free, NULL); - g_slist_free(pdata->iters); - g_free(pdata); + /* 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 +suboptions_set_sensitive(GtkToggleButton *btn, + gpointer user_data) +{ + GtkWidget *box = user_data; - gtk_drag_finish(context, file_added, FALSE, time_); + TRACE("entering"); - if(file_added && panel->image_list_loaded) - xfdesktop_settings_save_backdrop_list(panel, model); + gtk_widget_set_sensitive(box, gtk_toggle_button_get_active(btn)); } static void -xfdesktop_settings_setup_image_treeview(AppearancePanel *panel) +xfdesktop_settings_setup_image_iconview(AppearancePanel *panel) { - static GtkTargetEntry drag_targets[] = { - { "text/uri-list", 0, TARGET_TEXT_URI_LIST }, - }; - GtkCellRenderer *render; - GtkTreeViewColumn *col; + ExoIconView *iconview = EXO_ICON_VIEW(panel->image_iconview); - render = gtk_cell_renderer_pixbuf_new(); - col = gtk_tree_view_column_new_with_attributes("thumbnail", render, - "pixbuf", COL_PIX, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(panel->image_treeview), - col); - render = gtk_cell_renderer_text_new(); - col = gtk_tree_view_column_new_with_attributes("name", render, - "markup", COL_NAME, NULL); - gtk_tree_view_append_column(GTK_TREE_VIEW(panel->image_treeview), - col); - - g_signal_connect(G_OBJECT(gtk_tree_view_get_selection(GTK_TREE_VIEW(panel->image_treeview))), - "changed", - G_CALLBACK(cb_image_selection_changed), panel); + TRACE("entering"); - gtk_tree_view_enable_model_drag_dest(GTK_TREE_VIEW(panel->image_treeview), - drag_targets, 1, - GDK_ACTION_DEFAULT | GDK_ACTION_COPY); + /* We enable the search here but can't set the search column until + * it's populated, so we'll do that later in cb_folder_selection_changed */ + g_object_set(G_OBJECT(iconview), + "icon-column", COL_PIX, + "item-width", PREVIEW_WIDTH, + "enable-search", TRUE, + NULL); - g_signal_connect(G_OBJECT(panel->image_treeview), "drag-data-received", - G_CALLBACK(image_treeview_drag_data_received), panel); + g_signal_connect(G_OBJECT(iconview), "selection-changed", + G_CALLBACK(cb_image_selection_changed), panel); } static void -xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml, - XfconfChannel *channel) +xfdesktop_settings_dialog_setup_tabs(GtkBuilder *main_gxml, + XfconfChannel *channel, + GdkScreen *screen) { - gint i, j, nmonitors, nscreens; GtkWidget *appearance_container, *chk_custom_font_size, - *spin_font_size, *color_style_widget, *w, *box, - *spin_icon_size, *chk_show_thumbnails, *chk_single_click; + *spin_font_size, *w, *box, *spin_icon_size, + *chk_show_thumbnails, *chk_single_click, *appearance_settings; + 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")); + /* Icons tab */ + /* icon size */ spin_icon_size = GTK_WIDGET(gtk_builder_get_object(main_gxml, "spin_icon_size")); g_signal_connect(G_OBJECT(spin_icon_size), "value-changed", @@ -1323,10 +798,12 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml, DESKTOP_ICONS_ICON_SIZE_PROP, DEFAULT_ICON_SIZE)); + /* font size */ chk_custom_font_size = GTK_WIDGET(gtk_builder_get_object(main_gxml, "chk_custom_font_size")); spin_font_size = GTK_WIDGET(gtk_builder_get_object(main_gxml, "spin_font_size")); + /* single click */ chk_single_click = GTK_WIDGET(gtk_builder_get_object(main_gxml, "chk_single_click")); @@ -1334,6 +811,7 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml, G_CALLBACK(cb_xfdesktop_chk_custom_font_size_toggled), spin_font_size); + /* thumbnails */ chk_show_thumbnails = GTK_WIDGET(gtk_builder_get_object(main_gxml, "chk_show_thumbnails")); /* The default value when this property is not set, is 'TRUE'. @@ -1344,230 +822,96 @@ xfdesktop_settings_dialog_add_screens(GtkBuilder *main_gxml, gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(chk_show_thumbnails), TRUE); - nscreens = gdk_display_get_n_screens(gdk_display_get_default()); + /* Background tab */ + panel->channel = channel; + panel->screen = gdk_screen_get_number(screen); - for(i = 0; i < nscreens; ++i) { - GdkDisplay *gdpy = gdk_display_get_default(); - GdkScreen *screen = gdk_display_get_screen(gdpy, i); - nmonitors = gdk_screen_get_n_monitors(screen); + /* 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))); - if(nscreens > 1 || nmonitors > 1) { - gtk_notebook_set_show_tabs(GTK_NOTEBOOK(appearance_container), TRUE); - gtk_container_set_border_width(GTK_CONTAINER(appearance_container), 12); - } + g_signal_connect(wnck_window, "geometry-changed", + G_CALLBACK(cb_update_background_tab), panel); - for(j = 0; j < nmonitors; ++j) { - - gchar buf[1024]; - GtkBuilder *appearance_gxml; - AppearancePanel *panel = g_new0(AppearancePanel, 1); - GtkWidget *appearance_settings, *appearance_label; - GError *error = NULL; - - panel->channel = channel; - panel->screen = i; - panel->monitor = j; - - if(nscreens > 1 && nmonitors > 1) { - gchar *monitor_name = gdk_screen_get_monitor_plug_name(screen, - j); - if(monitor_name) { - g_snprintf(buf, sizeof(buf), - _("Screen %d, Monitor %d (%s)"), i+1, j+1, - monitor_name); - g_free(monitor_name); - } else - g_snprintf(buf, sizeof(buf), _("Screen %d, Monitor %d"), - i+1, j+1); - } else if(nscreens > 1) - g_snprintf(buf, sizeof(buf), _("Screen %d"), i+1); - else { - gchar *monitor_name = gdk_screen_get_monitor_plug_name(screen, - j); - if(monitor_name) { - g_snprintf(buf, sizeof(buf), _("Monitor %d (%s)"), - j+1, monitor_name); - g_free(monitor_name); - } else - g_snprintf(buf, sizeof(buf), _("Monitor %d"), j+1); - } + /* send invalid numbers so that the update_background_tab will update everything */ + panel->monitor = -1; + panel->workspace = -1; - appearance_gxml = gtk_builder_new(); - if(!gtk_builder_add_from_string(appearance_gxml, - xfdesktop_settings_appearance_frame_ui, - xfdesktop_settings_appearance_frame_ui_length, - &error)) - { - g_printerr("Failed to parse appearance settings UI description: %s\n", - error->message); - g_error_free(error); - exit(1); - } + appearance_gxml = gtk_builder_new(); + if(!gtk_builder_add_from_string(appearance_gxml, + xfdesktop_settings_appearance_frame_ui, + xfdesktop_settings_appearance_frame_ui_length, + &error)) + { + g_printerr("Failed to parse appearance settings UI description: %s\n", + error->message); + g_error_free(error); + exit(1); + } - appearance_settings = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "alignment_settings")); - - appearance_label = gtk_label_new_with_mnemonic(buf); - gtk_widget_show(appearance_label); - - gtk_notebook_append_page(GTK_NOTEBOOK(appearance_container), - appearance_settings, appearance_label); - - /* Connect xfconf bindings */ - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/brightness", - i, j); - panel->brightness_slider = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "slider_brightness")); - xfconf_g_property_bind(channel, buf, G_TYPE_INT, - G_OBJECT(gtk_range_get_adjustment(GTK_RANGE(panel->brightness_slider))), - "value"); - - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/saturation", - i, j); - panel->saturation_slider = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "slider_saturation")); - xfconf_g_property_bind(channel, buf, G_TYPE_DOUBLE, - G_OBJECT(gtk_range_get_adjustment(GTK_RANGE(panel->saturation_slider))), - "value"); - - w = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, "combo_style")); - gtk_combo_box_set_active(GTK_COMBO_BOX(w), 0); - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/image-style", - i, j); - xfconf_g_property_bind(channel, buf, G_TYPE_INT, - G_OBJECT(w), "active"); - - color_style_widget = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "combo_colors")); - gtk_combo_box_set_active(GTK_COMBO_BOX(color_style_widget), 0); - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/color-style", - i, j); - xfconf_g_property_bind(channel, buf, G_TYPE_INT, - G_OBJECT(color_style_widget), "active"); - g_signal_connect(G_OBJECT(color_style_widget), "changed", - G_CALLBACK(cb_xfdesktop_combo_color_changed), - panel); - - panel->color1_btn = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "color1_btn")); - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/color1", - i, j); - xfconf_g_property_bind_gdkcolor(channel, buf, - G_OBJECT(panel->color1_btn), - "color"); - - panel->color2_btn = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "color2_btn")); - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/color2", - i, j); - xfconf_g_property_bind_gdkcolor(channel, buf, - G_OBJECT(panel->color2_btn), - "color"); - - cb_xfdesktop_combo_color_changed(GTK_COMBO_BOX(color_style_widget), - panel); - - panel->frame_image_list = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "frame_image_list")); - - panel->image_treeview = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "treeview_imagelist")); - xfdesktop_settings_setup_image_treeview(panel); - - panel->btn_plus = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, "btn_plus")); - g_signal_connect(G_OBJECT(panel->btn_plus), "clicked", - G_CALLBACK(add_file_button_clicked), panel); - - panel->btn_minus = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "btn_minus")); - g_signal_connect(G_OBJECT(panel->btn_minus), "clicked", - G_CALLBACK(remove_file_button_clicked), panel); - - panel->btn_newlist = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "btn_newlist")); - g_signal_connect(G_OBJECT(panel->btn_newlist), "clicked", - G_CALLBACK(newlist_button_clicked), panel); - - panel->chk_xinerama_stretch = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "chk_xinerama_stretch")); - - /* The first monitor has the option of doing the xinerama-stretch, - * but only if there's multiple monitors attached. Make it invisible - * in all other cases. - */ - if(j == 0 && nmonitors > 1) { - g_snprintf(buf, sizeof(buf), "/backdrop/screen%d/xinerama-stretch", - i); - xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, - G_OBJECT(panel->chk_xinerama_stretch), "active"); - gtk_widget_set_sensitive(panel->chk_xinerama_stretch, TRUE); - } else { - gtk_widget_hide(panel->chk_xinerama_stretch); - } + appearance_settings = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, + "alignment_settings")); - panel->backdrop_cycle_chkbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "chk_cycle_backdrop")); - panel->backdrop_cycle_spinbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "spin_backdrop_time_minutes")); + panel->frame_image_list = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, + "frame_image_list")); - g_signal_connect(G_OBJECT(panel->backdrop_cycle_chkbox), "toggled", - G_CALLBACK(cb_xfdesktop_chk_cycle_backdrop_toggled), - panel->backdrop_cycle_spinbox); + gtk_table_attach_defaults(GTK_TABLE(appearance_container), + appearance_settings, 0,1,0,1); - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/backdrop-cycle-enable", - i, j); - xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, - G_OBJECT(panel->backdrop_cycle_chkbox), "active"); + panel->image_style_combo = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, "combo_style")); - g_snprintf(buf, sizeof(buf), PER_SCREEN_PROP_FORMAT "/backdrop-cycle-timer", - i, j); - xfconf_g_property_bind(channel, buf, G_TYPE_UINT, - G_OBJECT(gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(panel->backdrop_cycle_spinbox))), - "value"); + panel->color_style_combo = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, + "combo_colors")); - panel->radio_singleimage = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "radio_singleimage")); - g_signal_connect(G_OBJECT(panel->radio_singleimage), "toggled", - G_CALLBACK(cb_image_type_radio_clicked), panel); - panel->radio_imagelist = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "radio_imagelist")); - g_signal_connect(G_OBJECT(panel->radio_imagelist), "toggled", - G_CALLBACK(cb_image_type_radio_clicked), panel); - panel->radio_none = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, - "radio_none")); - g_signal_connect(G_OBJECT(panel->radio_none), "toggled", - G_CALLBACK(cb_image_type_radio_clicked), panel); - g_snprintf(buf, sizeof(buf), - "property-changed::" PER_SCREEN_PROP_FORMAT "/image-show", - i, j); - g_signal_connect(G_OBJECT(channel), buf, - G_CALLBACK(cb_show_image_changed), panel); - - if(!xfconf_channel_get_bool(channel, buf+18, TRUE)) { - panel->show_image = FALSE; - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_none), - TRUE); - } else { - gchar *image_path = NULL; + /* 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); - panel->show_image = TRUE; + g_signal_connect(G_OBJECT(panel->color_style_combo), "changed", + G_CALLBACK(cb_xfdesktop_combo_color_changed), + panel); - g_snprintf(buf, sizeof(buf), - PER_SCREEN_PROP_FORMAT "/image-path", i, j); - image_path = xfconf_channel_get_string(channel, buf, NULL); - if(image_path && xfdesktop_backdrop_list_is_valid(image_path)) { - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(panel->radio_imagelist), - TRUE); - } else - xfdesktop_settings_dialog_populate_image_list(panel); - g_free(image_path); + 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_object_unref(G_OBJECT(appearance_gxml)); - } - } + /* icon view area */ + panel->frame_image_list = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, + "frame_image_list")); + + panel->image_iconview = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, + "iconview_imagelist")); + xfdesktop_settings_setup_image_iconview(panel); + + /* folder: file chooser button */ + panel->btn_folder = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, "btn_folder")); + g_signal_connect(G_OBJECT(panel->btn_folder), "selection-changed", + G_CALLBACK(cb_folder_selection_changed), panel); + filter = gtk_file_filter_new(); + gtk_file_filter_set_name(filter, _("Image files")); + gtk_file_filter_add_pixbuf_formats(filter); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(panel->btn_folder), filter); + + /* background cycle timer */ + panel->backdrop_cycle_chkbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, + "chk_cycle_backdrop")); + panel->backdrop_cycle_spinbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, + "spin_backdrop_time_minutes")); + panel->random_backdrop_order_chkbox = GTK_WIDGET(gtk_builder_get_object(appearance_gxml, + "chk_random_backdrop_order")); + + g_signal_connect(G_OBJECT(panel->backdrop_cycle_chkbox), "toggled", + G_CALLBACK(cb_xfdesktop_chk_cycle_backdrop_toggled), + panel); + + g_object_unref(G_OBJECT(appearance_gxml)); + + + /* Menus Tab */ w = GTK_WIDGET(gtk_builder_get_object(main_gxml, "chk_show_desktop_menu")); xfconf_g_property_bind(channel, SHOW_DESKTOP_MENU_PROP, G_TYPE_BOOLEAN, G_OBJECT(w), "active"); @@ -1709,13 +1053,13 @@ main(int argc, char **argv) channel = xfconf_channel_new(XFDESKTOP_CHANNEL); - xfdesktop_settings_dialog_add_screens(gxml, channel); - if(opt_socket_id == 0) { 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)); /* To prevent the settings dialog to be saved in the session */ gdk_set_sm_client_id("FAKE ID"); @@ -1728,6 +1072,8 @@ 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(); diff --git a/settings/xfdesktop-settings-appearance-frame-ui.glade b/settings/xfdesktop-settings-appearance-frame-ui.glade index a397d94..b658ac5 100644 --- a/settings/xfdesktop-settings-appearance-frame-ui.glade +++ b/settings/xfdesktop-settings-appearance-frame-ui.glade @@ -1,22 +1,6 @@ - - 127 - -128 - 10 - 1 - 0 - 0 - - - 10 - -10 - 10 - 0.10000000000000001 - 0 - 1 - 65535 1 @@ -25,31 +9,6 @@ 0 10 - - - - - - - Auto - - - Centered - - - Tiled - - - Stretched - - - Scaled - - - Zoomed - - - @@ -104,12 +63,10 @@ GTK_POLICY_AUTOMATIC GTK_SHADOW_ETCHED_IN - + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False - 1 @@ -120,74 +77,32 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 3 - + True - True - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Add an image to the list - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-add - 1 - - - - - False - - - - - True - False - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Remove the selected image(s) from the list - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-remove - 1 - - + Folder: + True False - False - 1 - + True - False True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Create a new list, or load an existing one - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - gtk-new - 1 - - + Add an image to the list + GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER + 30 False - 4 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK St_yle: @@ -196,151 +111,39 @@ False - 3 - GTK_PACK_END - 3 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK Specify how the image will be resized to fit the screen - model1 - - - - 0 - - + + None + Centered + Tiled + Stretched + Scaled + Zoomed + False - GTK_PACK_END - 2 - - - False - 1 - - - - - - - - - True - <b>Images</b> - True - - - - - - - True - 6 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - GTK_SHADOW_NONE - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 6 - 6 - - - True - + True - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Select a single image as the backdrop - _Single image + Color: True - True - True - False - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Automatically pick a random image from a list file - Image _list - True - True - radio_singleimage - - - - False - 1 - - - - - True - True - Don't display an image at all - _None - True - True - radio_singleimage - - - False - 2 - - - - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Image</b> - True - - - - - False - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - GTK_SHADOW_NONE - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 6 - 6 - - - True - 6 - True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -359,182 +162,48 @@ - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - - - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Specifies the solid color, or the "left" or "top" color of the gradient - Select First Color - #151522223333 - - - - False - - - - - True - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Specifies the "right" or "bottom" color of the gradient - Select Second Color - #151522223333 - - - - False - 1 - - + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Specifies the solid color, or the "left" or "top" color of the gradient + Select First Color + #151522223333 + - 1 + False + + + + + True + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Specifies the "right" or "bottom" color of the gradient + Select Second Color + #151522223333 + + + + False - - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Colors</b> - True - - - - - False - 1 - - - - - 1 - False - - - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - GTK_SHADOW_NONE - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 6 - 6 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 6 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 4 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - B_rightness: - True - slider_brightness - - - False - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Increase or decrease the brightness of the final image - GTK_UPDATE_DISCONTINUOUS - adjustment1 - 0 - GTK_POS_RIGHT - - - - 1 - - - - - False - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Sa_turation: - True - slider_saturation False - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Increase or decrease the color saturation of the final image - GTK_UPDATE_DISCONTINUOUS - adjustment2 - GTK_POS_RIGHT - - - 1 - - False - 1 - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Adjustments</b> - True - - - - False - 1 - @@ -544,11 +213,11 @@ True - False + True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK _Change the background (in minutes): - While in image list mode, select this option to automatically select a different background from the image list after a set number of minutes. + Automatically select a different background from the current directory after a set number of minutes. True True @@ -563,35 +232,33 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK adjustment3 - Number of minutes before a different background is randomly selected from the list. + Number of minutes before a different background is selected. False 2 + + + True + False + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + _Random Order + True + True + + + False + + False 2 - - - True - False - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - St_retch this background across all monitors. - When multiple monitors are present, select this option to stretch the current background over all of them. - True - True - - - False - 3 - - diff --git a/settings/xfdesktop-settings-ui.glade b/settings/xfdesktop-settings-ui.glade index eef177e..7bccb6b 100644 --- a/settings/xfdesktop-settings-ui.glade +++ b/settings/xfdesktop-settings-ui.glade @@ -1,22 +1,6 @@ - - 127 - -128 - 10 - 1 - 0 - 0 - - - 10 - -10 - 10 - 0.10000000000000001 - 0 - 1 - 192 8 @@ -33,58 +17,6 @@ 0 12 - - 100 - 0 - 10 - 1 - 0 - 40 - - - - - - - - Auto - - - Centered - - - Tiled - - - Stretched - - - Scaled - - - Zoomed - - - - - - - - - - Solid color - - - Horizontal gradient - - - Vertical gradient - - - Transparent - - - @@ -179,6 +111,8 @@ GDK_WINDOW_TYPE_HINT_DIALOG False Set desktop background and menu and icon behavior + 640 + 480 True @@ -194,14 +128,9 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 6 - + True True - False - False - - - @@ -742,40 +671,6 @@ 2 - - - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Label trans_parency: - True - - - False - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Specify the transparency level for the rounded label drawn behind the icon text - adjustment5 - 0 - GTK_POS_RIGHT - - - 1 - - - - - 3 - - diff --git a/src/Makefile.am b/src/Makefile.am index adeac0b..4d73dad 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,6 +22,8 @@ xfdesktop_SOURCES = \ windowlist.h \ xfce-backdrop.c \ xfce-backdrop.h \ + xfce-workspace.c \ + xfce-workspace.h \ xfce-desktop.c \ xfce-desktop.h diff --git a/src/xfce-backdrop.c b/src/xfce-backdrop.c index b07492f..6d7f9db 100644 --- a/src/xfce-backdrop.c +++ b/src/xfce-backdrop.c @@ -64,18 +64,16 @@ struct _XfceBackdropPriv XfceBackdropColorStyle color_style; GdkColor color1; GdkColor color2; - - gboolean show_image; + XfceBackdropImageStyle image_style; gchar *image_path; - gchar *backdrop_list; - + gint brightness; - gdouble saturation; gboolean cycle_backdrop; guint cycle_timer; guint cycle_timer_id; + gboolean random_backdrop_order; }; enum @@ -91,13 +89,12 @@ enum PROP_COLOR_STYLE, PROP_COLOR1, PROP_COLOR2, - PROP_SHOW_IMAGE, PROP_IMAGE_STYLE, PROP_IMAGE_FILENAME, PROP_BRIGHTNESS, - PROP_SATURATION, PROP_BACKDROP_CYCLE_ENABLE, PROP_BACKDROP_CYCLE_TIMER, + PROP_BACKDROP_RANDOM_ORDER }; static guint backdrop_signals[LAST_SIGNAL] = { 0, }; @@ -284,19 +281,12 @@ xfce_backdrop_class_init(XfceBackdropClass *klass) GDK_TYPE_COLOR, XFDESKTOP_PARAM_FLAGS)); - g_object_class_install_property(gobject_class, PROP_SHOW_IMAGE, - g_param_spec_boolean("show-image", - "show image", - "show image", - TRUE, - XFDESKTOP_PARAM_FLAGS)); - g_object_class_install_property(gobject_class, PROP_IMAGE_STYLE, g_param_spec_enum("image-style", "image style", "image style", XFCE_TYPE_BACKDROP_IMAGE_STYLE, - XFCE_BACKDROP_IMAGE_AUTO, + XFCE_BACKDROP_IMAGE_SCALED, XFDESKTOP_PARAM_FLAGS)); g_object_class_install_property(gobject_class, PROP_IMAGE_FILENAME, @@ -313,13 +303,6 @@ xfce_backdrop_class_init(XfceBackdropClass *klass) -128, 127, 0, XFDESKTOP_PARAM_FLAGS)); - g_object_class_install_property(gobject_class, PROP_SATURATION, - g_param_spec_double("saturation", - "saturation", - "saturation", - -10.0, 10.0, 1.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", @@ -334,6 +317,13 @@ xfce_backdrop_class_init(XfceBackdropClass *klass) 0, G_MAXUSHORT, 10, XFDESKTOP_PARAM_FLAGS)); + g_object_class_install_property(gobject_class, PROP_BACKDROP_RANDOM_ORDER, + g_param_spec_boolean("backdrop-cycle-random-order", + "backdrop-cycle-random-order", + "backdrop-cycle-random-order", + FALSE, + XFDESKTOP_PARAM_FLAGS)); + #undef XFDESKTOP_PARAM_FLAGS } @@ -342,9 +332,7 @@ xfce_backdrop_init(XfceBackdrop *backdrop) { backdrop->priv = G_TYPE_INSTANCE_GET_PRIVATE(backdrop, XFCE_TYPE_BACKDROP, XfceBackdropPriv); - backdrop->priv->show_image = TRUE; backdrop->priv->cycle_timer_id = 0; - backdrop->priv->backdrop_list = NULL; /* color defaults */ backdrop->priv->color1.red = 0x1515; @@ -370,11 +358,6 @@ xfce_backdrop_finalize(GObject *object) backdrop->priv->cycle_timer_id = 0; } - if(backdrop->priv->backdrop_list != NULL) { - g_free(backdrop->priv->backdrop_list); - backdrop->priv->backdrop_list = NULL; - } - G_OBJECT_CLASS(xfce_backdrop_parent_class)->finalize(object); } @@ -404,10 +387,6 @@ xfce_backdrop_set_property(GObject *object, xfce_backdrop_set_second_color(backdrop, color); break; - case PROP_SHOW_IMAGE: - xfce_backdrop_set_show_image(backdrop, g_value_get_boolean(value)); - break; - case PROP_IMAGE_STYLE: xfce_backdrop_set_image_style(backdrop, g_value_get_enum(value)); break; @@ -421,10 +400,6 @@ xfce_backdrop_set_property(GObject *object, xfce_backdrop_set_brightness(backdrop, g_value_get_int(value)); break; - case PROP_SATURATION: - xfce_backdrop_set_saturation(backdrop, g_value_get_double(value)); - break; - case PROP_BACKDROP_CYCLE_ENABLE: xfce_backdrop_set_cycle_backdrop(backdrop, g_value_get_boolean(value)); break; @@ -433,6 +408,10 @@ xfce_backdrop_set_property(GObject *object, xfce_backdrop_set_cycle_timer(backdrop, g_value_get_uint(value)); break; + case PROP_BACKDROP_RANDOM_ORDER: + xfce_backdrop_set_random_order(backdrop, g_value_get_boolean(value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -460,10 +439,6 @@ xfce_backdrop_get_property(GObject *object, g_value_set_boxed(value, &backdrop->priv->color2); break; - case PROP_SHOW_IMAGE: - g_value_set_boolean(value, xfce_backdrop_get_show_image(backdrop)); - break; - case PROP_IMAGE_STYLE: g_value_set_enum(value, xfce_backdrop_get_image_style(backdrop)); break; @@ -477,10 +452,6 @@ xfce_backdrop_get_property(GObject *object, g_value_set_int(value, xfce_backdrop_get_brightness(backdrop)); break; - case PROP_SATURATION: - g_value_set_double(value, xfce_backdrop_get_saturation(backdrop)); - break; - case PROP_BACKDROP_CYCLE_ENABLE: g_value_set_boolean(value, xfce_backdrop_get_cycle_backdrop(backdrop)); break; @@ -489,6 +460,10 @@ xfce_backdrop_get_property(GObject *object, g_value_set_uint(value, xfce_backdrop_get_cycle_timer(backdrop)); break; + case PROP_BACKDROP_RANDOM_ORDER: + g_value_set_boolean(value, xfce_backdrop_get_random_order(backdrop)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); break; @@ -670,32 +645,6 @@ xfce_backdrop_get_second_color(XfceBackdrop *backdrop, } /** - * xfce_backdrop_set_show_image: - * @backdrop: An #XfceBackdrop. - * @show_image: Whether or not to composite the image on top of the color. - * - * Sets whether or not the #XfceBackdrop should consist of an image composited - * on top of a color (or color gradient), or just a color (or color gradient). - **/ -void -xfce_backdrop_set_show_image(XfceBackdrop *backdrop, gboolean show_image) -{ - g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); - - if(backdrop->priv->show_image != show_image) { - backdrop->priv->show_image = show_image; - g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CHANGED], 0); - } -} - -gboolean -xfce_backdrop_get_show_image(XfceBackdrop *backdrop) -{ - g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), FALSE); - return backdrop->priv->show_image; -} - -/** * xfce_backdrop_set_image_style: * @backdrop: An #XfceBackdrop. * @style: An XfceBackdropImageStyle. @@ -739,7 +688,9 @@ void xfce_backdrop_set_image_filename(XfceBackdrop *backdrop, const gchar *filename) { g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); - + + TRACE("entering"); + g_free(backdrop->priv->image_path); if(filename) @@ -758,37 +709,6 @@ xfce_backdrop_get_image_filename(XfceBackdrop *backdrop) } /** - * xfce_backdrop_set_list: - * @backdrop: An #XfceBackdrop. - * @backdrop_list: A list of backdrop images. - * - * Sets the internal list of wallpaper images assigned to this backdrop. - * Frees any previous backdrop list before setting the new one. - * [Transfer full] - **/ -void -xfce_backdrop_set_list(XfceBackdrop *backdrop, - gchar *backdrop_list) -{ - g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); - - if(backdrop->priv->backdrop_list != NULL) { - g_free(backdrop->priv->backdrop_list); - backdrop->priv->backdrop_list = NULL; - } - - backdrop->priv->backdrop_list = backdrop_list; -} - -G_CONST_RETURN gchar* -xfce_backdrop_get_list(XfceBackdrop *backdrop) -{ - g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), NULL); - - return backdrop->priv->backdrop_list; -} - -/** * xfce_backdrop_set_brightness: * @backdrop: An #XfceBackdrop. * @brightness: A brightness value. @@ -815,24 +735,6 @@ xfce_backdrop_get_brightness(XfceBackdrop *backdrop) return backdrop->priv->brightness; } -void -xfce_backdrop_set_saturation(XfceBackdrop *backdrop, - gdouble saturation) -{ - g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); - if(abs(saturation - backdrop->priv->saturation) > 0.05) { - backdrop->priv->saturation = saturation; - g_signal_emit(G_OBJECT(backdrop), backdrop_signals[BACKDROP_CHANGED], 0); - } -} - -gdouble -xfce_backdrop_get_saturation(XfceBackdrop *backdrop) -{ - g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), 1.0); - return backdrop->priv->saturation; -} - static gboolean xfce_backdrop_timer(XfceBackdrop *backdrop) { @@ -911,6 +813,25 @@ xfce_backdrop_get_cycle_backdrop(XfceBackdrop *backdrop) return backdrop->priv->cycle_backdrop; } +void +xfce_backdrop_set_random_order(XfceBackdrop *backdrop, + gboolean random_order) +{ + g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); + + TRACE("entering"); + + backdrop->priv->random_backdrop_order = random_order; +} + +gboolean +xfce_backdrop_get_random_order(XfceBackdrop *backdrop) +{ + g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), FALSE); + + return backdrop->priv->random_backdrop_order; +} + /** * xfce_backdrop_get_pixbuf: * @backdrop: An #XfceBackdrop. @@ -933,7 +854,8 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) g_return_val_if_fail(XFCE_IS_BACKDROP(backdrop), NULL); - if(backdrop->priv->show_image && backdrop->priv->image_path) { + if(backdrop->priv->image_style != XFCE_BACKDROP_IMAGE_NONE && + backdrop->priv->image_path) { image = gdk_pixbuf_new_from_file(backdrop->priv->image_path, NULL); if(image) { iw = gdk_pixbuf_get_width(image); @@ -970,13 +892,7 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) return final_image; } - if(backdrop->priv->image_style == XFCE_BACKDROP_IMAGE_AUTO) { - if(ih <= h / 2 && iw <= w / 2) - istyle = XFCE_BACKDROP_IMAGE_TILED; - else - istyle = XFCE_BACKDROP_IMAGE_ZOOMED; - } else - istyle = backdrop->priv->image_style; + istyle = backdrop->priv->image_style; /* if the image is the same as the screen size, there's no reason to do * any scaling at all */ @@ -1033,6 +949,7 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) break; case XFCE_BACKDROP_IMAGE_STRETCHED: + case XFCE_BACKDROP_IMAGE_SPANNING_SCREENS: xscale = (gdouble)w / iw; yscale = (gdouble)h / ih; gdk_pixbuf_composite(image, final_image, 0, 0, w, h, @@ -1084,12 +1001,6 @@ xfce_backdrop_get_pixbuf(XfceBackdrop *backdrop) if(backdrop->priv->brightness != 0) final_image = adjust_brightness(final_image, backdrop->priv->brightness); - - if(backdrop->priv->saturation > 1.01 || backdrop->priv->saturation < 0.99) { - gdk_pixbuf_saturate_and_pixelate(final_image, final_image, - (gfloat)backdrop->priv->saturation, - FALSE); - } return final_image; } diff --git a/src/xfce-backdrop.h b/src/xfce-backdrop.h index 78ba6b0..6c013c3 100644 --- a/src/xfce-backdrop.h +++ b/src/xfce-backdrop.h @@ -40,12 +40,13 @@ typedef struct _XfceBackdropPriv XfceBackdropPriv; typedef enum { - XFCE_BACKDROP_IMAGE_AUTO = 0, + XFCE_BACKDROP_IMAGE_NONE = 0, XFCE_BACKDROP_IMAGE_CENTERED, XFCE_BACKDROP_IMAGE_TILED, XFCE_BACKDROP_IMAGE_STRETCHED, XFCE_BACKDROP_IMAGE_SCALED, XFCE_BACKDROP_IMAGE_ZOOMED, + XFCE_BACKDROP_IMAGE_SPANNING_SCREENS, } XfceBackdropImageStyle; typedef enum @@ -100,10 +101,6 @@ void xfce_backdrop_set_second_color (XfceBackdrop *backdrop, void xfce_backdrop_get_second_color (XfceBackdrop *backdrop, GdkColor *color); -void xfce_backdrop_set_show_image (XfceBackdrop *backdrop, - gboolean show_image); -gboolean xfce_backdrop_get_show_image (XfceBackdrop *backdrop); - void xfce_backdrop_set_image_style (XfceBackdrop *backdrop, XfceBackdropImageStyle style); XfceBackdropImageStyle xfce_backdrop_get_image_style @@ -114,19 +111,11 @@ void xfce_backdrop_set_image_filename (XfceBackdrop *backdrop, G_CONST_RETURN gchar *xfce_backdrop_get_image_filename (XfceBackdrop *backdrop); -void xfce_backdrop_set_list (XfceBackdrop *backdrop, - gchar *backdrop_list); -G_CONST_RETURN gchar *xfce_backdrop_get_list - (XfceBackdrop *backdrop); void xfce_backdrop_set_brightness (XfceBackdrop *backdrop, gint brightness); gint xfce_backdrop_get_brightness (XfceBackdrop *backdrop); -void xfce_backdrop_set_saturation (XfceBackdrop *backdrop, - gdouble saturation); -gdouble xfce_backdrop_get_saturation (XfceBackdrop *backdrop); - void xfce_backdrop_set_cycle_backdrop (XfceBackdrop *backdrop, gboolean cycle_backdrop); gboolean xfce_backdrop_get_cycle_backdrop(XfceBackdrop *backdrop); @@ -135,6 +124,10 @@ void xfce_backdrop_set_cycle_timer (XfceBackdrop *backdrop, guint cycle_timer); guint xfce_backdrop_get_cycle_timer (XfceBackdrop *backdrop); +void xfce_backdrop_set_random_order (XfceBackdrop *backdrop, + gboolean random_order); +gboolean xfce_backdrop_get_random_order (XfceBackdrop *backdrop); + GdkPixbuf *xfce_backdrop_get_pixbuf (XfceBackdrop *backdrop); G_END_DECLS diff --git a/src/xfce-desktop.c b/src/xfce-desktop.c index 526ecf7..134fccf 100644 --- a/src/xfce-desktop.c +++ b/src/xfce-desktop.c @@ -77,10 +77,12 @@ #include #include +#include #include "xfdesktop-common.h" #include "xfce-desktop.h" #include "xfce-desktop-enum-types.h" +#include "xfce-workspace.h" /* disable setting the x background for bug 7442 */ //#define DISABLE_FOR_BUG7442 @@ -88,6 +90,7 @@ struct _XfceDesktopPriv { GdkScreen *gscreen; + WnckScreen *wnck_screen; gboolean updates_frozen; XfconfChannel *channel; @@ -95,10 +98,9 @@ struct _XfceDesktopPriv GdkPixmap *bg_pixmap; - guint nbackdrops; - XfceBackdrop **backdrops; - - gboolean xinerama_stretch; + gint nworkspaces; + XfceWorkspace **workspaces; + gint current_workspace; SessionLogoutFunc session_logout_func; @@ -122,7 +124,6 @@ enum enum { PROP_0 = 0, - PROP_XINERAMA_STRETCH, #ifdef ENABLE_DESKTOP_ICONS PROP_ICON_STYLE, PROP_ICON_SIZE, @@ -155,9 +156,7 @@ static gboolean xfce_desktop_delete_event(GtkWidget *w, static void xfce_desktop_style_set(GtkWidget *w, GtkStyle *old_style); -static void xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop, - XfceBackdrop *backdrop, - guint monitor); +static gint xfce_desktop_get_current_workspace(XfceDesktop *desktop); static guint signals[N_SIGNALS] = { 0, }; @@ -173,9 +172,6 @@ xfce_desktop_ensure_system_font_size(XfceDesktop *desktop) PangoFontDescription *pfd; gscreen = gtk_widget_get_screen(GTK_WIDGET(desktop)); - /* FIXME: needed? */ - if(!gscreen) - gscreen = gdk_display_get_default_screen(gdk_display_get_default()); settings = gtk_settings_get_for_screen(gscreen); g_object_get(G_OBJECT(settings), "gtk-font-name", &font_name, NULL); @@ -313,8 +309,7 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data) GdkScreen *gscreen = desktop->priv->gscreen; GdkPixbuf *pix; GdkRectangle rect; - guint i; - gint monitor = -1; + gint i, monitor = -1, current_workspace; TRACE("entering"); @@ -324,9 +319,11 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data) return; TRACE("really entering"); - - for(i = 0; i < XFCE_DESKTOP(desktop)->priv->nbackdrops; i++) { - if(backdrop == XFCE_DESKTOP(desktop)->priv->backdrops[i]) { + + current_workspace = xfce_desktop_get_current_workspace(desktop); + + 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; break; } @@ -339,15 +336,15 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data) if(!pix) return; - if(desktop->priv->xinerama_stretch) { + if(xfce_desktop_get_n_monitors(desktop) > 1 + && xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) { GdkRectangle monitor_rect; gdk_screen_get_monitor_geometry(gscreen, 0, &rect); - /* Get the lowest x and y value for all the monitors in * case none of them start at 0,0 for whatever reason. */ - for(i = 1; i < (guint)gdk_screen_get_n_monitors(gscreen); i++) { + for(i = 1; i < xfce_desktop_get_n_monitors(desktop); i++) { gdk_screen_get_monitor_geometry(gscreen, i, &monitor_rect); if(monitor_rect.x < rect.x) @@ -381,36 +378,16 @@ backdrop_changed_cb(XfceBackdrop *backdrop, gpointer user_data) } static void -backdrop_cycle_cb(XfceBackdrop *backdrop, gpointer user_data) +screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data) { - const gchar* backdrop_list; + XfceDesktop *desktop = user_data; + gint w, h, current_workspace; + XfceBackdrop *current_backdrop; TRACE("entering"); - g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); - - backdrop_list = xfce_backdrop_get_list(backdrop); - - if(xfdesktop_backdrop_list_is_valid(backdrop_list)) { - gchar *backdrop_file; - GError *error = NULL; - - backdrop_file = xfdesktop_backdrop_list_choose_random(backdrop_list, - &error); - - xfce_backdrop_set_image_filename(backdrop, backdrop_file); - g_free(backdrop_file); - backdrop_changed_cb(backdrop, user_data); - } -} - -static void -screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data) -{ - XfceDesktop *desktop = user_data; - gint w, h; - g_return_if_fail(XFCE_IS_DESKTOP(desktop)); + g_return_if_fail(desktop->priv->workspaces); w = gdk_screen_get_width(gscreen); h = gdk_screen_get_height(gscreen); @@ -425,20 +402,26 @@ screen_size_changed_cb(GdkScreen *gscreen, gpointer user_data) desktop->priv->bg_pixmap); gdk_window_set_back_pixmap(GTK_WIDGET(desktop)->window, desktop->priv->bg_pixmap, FALSE); - + + current_workspace = xfce_desktop_get_current_workspace(desktop); + + if(desktop->priv->nworkspaces <= current_workspace) + return; + /* special case for 1 backdrop to handle xinerama stretching */ - if(desktop->priv->xinerama_stretch) { - xfce_backdrop_set_size(desktop->priv->backdrops[0], w, h); - backdrop_changed_cb(desktop->priv->backdrops[0], desktop); + 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; - guint i; + gint i; - for(i = 0; i < desktop->priv->nbackdrops; i++) { + for(i = 0; i < xfce_desktop_get_n_monitors(desktop); i++) { gdk_screen_get_monitor_geometry(gscreen, i, &rect); - xfce_backdrop_set_size(desktop->priv->backdrops[i], rect.width, - rect.height); - backdrop_changed_cb(desktop->priv->backdrops[i], desktop); + 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); } } } @@ -447,6 +430,7 @@ static void screen_composited_changed_cb(GdkScreen *gscreen, gpointer user_data) { + TRACE("entering"); /* fake a screen size changed, so the background is properly set */ screen_size_changed_cb(gscreen, user_data); } @@ -456,66 +440,110 @@ xfce_desktop_monitors_changed(GdkScreen *gscreen, gpointer user_data) { XfceDesktop *desktop = XFCE_DESKTOP(user_data); - guint i; + gint i; - if(desktop->priv->xinerama_stretch) { - if(desktop->priv->nbackdrops > 1) { - for(i = 1; i < desktop->priv->nbackdrops; ++i) - g_object_unref(G_OBJECT(desktop->priv->backdrops[i])); - } + TRACE("entering"); - if(desktop->priv->nbackdrops != 1) { - desktop->priv->backdrops = g_realloc(desktop->priv->backdrops, - sizeof(XfceBackdrop *)); - if(!desktop->priv->nbackdrops) { - GdkVisual *vis = gtk_widget_get_visual(GTK_WIDGET(desktop)); - desktop->priv->backdrops[0] = xfce_backdrop_new(vis); - xfce_desktop_connect_backdrop_settings(desktop, - desktop->priv->backdrops[0], - 0); - g_signal_connect(G_OBJECT(desktop->priv->backdrops[0]), - "changed", - G_CALLBACK(backdrop_changed_cb), desktop); - g_signal_connect(G_OBJECT(desktop->priv->backdrops[0]), - "cycle", - G_CALLBACK(backdrop_cycle_cb), desktop); - } - desktop->priv->nbackdrops = 1; - } - } else { - guint n_monitors = gdk_screen_get_n_monitors(gscreen); + /* Update the workspaces */ + for(i = 0; i < desktop->priv->nworkspaces; i++) { + xfce_workspace_monitors_changed(desktop->priv->workspaces[i], + gscreen); + } - if(n_monitors < desktop->priv->nbackdrops) { - for(i = n_monitors; i < desktop->priv->nbackdrops; ++i) - g_object_unref(G_OBJECT(desktop->priv->backdrops[i])); - } + /* fake a screen size changed, so the background is properly set */ + screen_size_changed_cb(gscreen, user_data); +} - if(n_monitors != desktop->priv->nbackdrops) { - desktop->priv->backdrops = g_realloc(desktop->priv->backdrops, - sizeof(XfceBackdrop *) * n_monitors); - if(n_monitors > desktop->priv->nbackdrops) { - GdkVisual *vis = gtk_widget_get_visual(GTK_WIDGET(desktop)); - for(i = desktop->priv->nbackdrops; i < n_monitors; ++i) { - desktop->priv->backdrops[i] = xfce_backdrop_new(vis); - xfce_desktop_connect_backdrop_settings(desktop, - desktop->priv->backdrops[i], - i); - g_signal_connect(G_OBJECT(desktop->priv->backdrops[i]), - "changed", - G_CALLBACK(backdrop_changed_cb), - desktop); - g_signal_connect(G_OBJECT(desktop->priv->backdrops[i]), - "cycle", - G_CALLBACK(backdrop_cycle_cb), - desktop); - } - } - desktop->priv->nbackdrops = n_monitors; - } - } +static void +workspace_backdrop_changed_cb(XfceWorkspace *workspace, + XfceBackdrop *backdrop, + gpointer user_data) +{ + XfceDesktop *desktop = XFCE_DESKTOP(user_data); + + TRACE("entering"); + + g_return_if_fail(XFCE_IS_WORKSPACE(workspace) && XFCE_IS_BACKDROP(backdrop)); + + if(desktop->priv->current_workspace == xfce_workspace_get_workspace_num(workspace)) + backdrop_changed_cb(backdrop, user_data); +} + +static void +workspace_changed_cb(WnckScreen *wnck_screen, + WnckWorkspace *previously_active_space, + gpointer user_data) +{ + XfceDesktop *desktop = XFCE_DESKTOP(user_data); + WnckWorkspace *wnck_workspace = wnck_screen_get_active_workspace(wnck_screen); + + TRACE("entering"); + + desktop->priv->current_workspace = wnck_workspace_get_number(wnck_workspace); + + /* fake a screen size changed, so the background is properly set */ + screen_size_changed_cb(desktop->priv->gscreen, user_data); +} + +static void +workspace_created_cb(WnckScreen *wnck_screen, + WnckWorkspace *new_workspace, + gpointer user_data) +{ + XfceDesktop *desktop = XFCE_DESKTOP(user_data); + gint nlast_workspace; + TRACE("entering"); - /* update the total size of the screen and the size of each backdrop */ - screen_size_changed_cb(gscreen, desktop); + nlast_workspace = desktop->priv->nworkspaces; + + /* add one more workspace */ + desktop->priv->nworkspaces = nlast_workspace + 1; + + /* allocate size for it */ + desktop->priv->workspaces = g_realloc(desktop->priv->workspaces, + desktop->priv->nworkspaces * sizeof(XfceWorkspace *)); + + /* create the new workspace and set it up */ + desktop->priv->workspaces[nlast_workspace] = xfce_workspace_new(desktop->priv->gscreen, + desktop->priv->channel, + desktop->priv->property_prefix, + nlast_workspace); + + xfce_workspace_monitors_changed(desktop->priv->workspaces[nlast_workspace], + desktop->priv->gscreen); + + g_signal_connect(desktop->priv->workspaces[nlast_workspace], + "workspace-backdrop-changed", + G_CALLBACK(workspace_backdrop_changed_cb), desktop); +} + +static void +workspace_destroyed_cb(WnckScreen *wnck_screen, + WnckWorkspace *old_workspace, + gpointer user_data) +{ + XfceDesktop *desktop = XFCE_DESKTOP(user_data); + gint nlast_workspace; + TRACE("entering"); + + g_return_if_fail(XFCE_IS_DESKTOP(desktop)); + g_return_if_fail(desktop->priv->nworkspaces - 1 >= 0); + g_return_if_fail(XFCE_IS_WORKSPACE(desktop->priv->workspaces[desktop->priv->nworkspaces-1])); + + nlast_workspace = desktop->priv->nworkspaces - 1; + + g_signal_handlers_disconnect_by_func(desktop->priv->workspaces[nlast_workspace], + G_CALLBACK(workspace_backdrop_changed_cb), + desktop); + + g_object_unref(desktop->priv->workspaces[nlast_workspace]); + + /* Remove one workspace */ + desktop->priv->nworkspaces = nlast_workspace; + + /* deallocate it */ + desktop->priv->workspaces = g_realloc(desktop->priv->workspaces, + desktop->priv->nworkspaces * sizeof(XfceWorkspace *)); } static void @@ -620,13 +648,6 @@ xfce_desktop_class_init(XfceDesktopClass *klass) | G_PARAM_STATIC_NICK \ | G_PARAM_STATIC_BLURB) - g_object_class_install_property(gobject_class, PROP_XINERAMA_STRETCH, - g_param_spec_boolean("xinerama-stretch", - "xinerama stretch", - "xinerama stretch", - FALSE, - XFDESKTOP_PARAM_FLAGS)); - #ifdef ENABLE_DESKTOP_ICONS g_object_class_install_property(gobject_class, PROP_ICON_STYLE, g_param_spec_enum("icon-style", @@ -696,11 +717,6 @@ xfce_desktop_set_property(GObject *object, XfceDesktop *desktop = XFCE_DESKTOP(object); switch(property_id) { - case PROP_XINERAMA_STRETCH: - xfce_desktop_set_xinerama_stretch(desktop, - g_value_get_boolean(value)); - break; - #ifdef ENABLE_DESKTOP_ICONS case PROP_ICON_STYLE: xfce_desktop_set_icon_style(desktop, @@ -738,10 +754,6 @@ xfce_desktop_get_property(GObject *object, XfceDesktop *desktop = XFCE_DESKTOP(object); switch(property_id) { - case PROP_XINERAMA_STRETCH: - g_value_set_boolean(value, desktop->priv->xinerama_stretch); - break; - #ifdef ENABLE_DESKTOP_ICONS case PROP_ICON_STYLE: g_value_set_enum(value, desktop->priv->icons_style); @@ -771,9 +783,11 @@ xfce_desktop_realize(GtkWidget *widget) { XfceDesktop *desktop = XFCE_DESKTOP(widget); GdkAtom atom; - gint sw, sh; + gint sw, sh, i; Window xid; GdkWindow *groot; + WnckScreen *wnck_screen; + WnckWorkspace *wnck_workspace; TRACE("entering"); @@ -818,13 +832,45 @@ xfce_desktop_realize(GtkWidget *widget) screen_set_selection(desktop); + /* We have to force wnck to initialize */ + wnck_screen = wnck_screen_get(gdk_screen_get_number(desktop->priv->gscreen)); + wnck_screen_force_update(wnck_screen); + desktop->priv->wnck_screen = wnck_screen; + + /* 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->nworkspaces = wnck_screen_get_workspace_count(wnck_screen); + + desktop->priv->workspaces = g_realloc(desktop->priv->workspaces, + desktop->priv->nworkspaces * sizeof(XfceWorkspace *)); + + for(i = 0; i < desktop->priv->nworkspaces; i++) { + desktop->priv->workspaces[i] = xfce_workspace_new(desktop->priv->gscreen, + desktop->priv->channel, + desktop->priv->property_prefix, + i); + xfce_workspace_monitors_changed(desktop->priv->workspaces[i], + desktop->priv->gscreen); + + g_signal_connect(desktop->priv->workspaces[i], "workspace-backdrop-changed", + G_CALLBACK(workspace_backdrop_changed_cb), desktop); + } + + g_signal_connect(desktop->priv->wnck_screen, "active-workspace-changed", + G_CALLBACK(workspace_changed_cb), desktop); + g_signal_connect(desktop->priv->wnck_screen, "workspace-created", + G_CALLBACK(workspace_created_cb), desktop); + g_signal_connect(desktop->priv->wnck_screen, "workspace-destroyed", + G_CALLBACK(workspace_destroyed_cb), desktop); + xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop); g_signal_connect(G_OBJECT(desktop->priv->gscreen), "size-changed", G_CALLBACK(screen_size_changed_cb), desktop); g_signal_connect(G_OBJECT(desktop->priv->gscreen), "composited-changed", G_CALLBACK(screen_composited_changed_cb), desktop); - + gtk_widget_add_events(GTK_WIDGET(desktop), GDK_EXPOSURE_MASK); #ifdef ENABLE_DESKTOP_ICONS @@ -838,7 +884,7 @@ static void xfce_desktop_unrealize(GtkWidget *widget) { XfceDesktop *desktop = XFCE_DESKTOP(widget); - guint i; + gint i; GdkWindow *groot; gchar property_name[128]; @@ -877,14 +923,14 @@ xfce_desktop_unrealize(GtkWidget *widget) gdk_window_set_back_pixmap(groot, NULL, FALSE); #endif - if(desktop->priv->backdrops) { - for(i = 0; i < desktop->priv->nbackdrops; i++) { + if(desktop->priv->workspaces) { + for(i = 0; i < desktop->priv->nworkspaces; i++) { g_snprintf(property_name, 128, XFDESKTOP_IMAGE_FILE_FMT, i); gdk_property_delete(groot, gdk_atom_intern(property_name, FALSE)); - g_object_unref(G_OBJECT(desktop->priv->backdrops[i])); + g_object_unref(G_OBJECT(desktop->priv->workspaces[i])); } - g_free(desktop->priv->backdrops); - desktop->priv->backdrops = NULL; + g_free(desktop->priv->workspaces); + desktop->priv->workspaces = NULL; } gdk_flush(); @@ -1016,15 +1062,9 @@ static void xfce_desktop_connect_settings(XfceDesktop *desktop) { XfconfChannel *channel = desktop->priv->channel; - gchar buf[1024]; xfce_desktop_freeze_updates(desktop); - g_strlcpy(buf, desktop->priv->property_prefix, sizeof(buf)); - g_strlcat(buf, "xinerama-stretch", sizeof(buf)); - xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, - G_OBJECT(desktop), "xinerama-stretch"); - #ifdef ENABLE_DESKTOP_ICONS #define ICONS_PREFIX "/desktop-icons/" @@ -1053,131 +1093,44 @@ xfce_desktop_image_filename_changed(XfconfChannel *channel, XfceDesktop *desktop = user_data; gchar *p; const gchar *filename; - gint monitor; + gint monitor, current_workspace; XfceBackdrop *backdrop; + TRACE("entering"); + p = strstr(property, "/monitor"); if(!p) return; monitor = atoi(p + 8); - if(monitor < 0 || monitor >= gdk_screen_get_n_monitors(desktop->priv->gscreen)) + if(monitor < 0 || monitor >= xfce_desktop_get_n_monitors(desktop)) return; - if(desktop->priv->xinerama_stretch && monitor != 0) + current_workspace = desktop->priv->current_workspace; + + if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace]) + && monitor != 0) return; - backdrop = desktop->priv->backdrops[monitor]; + + 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)) { - if(xfdesktop_backdrop_list_is_valid(filename)) { - gchar *backdrop_file; - GError *error = NULL; - - backdrop_file = xfdesktop_backdrop_list_choose_random(filename, - &error); -#if 0 - if(!backdrop_file && !xfdesktop_backdrop_list_is_valid(filename)) { - gchar *primary = g_strdup_printf(_("Unable to load image from backdrop list file \"%s\""), - filename); - xfce_message_dialog(GTK_WINDOW(desktop), _("Desktop Error"), - GTK_STOCK_DIALOG_ERROR, primary, - error->message, - GTK_STOCK_CLOSE, GTK_RESPONSE_ACCEPT, - NULL); - g_error_free(error); - g_free(primary); - } -#endif - xfce_backdrop_set_image_filename(backdrop, backdrop_file); - g_free(backdrop_file); - - xfce_backdrop_set_list(backdrop, g_strdup(filename)); - } else { - xfce_backdrop_set_image_filename(backdrop, filename); - - xfce_backdrop_set_list(backdrop, NULL); - } - } + if(G_LIKELY(filename && *filename)) + xfce_backdrop_set_image_filename(backdrop, filename); } -static void -xfce_desktop_connect_backdrop_settings(XfceDesktop *desktop, - XfceBackdrop *backdrop, - guint monitor) +static gint +xfce_desktop_get_current_workspace(XfceDesktop *desktop) { - XfconfChannel *channel = desktop->priv->channel; - char buf[1024], buf1[1024]; - gint pp_len; - GValue value = { 0, }; - - g_snprintf(buf, sizeof(buf), "%smonitor%d/", - desktop->priv->property_prefix, monitor); - pp_len = strlen(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"); - - buf[pp_len] = 0; - g_strlcat(buf, "color2", sizeof(buf)); - xfconf_g_property_bind_gdkcolor(channel, buf, - G_OBJECT(backdrop), "second-color"); - - buf[pp_len] = 0; - g_strlcat(buf, "image-show", sizeof(buf)); - xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, - G_OBJECT(backdrop), "show-image"); - - buf[pp_len] = 0; - g_strlcat(buf, "image-style", sizeof(buf)); - xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_IMAGE_STYLE, - 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, "saturation", sizeof(buf)); - xfconf_g_property_bind(channel, buf, G_TYPE_DOUBLE, - G_OBJECT(backdrop), "saturation"); - - 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"); - - buf[pp_len] = 0; - g_strlcat(buf, "backdrop-cycle-timer", sizeof(buf)); - xfconf_g_property_bind(channel, buf, G_TYPE_UINT, - G_OBJECT(backdrop), "backdrop-cycle-timer"); - - /* the image filename could be an image or a backdrop list, so we - * can't just bind the property directly */ - buf[pp_len] = 0; - g_strlcat(buf, "image-path", sizeof(buf)); - g_strlcpy(buf1, "property-changed::", sizeof(buf1)); - g_strlcat(buf1, buf, sizeof(buf1)); - g_signal_connect(G_OBJECT(channel), buf1, - G_CALLBACK(xfce_desktop_image_filename_changed), desktop); - if(xfconf_channel_get_property(channel, buf, &value)) { - xfce_desktop_image_filename_changed(channel, buf, &value, desktop); - g_value_unset(&value); - } -} - + g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), -1); + return desktop->priv->current_workspace; +} /* public api */ @@ -1216,12 +1169,12 @@ xfce_desktop_new(GdkScreen *gscreen, return GTK_WIDGET(desktop); } -guint +gint xfce_desktop_get_n_monitors(XfceDesktop *desktop) { g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), 0); - return desktop->priv->nbackdrops; + return gdk_screen_get_n_monitors(desktop->priv->gscreen); } gint @@ -1241,28 +1194,6 @@ xfce_desktop_get_height(XfceDesktop *desktop) } void -xfce_desktop_set_xinerama_stretch(XfceDesktop *desktop, - gboolean stretch) -{ - g_return_if_fail(XFCE_IS_DESKTOP(desktop)); - - if(stretch == desktop->priv->xinerama_stretch) - return; - - desktop->priv->xinerama_stretch = stretch; - - if(!desktop->priv->updates_frozen) - xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop); -} - -gboolean -xfce_desktop_get_xinerama_stretch(XfceDesktop *desktop) -{ - g_return_val_if_fail(XFCE_IS_DESKTOP(desktop), FALSE); - return desktop->priv->xinerama_stretch; -} - -void xfce_desktop_set_icon_style(XfceDesktop *desktop, XfceDesktopIconStyle style) { @@ -1384,16 +1315,6 @@ xfce_desktop_thaw_updates(XfceDesktop *desktop) xfce_desktop_monitors_changed(desktop->priv->gscreen, desktop); } -XfceBackdrop * -xfce_desktop_peek_backdrop(XfceDesktop *desktop, - guint monitor) -{ - g_return_val_if_fail(XFCE_IS_DESKTOP(desktop) - && GTK_WIDGET_REALIZED(GTK_WIDGET(desktop)) - && monitor < desktop->priv->nbackdrops, NULL); - return desktop->priv->backdrops[monitor]; -} - static gboolean xfce_desktop_menu_destroy_idled(gpointer data) { @@ -1470,23 +1391,25 @@ void xfce_desktop_refresh(XfceDesktop *desktop) { gchar buf[256]; - guint i, max; + gint i, max, current_workspace; g_return_if_fail(XFCE_IS_DESKTOP(desktop)); if(!GTK_WIDGET_REALIZED(desktop)) return; + current_workspace = desktop->priv->current_workspace; + /* reload image */ - if(desktop->priv->xinerama_stretch) + if(xfce_workspace_get_xinerama_stretch(desktop->priv->workspaces[current_workspace])) max = 1; else - max = desktop->priv->nbackdrops; + max = xfce_desktop_get_n_monitors(desktop); for(i = 0; i < max; ++i) { GValue val = { 0, }; - g_snprintf(buf, sizeof(buf), "%smonitor%d/image-path", - desktop->priv->property_prefix, i); + 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); xfce_desktop_image_filename_changed(desktop->priv->channel, buf, diff --git a/src/xfce-desktop.h b/src/xfce-desktop.h index a9224af..ade6aeb 100644 --- a/src/xfce-desktop.h +++ b/src/xfce-desktop.h @@ -77,15 +77,11 @@ GtkWidget *xfce_desktop_new(GdkScreen *gscreen, XfconfChannel *channel, const gchar *property_prefix); -guint xfce_desktop_get_n_monitors(XfceDesktop *desktop); +gint xfce_desktop_get_n_monitors(XfceDesktop *desktop); gint xfce_desktop_get_width(XfceDesktop *desktop); gint xfce_desktop_get_height(XfceDesktop *desktop); -void xfce_desktop_set_xinerama_stretch(XfceDesktop *desktop, - gboolean stretch); -gboolean xfce_desktop_get_xinerama_stretch(XfceDesktop *desktop); - void xfce_desktop_set_icon_style(XfceDesktop *desktop, XfceDesktopIconStyle style); XfceDesktopIconStyle xfce_desktop_get_icon_style(XfceDesktop *desktop); @@ -104,8 +100,6 @@ void xfce_desktop_set_session_logout_func(XfceDesktop *desktop, void xfce_desktop_freeze_updates(XfceDesktop *desktop); void xfce_desktop_thaw_updates(XfceDesktop *desktop); -XfceBackdrop *xfce_desktop_peek_backdrop(XfceDesktop *desktop, - guint monitor); void xfce_desktop_popup_root_menu(XfceDesktop *desktop, guint button, diff --git a/src/xfce-workspace.c b/src/xfce-workspace.c new file mode 100644 index 0000000..a43157a --- /dev/null +++ b/src/xfce-workspace.c @@ -0,0 +1,422 @@ +/* + * xfworkspace - xfce4's desktop manager + * + * Copyright (c) 2004-2007 Brian Tarricone, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Random portions taken from or inspired by the original xfworkspace for xfce4: + * Copyright (C) 2002-2003 Jasper Huijsmans (huysmans@users.sourceforge.net) + * Copyright (C) 2003 Benedikt Meurer + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#ifdef HAVE_STDLIB_H +#include +#endif + +#ifdef HAVE_STRING_H +#include +#endif + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include +#include + +#ifdef HAVE_TIME_H +#include +#endif + +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "xfdesktop-common.h" +#include "xfce-workspace.h" +#include "xfce-desktop-enum-types.h" + +struct _XfceWorkspacePriv +{ + GdkScreen *gscreen; + + XfconfChannel *channel; + gchar *property_prefix; + + guint workspace_num; + guint nbackdrops; + XfceBackdrop **backdrops; +}; + +enum +{ + WORKSPACE_BACKDROP_CHANGED, + N_SIGNALS, +}; + +static guint signals[N_SIGNALS] = { 0, }; + +static void xfce_workspace_finalize(GObject *object); +static void xfce_workspace_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void xfce_workspace_get_property(GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); + +static void xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace, + XfceBackdrop *backdrop, + guint monitor); + +G_DEFINE_TYPE(XfceWorkspace, xfce_workspace, G_TYPE_OBJECT) + +gboolean +xfce_workspace_get_xinerama_stretch(XfceWorkspace *workspace) +{ + g_return_val_if_fail(XFCE_IS_WORKSPACE(workspace), FALSE); + g_return_val_if_fail(workspace->priv->backdrops != NULL, FALSE); + g_return_val_if_fail(XFCE_IS_BACKDROP(workspace->priv->backdrops[0]), FALSE); + + return xfce_backdrop_get_image_style(workspace->priv->backdrops[0]) == XFCE_BACKDROP_IMAGE_SPANNING_SCREENS; +} + +static void +backdrop_cycle_cb(XfceBackdrop *backdrop, gpointer user_data) +{ + const gchar* backdrop_file; + gchar *new_backdrop = NULL; + XfceWorkspace *workspace = XFCE_WORKSPACE(user_data); + + TRACE("entering"); + + g_return_if_fail(XFCE_IS_BACKDROP(backdrop)); + + backdrop_file = xfce_backdrop_get_image_filename(backdrop); + + if(backdrop_file == NULL) + return; + + if(xfce_backdrop_get_random_order(backdrop)) { + DBG("Random! current file: %s", backdrop_file); + new_backdrop = xfdesktop_backdrop_choose_random(backdrop_file); + } else { + DBG("Next! current file: %s", backdrop_file); + new_backdrop = xfdesktop_backdrop_choose_next(backdrop_file); + } + DBG("new file: %s for Workspace %d", new_backdrop, + xfce_workspace_get_workspace_num(workspace)); + + 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) +{ + TRACE("entering"); + /* Propagate it up */ + g_signal_emit(G_OBJECT(user_data), signals[WORKSPACE_BACKDROP_CHANGED], 0, backdrop); +} + +void +xfce_workspace_monitors_changed(XfceWorkspace *workspace, + GdkScreen *gscreen) +{ + guint i; + + 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])); + } + + 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; + } + } else { + /* We need one backdrop per monitor */ + guint n_monitors = gdk_screen_get_n_monitors(gscreen); + + if(n_monitors < workspace->priv->nbackdrops) { + for(i = n_monitors; i < workspace->priv->nbackdrops; ++i) + g_object_unref(G_OBJECT(workspace->priv->backdrops[i])); + } + + if(n_monitors != workspace->priv->nbackdrops) { + workspace->priv->backdrops = g_realloc(workspace->priv->backdrops, + sizeof(XfceBackdrop *) * n_monitors); + if(n_monitors > workspace->priv->nbackdrops) { + GdkVisual *vis = gdk_screen_get_rgba_visual(gscreen); + if(vis == NULL) + vis = gdk_screen_get_system_visual(gscreen); + + for(i = workspace->priv->nbackdrops; i < n_monitors; ++i) { + workspace->priv->backdrops[i] = xfce_backdrop_new(vis); + xfce_workspace_connect_backdrop_settings(workspace, + workspace->priv->backdrops[i], + i); + g_signal_connect(G_OBJECT(workspace->priv->backdrops[0]), + "changed", + G_CALLBACK(backdrop_changed_cb), workspace); + g_signal_connect(G_OBJECT(workspace->priv->backdrops[i]), + "cycle", + G_CALLBACK(backdrop_cycle_cb), + workspace); + } + } + workspace->priv->nbackdrops = n_monitors; + } + } +} + +static void +xfce_workspace_class_init(XfceWorkspaceClass *klass) +{ + GObjectClass *gobject_class = (GObjectClass *)klass; + + g_type_class_add_private(klass, sizeof(XfceWorkspacePriv)); + + gobject_class->finalize = xfce_workspace_finalize; + gobject_class->set_property = xfce_workspace_set_property; + gobject_class->get_property = xfce_workspace_get_property; + + signals[WORKSPACE_BACKDROP_CHANGED] = g_signal_new("workspace-backdrop-changed", + XFCE_TYPE_WORKSPACE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(XfceWorkspaceClass, + changed), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); +} + +static void +xfce_workspace_init(XfceWorkspace *workspace) +{ + workspace->priv = G_TYPE_INSTANCE_GET_PRIVATE(workspace, XFCE_TYPE_WORKSPACE, + XfceWorkspacePriv); +} + +static void +xfce_workspace_finalize(GObject *object) +{ + XfceWorkspace *workspace = XFCE_WORKSPACE(object); + + g_object_unref(G_OBJECT(workspace->priv->channel)); + g_free(workspace->priv->property_prefix); + +} + +static void +xfce_workspace_set_property(GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch(property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +xfce_workspace_get_property(GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch(property_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +xfce_workspace_connect_backdrop_settings(XfceWorkspace *workspace, + XfceBackdrop *backdrop, + guint monitor) +{ + XfconfChannel *channel = workspace->priv->channel; + char buf[1024]; + gint pp_len; + + TRACE("entering"); + + g_snprintf(buf, sizeof(buf), "%smonitor%d/workspace%d/", + workspace->priv->property_prefix, monitor, workspace->priv->workspace_num); + pp_len = strlen(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"); + + buf[pp_len] = 0; + g_strlcat(buf, "color2", sizeof(buf)); + xfconf_g_property_bind_gdkcolor(channel, buf, + G_OBJECT(backdrop), "second-color"); + + buf[pp_len] = 0; + g_strlcat(buf, "image-style", sizeof(buf)); + xfconf_g_property_bind(channel, buf, XFCE_TYPE_BACKDROP_IMAGE_STYLE, + 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"); + + buf[pp_len] = 0; + g_strlcat(buf, "backdrop-cycle-timer", sizeof(buf)); + xfconf_g_property_bind(channel, buf, G_TYPE_UINT, + G_OBJECT(backdrop), "backdrop-cycle-timer"); + + buf[pp_len] = 0; + g_strlcat(buf, "backdrop-cycle-random-order", sizeof(buf)); + xfconf_g_property_bind(channel, buf, G_TYPE_BOOLEAN, + G_OBJECT(backdrop), "backdrop-cycle-random-order"); + + buf[pp_len] = 0; + g_strlcat(buf, "last-image", sizeof(buf)); + xfconf_g_property_bind(channel, buf, G_TYPE_STRING, + G_OBJECT(backdrop), "image-filename"); +} + + + +/* public api */ + +/** + * xfce_workspace_new: + * @gscreen: The current #GdkScreen. + * @channel: An #XfconfChannel to use for settings. + * @property_prefix: String prefix for per-screen properties. + * @number: The workspace number to represent + * + * Creates a new #XfceWorkspace for the specified #GdkScreen. If @gscreen is + * %NULL, the default screen will be used. + * + * Return value: A new #XfceWorkspace. + **/ +XfceWorkspace * +xfce_workspace_new(GdkScreen *gscreen, + XfconfChannel *channel, + const gchar *property_prefix, + gint number) +{ + XfceWorkspace *workspace; + + g_return_val_if_fail(channel && property_prefix, NULL); + + workspace = g_object_new(XFCE_TYPE_WORKSPACE, NULL); + + if(!gscreen) + gscreen = gdk_display_get_default_screen(gdk_display_get_default()); + + workspace->priv->gscreen = gscreen; + workspace->priv->workspace_num = number; + workspace->priv->channel = g_object_ref(G_OBJECT(channel)); + workspace->priv->property_prefix = g_strdup(property_prefix); + + return workspace; +} + +gint +xfce_workspace_get_workspace_num(XfceWorkspace *workspace) +{ + g_return_val_if_fail(XFCE_IS_WORKSPACE(workspace), -1); + + return workspace->priv->workspace_num; +} + +void +xfce_workspace_set_workspace_num(XfceWorkspace *workspace, gint number) +{ + g_return_if_fail(XFCE_IS_WORKSPACE(workspace)); + + workspace->priv->workspace_num = number; +} + +XfceBackdrop *xfce_workspace_get_backdrop(XfceWorkspace *workspace, + guint monitor) +{ + g_return_val_if_fail(XFCE_IS_WORKSPACE(workspace) + && monitor < workspace->priv->nbackdrops, NULL); + return workspace->priv->backdrops[monitor]; +} diff --git a/src/xfce-workspace.h b/src/xfce-workspace.h new file mode 100644 index 0000000..173bc15 --- /dev/null +++ b/src/xfce-workspace.h @@ -0,0 +1,78 @@ +/* + * xfworkspace - xfce4's desktop manager + * + * Copyright (c) 2004-2007 Brian Tarricone, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _XFCE_WORKSPACE_H_ +#define _XFCE_WORKSPACE_H_ + +#include +#include + +#include "xfce-backdrop.h" + +G_BEGIN_DECLS + +#define XFCE_TYPE_WORKSPACE (xfce_workspace_get_type()) +#define XFCE_WORKSPACE(object) (G_TYPE_CHECK_INSTANCE_CAST((object), XFCE_TYPE_WORKSPACE, XfceWorkspace)) +#define XFCE_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), XFCE_TYPE_WORKSPACE, XfceWorkspaceClass)) +#define XFCE_IS_WORKSPACE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), XFCE_TYPE_WORKSPACE)) +#define XFCE_IS_WORKSPACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), XFCE_TYPE_WORKSPACE)) +#define XFCE_WORKSPACE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), XFCE_TYPE_WORKSPACE, XfceWorkspaceClass)) + +typedef struct _XfceWorkspace XfceWorkspace; +typedef struct _XfceWorkspaceClass XfceWorkspaceClass; +typedef struct _XfceWorkspacePriv XfceWorkspacePriv; + +struct _XfceWorkspace +{ + GObject gobject; + + /*< private >*/ + XfceWorkspacePriv *priv; +}; + +struct _XfceWorkspaceClass +{ + GObjectClass parent_class; + + /*< signals >*/ + void (*changed)(XfceWorkspace *workspace, XfceBackdrop *backdrop); +}; + +GType xfce_workspace_get_type (void) G_GNUC_CONST; + +XfceWorkspace *xfce_workspace_new(GdkScreen *gscreen, + XfconfChannel *channel, + const gchar *property_prefix, + gint number); + +gint xfce_workspace_get_workspace_num(XfceWorkspace *workspace); +void xfce_workspace_set_workspace_num(XfceWorkspace *workspace, gint number); + +void xfce_workspace_monitors_changed(XfceWorkspace *workspace, + GdkScreen *gscreen); + +gboolean xfce_workspace_get_xinerama_stretch(XfceWorkspace *workspace); + +XfceBackdrop *xfce_workspace_get_backdrop(XfceWorkspace *workspace, + guint monitor); + +G_END_DECLS + +#endif -- 1.7.10.4