[gnome-control-center] Add support for per-monitor backgrounds
- From: William Jon McCann <mccann src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-control-center] Add support for per-monitor backgrounds
- Date: Thu, 10 Dec 2009 03:15:42 +0000 (UTC)
commit 9d4a90d7986f819e9918035e8b247fbf08b1cd2b
Author: William Jon McCann <jmccann redhat com>
Date: Fri Dec 4 19:54:47 2009 -0500
Add support for per-monitor backgrounds
https://bugzilla.gnome.org/show_bug.cgi?id=147808
capplets/appearance/appearance-desktop.c | 171 +++++++++++++++++++++++-------
capplets/appearance/appearance.h | 4 +
capplets/appearance/gnome-wp-item.c | 65 +++++++----
capplets/appearance/gnome-wp-item.h | 10 ++-
4 files changed, 184 insertions(+), 66 deletions(-)
---
diff --git a/capplets/appearance/appearance-desktop.c b/capplets/appearance/appearance-desktop.c
index 5979654..2ae6bd6 100644
--- a/capplets/appearance/appearance-desktop.c
+++ b/capplets/appearance/appearance-desktop.c
@@ -82,7 +82,6 @@ get_selected_item (AppearanceData *data,
if (selected != NULL)
{
GtkTreeIter sel_iter;
- gchar *wpfile;
gtk_tree_model_get_iter (data->wp_model, &sel_iter,
selected->data);
@@ -93,10 +92,7 @@ get_selected_item (AppearanceData *data,
if (iter)
*iter = sel_iter;
- gtk_tree_model_get (data->wp_model, &sel_iter, 2, &wpfile, -1);
-
- item = g_hash_table_lookup (data->wp_hash, wpfile);
- g_free (wpfile);
+ gtk_tree_model_get (data->wp_model, &sel_iter, 1, &item, -1);
}
return item;
@@ -129,7 +125,10 @@ static void on_item_changed (GnomeBG *bg, AppearanceData *data) {
g_signal_handlers_block_by_func (bg, G_CALLBACK (on_item_changed), data);
- pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory);
+ pixbuf = gnome_wp_item_get_thumbnail (item,
+ data->thumb_factory,
+ data->thumb_width,
+ data->thumb_height);
if (pixbuf) {
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
g_object_unref (pixbuf);
@@ -153,13 +152,14 @@ wp_props_load_wallpaper (gchar *key,
gtk_list_store_append (GTK_LIST_STORE (data->wp_model), &iter);
- pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory);
+ pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory,
+ data->thumb_width,
+ data->thumb_height);
gnome_wp_item_update_description (item);
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter,
0, pixbuf,
- 1, item->description,
- 2, item->filename,
+ 1, item,
-1);
if (pixbuf != NULL)
@@ -313,7 +313,9 @@ wp_scale_type_changed (GtkComboBox *combobox,
item->options = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_style_menu));
- pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory);
+ pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory,
+ data->thumb_width,
+ data->thumb_height);
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
if (pixbuf != NULL)
g_object_unref (pixbuf);
@@ -338,7 +340,9 @@ wp_shade_type_changed (GtkWidget *combobox,
item->shade_type = gtk_combo_box_get_active (GTK_COMBO_BOX (data->wp_color_menu));
- pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory);
+ pixbuf = gnome_wp_item_get_thumbnail (item, data->thumb_factory,
+ data->thumb_width,
+ data->thumb_height);
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
if (pixbuf != NULL)
g_object_unref (pixbuf);
@@ -768,7 +772,6 @@ wp_view_tooltip_cb (GtkWidget *widget,
AppearanceData *data)
{
GtkTreeIter iter;
- gchar *wpfile;
GnomeWPItem *item;
if (gtk_icon_view_get_tooltip_context (data->wp_view,
@@ -778,10 +781,7 @@ wp_view_tooltip_cb (GtkWidget *widget,
NULL,
&iter))
{
- gtk_tree_model_get (data->wp_model, &iter, 2, &wpfile, -1);
- item = g_hash_table_lookup (data->wp_hash, wpfile);
- g_free (wpfile);
-
+ gtk_tree_model_get (data->wp_model, &iter, 1, &item, -1);
gtk_tooltip_set_markup (tooltip, item->description);
return TRUE;
@@ -795,31 +795,25 @@ wp_list_sort (GtkTreeModel *model,
GtkTreeIter *a, GtkTreeIter *b,
AppearanceData *data)
{
- gchar *foo, *bar;
- gchar *desca, *descb;
+ GnomeWPItem *itema, *itemb;
gint retval;
- gtk_tree_model_get (model, a, 1, &desca, 2, &foo, -1);
- gtk_tree_model_get (model, b, 1, &descb, 2, &bar, -1);
+ gtk_tree_model_get (model, a, 1, &itema, -1);
+ gtk_tree_model_get (model, b, 1, &itemb, -1);
- if (!strcmp (foo, "(none)"))
+ if (!strcmp (itema->filename, "(none)"))
{
retval = -1;
}
- else if (!strcmp (bar, "(none)"))
+ else if (!strcmp (itemb->filename, "(none)"))
{
retval = 1;
}
else
{
- retval = g_utf8_collate (desca, descb);
+ retval = g_utf8_collate (itema->description, itemb->description);
}
- g_free (desca);
- g_free (descb);
- g_free (foo);
- g_free (bar);
-
return retval;
}
@@ -875,6 +869,68 @@ wp_update_preview (GtkFileChooser *chooser,
}
static gboolean
+reload_item (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ AppearanceData *data)
+{
+ GnomeWPItem *item;
+ GdkPixbuf *pixbuf;
+
+ gtk_tree_model_get (model, iter, 1, &item, -1);
+
+ pixbuf = gnome_wp_item_get_thumbnail (item,
+ data->thumb_factory,
+ data->thumb_width,
+ data->thumb_height);
+ if (pixbuf) {
+ gtk_list_store_set (GTK_LIST_STORE (data->wp_model), iter, 0, pixbuf, -1);
+ g_object_unref (pixbuf);
+ }
+
+ return FALSE;
+}
+
+static gdouble
+get_monitor_aspect_ratio_for_widget (GtkWidget *widget)
+{
+ gdouble aspect;
+ gint monitor;
+ GdkRectangle rect;
+
+ monitor = gdk_screen_get_monitor_at_window (gtk_widget_get_screen (widget), gtk_widget_get_window (widget));
+ gdk_screen_get_monitor_geometry (gtk_widget_get_screen (widget), monitor, &rect);
+ aspect = rect.height / (gdouble)rect.width;
+
+ return aspect;
+}
+
+#define LIST_IMAGE_SIZE 108
+
+static void
+compute_thumbnail_sizes (AppearanceData *data)
+{
+ gdouble aspect;
+
+ aspect = get_monitor_aspect_ratio_for_widget (GTK_WIDGET (data->wp_view));
+ if (aspect > 1) {
+ /* portrait */
+ data->thumb_width = LIST_IMAGE_SIZE / aspect;
+ data->thumb_height = LIST_IMAGE_SIZE;
+ } else {
+ data->thumb_width = LIST_IMAGE_SIZE;
+ data->thumb_height = LIST_IMAGE_SIZE * aspect;
+ }
+}
+
+static void
+reload_wallpapers (AppearanceData *data)
+{
+ compute_thumbnail_sizes (data);
+ gtk_tree_model_foreach (data->wp_model, (GtkTreeModelForeachFunc)reload_item, data);
+}
+
+static gboolean
wp_load_stuffs (void *user_data)
{
AppearanceData *data;
@@ -883,6 +939,8 @@ wp_load_stuffs (void *user_data)
data = (AppearanceData *) user_data;
+ compute_thumbnail_sizes (data);
+
gnome_wp_xml_load_list (data);
g_hash_table_foreach (data->wp_hash, (GHFunc) wp_props_load_wallpaper,
data);
@@ -976,8 +1034,11 @@ static void
wp_select_after_realize (GtkWidget *widget,
AppearanceData *data)
{
- GnomeWPItem *item = get_selected_item (data, NULL);
+ GnomeWPItem *item;
+
+ g_idle_add (wp_load_stuffs, data);
+ item = get_selected_item (data, NULL);
if (item == NULL)
item = g_hash_table_lookup (data->wp_hash, "(none)");
@@ -1043,7 +1104,11 @@ next_frame (AppearanceData *data,
item = get_selected_item (data, &iter);
if (frame >= 0)
- pixbuf = gnome_wp_item_get_frame_thumbnail (item, data->thumb_factory, frame);
+ pixbuf = gnome_wp_item_get_frame_thumbnail (item,
+ data->thumb_factory,
+ data->thumb_width,
+ data->thumb_height,
+ frame);
if (pixbuf) {
gtk_list_store_set (GTK_LIST_STORE (data->wp_model), &iter, 0, pixbuf, -1);
g_object_unref (pixbuf);
@@ -1056,7 +1121,11 @@ next_frame (AppearanceData *data,
pb = buttons[0];
}
else {
- pixbuf = gnome_wp_item_get_frame_thumbnail (item, data->thumb_factory, frame + 1);
+ pixbuf = gnome_wp_item_get_frame_thumbnail (item,
+ data->thumb_factory,
+ data->thumb_width,
+ data->thumb_height,
+ frame + 1);
if (pixbuf)
g_object_unref (pixbuf);
else
@@ -1140,6 +1209,13 @@ buttons_cell_data_func (GtkCellLayout *layout,
gtk_tree_path_free (path);
}
+static void
+screen_monitors_changed (GdkScreen *screen,
+ AppearanceData *data)
+{
+ reload_wallpapers (data);
+}
+
void
desktop_init (AppearanceData *data,
const gchar **uris)
@@ -1194,9 +1270,8 @@ desktop_init (AppearanceData *data,
(GConfClientNotifyFunc) wp_color2_changed,
data, NULL, NULL);
- data->wp_model = GTK_TREE_MODEL (gtk_list_store_new (3, GDK_TYPE_PIXBUF,
- G_TYPE_STRING,
- G_TYPE_STRING));
+ data->wp_model = GTK_TREE_MODEL (gtk_list_store_new (2, GDK_TYPE_PIXBUF,
+ G_TYPE_POINTER));
data->wp_view = GTK_ICON_VIEW (appearance_capplet_get_widget (data, "wp_view"));
gtk_icon_view_set_model (data->wp_view, GTK_TREE_MODEL (data->wp_model));
@@ -1232,12 +1307,12 @@ desktop_init (AppearanceData *data,
data->frame = -1;
- gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (data->wp_model), 2,
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (data->wp_model), 1,
(GtkTreeIterCompareFunc) wp_list_sort,
data, NULL);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (data->wp_model),
- 2, GTK_SORT_ASCENDING);
+ 1, GTK_SORT_ASCENDING);
gtk_drag_dest_set (GTK_WIDGET (data->wp_view), GTK_DEST_DEFAULT_ALL, drop_types,
G_N_ELEMENTS (drop_types), GDK_ACTION_COPY | GDK_ACTION_MOVE);
@@ -1280,14 +1355,20 @@ desktop_init (AppearanceData *data,
g_signal_connect (data->wp_rem_button, "clicked",
(GCallback) wp_remove_wallpaper, data);
-
- g_idle_add (wp_load_stuffs, data);
+ data->screen_monitors_handler = g_signal_connect (gtk_widget_get_screen (GTK_WIDGET (data->wp_view)),
+ "monitors-changed",
+ G_CALLBACK (screen_monitors_changed),
+ data);
+ data->screen_size_handler = g_signal_connect (gtk_widget_get_screen (GTK_WIDGET (data->wp_view)),
+ "size-changed",
+ G_CALLBACK (screen_monitors_changed),
+ data);
g_signal_connect (data->wp_view, "selection-changed",
(GCallback) wp_props_wp_selected, data);
g_signal_connect (data->wp_view, "query-tooltip",
(GCallback) wp_view_tooltip_cb, data);
- gtk_widget_set_has_tooltip (data->wp_view, TRUE);
+ gtk_widget_set_has_tooltip (GTK_WIDGET (data->wp_view), TRUE);
wp_set_sensitivities (data);
@@ -1300,6 +1381,18 @@ void
desktop_shutdown (AppearanceData *data)
{
gnome_wp_xml_save_list (data);
+
+ if (data->screen_monitors_handler > 0) {
+ g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (data->wp_view)),
+ data->screen_monitors_handler);
+ data->screen_monitors_handler = 0;
+ }
+ if (data->screen_size_handler > 0) {
+ g_signal_handler_disconnect (gtk_widget_get_screen (GTK_WIDGET (data->wp_view)),
+ data->screen_size_handler);
+ data->screen_size_handler = 0;
+ }
+
g_slist_foreach (data->wp_uris, (GFunc) g_free, NULL);
g_slist_free (data->wp_uris);
if (data->wp_filesel)
diff --git a/capplets/appearance/appearance.h b/capplets/appearance/appearance.h
index 5b4dd59..c598b06 100644
--- a/capplets/appearance/appearance.h
+++ b/capplets/appearance/appearance.h
@@ -36,6 +36,8 @@ typedef struct
GConfClient *client;
GtkBuilder *ui;
GnomeDesktopThumbnailFactory *thumb_factory;
+ gulong screen_size_handler;
+ gulong screen_monitors_handler;
/* desktop */
GHashTable *wp_hash;
@@ -51,6 +53,8 @@ typedef struct
GtkWidget *wp_image;
GSList *wp_uris;
gint frame;
+ gint thumb_width;
+ gint thumb_height;
/* font */
GtkWidget *font_details;
diff --git a/capplets/appearance/gnome-wp-item.c b/capplets/appearance/gnome-wp-item.c
index b4c86f2..b4af8fc 100644
--- a/capplets/appearance/gnome-wp-item.c
+++ b/capplets/appearance/gnome-wp-item.c
@@ -205,22 +205,19 @@ add_slideshow_frame (GdkPixbuf *pixbuf)
return tmp;
}
-#define LIST_IMAGE_WIDTH 108
-
GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem * item,
GnomeDesktopThumbnailFactory * thumbs,
+ int width,
+ int height,
gint frame) {
GdkPixbuf *pixbuf = NULL;
- double aspect =
- (double)gdk_screen_get_height (gdk_screen_get_default()) /
- gdk_screen_get_width (gdk_screen_get_default());
set_bg_properties (item);
if (frame != -1)
- pixbuf = gnome_bg_create_frame_thumbnail (item->bg, thumbs, gdk_screen_get_default (), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect, frame);
+ pixbuf = gnome_bg_create_frame_thumbnail (item->bg, thumbs, gdk_screen_get_default (), width, height, frame);
else
- pixbuf = gnome_bg_create_thumbnail (item->bg, thumbs, gdk_screen_get_default(), LIST_IMAGE_WIDTH, LIST_IMAGE_WIDTH * aspect);
+ pixbuf = gnome_bg_create_thumbnail (item->bg, thumbs, gdk_screen_get_default(), width, height);
if (pixbuf && gnome_bg_changes_with_time (item->bg))
{
@@ -231,15 +228,17 @@ GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem * item,
pixbuf = tmp;
}
- gnome_bg_get_image_size (item->bg, thumbs, &item->width, &item->height);
+ gnome_bg_get_image_size (item->bg, thumbs, width, height, &item->width, &item->height);
return pixbuf;
}
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem * item,
- GnomeDesktopThumbnailFactory * thumbs) {
- return gnome_wp_item_get_frame_thumbnail (item, thumbs, -1);
+ GnomeDesktopThumbnailFactory * thumbs,
+ gint width,
+ gint height) {
+ return gnome_wp_item_get_frame_thumbnail (item, thumbs, width, height, -1);
}
void gnome_wp_item_update_description (GnomeWPItem * item) {
@@ -252,37 +251,55 @@ void gnome_wp_item_update_description (GnomeWPItem * item) {
gchar *size;
gchar *dirname = g_path_get_dirname (item->filename);
+ description = NULL;
+ size = NULL;
+
if (strcmp (item->fileinfo->mime_type, "application/xml") == 0)
{
if (gnome_bg_changes_with_time (item->bg))
description = _("Slide Show");
- else
+ else if (item->width > 0 && item->height > 0)
description = _("Image");
}
else
description = g_content_type_get_description (item->fileinfo->mime_type);
- if (gnome_bg_changes_with_size (item->bg))
+ if (gnome_bg_has_multiple_sizes (item->bg))
size = g_strdup (_("multiple sizes"));
- else
+ else if (item->width > 0 && item->height > 0) {
/* translators: x pixel(s) by y pixel(s) */
size = g_strdup_printf ("%d %s by %d %s",
item->width,
ngettext ("pixel", "pixels", item->width),
item->height,
ngettext ("pixel", "pixels", item->height));
+ }
+
+ if (description && size) {
+ /* translators: <b>wallpaper name</b>
+ * mime type, size
+ * Folder: /path/to/file
+ */
+ item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
+ "%s, %s\n"
+ "Folder: %s"),
+ item->name,
+ description,
+ size,
+ dirname);
+ } else {
+ /* translators: <b>wallpaper name</b>
+ * Image missing
+ * Folder: /path/to/file
+ */
+ item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
+ "%s\n"
+ "Folder: %s"),
+ item->name,
+ _("Image missing"),
+ dirname);
+ }
- /* translators: <b>wallpaper name</b>
- * mime type, size
- * Folder: /path/to/file
- */
- item->description = g_markup_printf_escaped (_("<b>%s</b>\n"
- "%s, %s\n"
- "Folder: %s"),
- item->name,
- description,
- size,
- dirname);
g_free (size);
g_free (dirname);
}
diff --git a/capplets/appearance/gnome-wp-item.h b/capplets/appearance/gnome-wp-item.h
index 63bdb69..03dc417 100644
--- a/capplets/appearance/gnome-wp-item.h
+++ b/capplets/appearance/gnome-wp-item.h
@@ -71,10 +71,14 @@ GnomeWPItem * gnome_wp_item_new (const gchar *filename,
void gnome_wp_item_free (GnomeWPItem *item);
GdkPixbuf * gnome_wp_item_get_thumbnail (GnomeWPItem *item,
- GnomeDesktopThumbnailFactory *thumbs);
-GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem *item,
GnomeDesktopThumbnailFactory *thumbs,
- gint frame);
+ gint width,
+ gint height);
+GdkPixbuf * gnome_wp_item_get_frame_thumbnail (GnomeWPItem *item,
+ GnomeDesktopThumbnailFactory *thumbs,
+ gint width,
+ gint height,
+ gint frame);
void gnome_wp_item_update (GnomeWPItem *item);
void gnome_wp_item_update_description (GnomeWPItem *item);
void gnome_wp_item_ensure_gnome_bg (GnomeWPItem *item);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]