[gnome-control-center] Add support for per-monitor backgrounds



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]