[gnome-control-center] background: Composite the emblems ourselves
- From: Debarshi Ray <debarshir src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-control-center] background: Composite the emblems ourselves
- Date: Wed, 16 Jul 2014 15:42:55 +0000 (UTC)
commit 7f606870a3f26b50cda1c6c6f54ee242167f42ca
Author: Debarshi Ray <debarshir gnome org>
Date: Mon Jun 30 15:47:24 2014 +0200
background: Composite the emblems ourselves
We were assuming that setting stock-size would affect the emblems in
GEmblemedIcons, but not the icons themselves. This is a bit weird.
GtkCellRendererPixbuf:gicon is meant to work with
GtkCellRendererPixbuf:stock-size, and this was only working so far
because GTK_ICON_LOOKUP_FORCE_SIZE was not being used when loading
the icon.
Let's composite the emblems ourselves so that we don't have to depend
on this quirky interpretation of stock-size.
Unfortunately, we can not directly use the pixbufs because they are
unaware of the scale factor and GTK+ will scale them on HiDpi
displays. Since our pixbufs already have enough pixels to work well
with such devices, scaling them further will lead to giant, fuzzy
thumbnails. Hence, we use GtkCellRendererPixbuf:surface with the
scale factor codified in it.
https://bugzilla.gnome.org/show_bug.cgi?id=732375
configure.ac | 2 +-
panels/background/bg-colors-source.c | 11 +++-
panels/background/bg-pictures-source.c | 17 ++++-
panels/background/bg-source.c | 12 +++-
panels/background/bg-source.h | 2 +
panels/background/bg-wallpapers-source.c | 14 +++-
panels/background/cc-background-chooser-dialog.c | 8 +--
panels/background/cc-background-item.c | 80 ++++++++++++++++++----
panels/background/cc-background-item.h | 4 +-
panels/background/cc-background-panel.c | 3 +
10 files changed, 121 insertions(+), 32 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 9efe923..c95c64f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -119,7 +119,7 @@ LIBGD_INIT([_view-common notification static])
PKG_CHECK_MODULES(LIBLANGUAGE, $COMMON_MODULES gnome-desktop-3.0 fontconfig)
PKG_CHECK_MODULES(LIBSHORTCUTS, $COMMON_MODULES x11)
PKG_CHECK_MODULES(SHELL, $COMMON_MODULES x11 polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION)
-PKG_CHECK_MODULES(BACKGROUND_PANEL, $COMMON_MODULES libxml-2.0 gnome-desktop-3.0
+PKG_CHECK_MODULES(BACKGROUND_PANEL, $COMMON_MODULES cairo-gobject libxml-2.0 gnome-desktop-3.0
gdk-pixbuf-2.0 >= $GDKPIXBUF_REQUIRED_VERSION
goa-1.0 >= $GOA_REQUIRED_VERSION
grilo-0.2 >= $GRILO_REQUIRED_VERSION)
diff --git a/panels/background/bg-colors-source.c b/panels/background/bg-colors-source.c
index dd9ba97..3a589f5 100644
--- a/panels/background/bg-colors-source.c
+++ b/panels/background/bg-colors-source.c
@@ -24,6 +24,7 @@
#include "cc-background-item.h"
+#include <cairo-gobject.h>
#include <glib/gi18n-lib.h>
#include <gdesktop-enums.h>
@@ -76,6 +77,8 @@ bg_colors_source_constructed (GObject *object)
CcBackgroundItemFlags flags;
CcBackgroundItem *item;
GIcon *pixbuf;
+ cairo_surface_t *surface;
+ int scale_factor;
item = cc_background_item_new (NULL);
flags = CC_BACKGROUND_ITEM_HAS_PCOLOR |
@@ -96,14 +99,18 @@ bg_colors_source_constructed (GObject *object)
cc_background_item_load (item, NULL);
/* insert the item into the liststore */
+ scale_factor = bg_source_get_scale_factor (BG_SOURCE (self));
pixbuf = cc_background_item_get_thumbnail (item,
thumb_factory,
- thumbnail_width, thumbnail_height);
+ thumbnail_width, thumbnail_height,
+ scale_factor);
+ surface = gdk_cairo_surface_create_from_pixbuf (GDK_PIXBUF (pixbuf), scale_factor, NULL);
gtk_list_store_insert_with_values (store, NULL, 0,
- 0, pixbuf,
+ 0, surface,
1, item,
-1);
+ cairo_surface_destroy (surface);
g_object_unref (pixbuf);
g_object_unref (item);
}
diff --git a/panels/background/bg-pictures-source.c b/panels/background/bg-pictures-source.c
index 0c5c6c0..3d0607f 100644
--- a/panels/background/bg-pictures-source.c
+++ b/panels/background/bg-pictures-source.c
@@ -27,6 +27,7 @@
#include "cc-background-item.h"
#include <string.h>
+#include <cairo-gobject.h>
#include <gio/gio.h>
#include <grilo.h>
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
@@ -150,6 +151,8 @@ picture_scaled (GObject *source_object,
GtkTreePath *path;
GtkTreeRowReference *row_ref;
GtkListStore *store;
+ cairo_surface_t *surface = NULL;
+ int scale_factor;
item = g_object_get_data (source_object, "item");
pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
@@ -183,6 +186,8 @@ picture_scaled (GObject *source_object,
goto out;
}
+ scale_factor = bg_source_get_scale_factor (BG_SOURCE (bg_source));
+ surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
cc_background_item_load (item, NULL);
row_ref = g_object_get_data (G_OBJECT (item), "row-ref");
@@ -190,7 +195,7 @@ picture_scaled (GObject *source_object,
{
/* insert the item into the liststore if it did not exist */
gtk_list_store_insert_with_values (store, NULL, -1,
- 0, pixbuf,
+ 0, surface,
1, item,
-1);
}
@@ -201,7 +206,7 @@ picture_scaled (GObject *source_object,
{
/* otherwise update the thumbnail */
gtk_list_store_set (store, &iter,
- 0, pixbuf,
+ 0, surface,
-1);
}
}
@@ -212,6 +217,7 @@ picture_scaled (GObject *source_object,
out:
+ g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy);
g_clear_object (&pixbuf);
}
@@ -336,10 +342,12 @@ add_single_file (BgPicturesSource *bg_source,
GtkTreeIter iter;
GtkTreePath *path = NULL;
GtkTreeRowReference *row_ref;
+ cairo_surface_t *surface = NULL;
char *source_uri = NULL;
char *uri = NULL;
gboolean is_native;
gboolean retval = FALSE;
+ int scale_factor;
/* find png and jpeg files */
if (!content_type)
@@ -395,11 +403,13 @@ add_single_file (BgPicturesSource *bg_source,
goto read_file;
}
+ scale_factor = bg_source_get_scale_factor (BG_SOURCE (bg_source));
+ surface = gdk_cairo_surface_create_from_pixbuf (pixbuf, scale_factor, NULL);
store = bg_source_get_liststore (BG_SOURCE (bg_source));
/* insert the item into the liststore */
gtk_list_store_insert_with_values (store, &iter, -1,
- 0, pixbuf,
+ 0, surface,
1, item,
-1);
@@ -470,6 +480,7 @@ add_single_file (BgPicturesSource *bg_source,
out:
gtk_tree_path_free (path);
+ g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy);
g_clear_object (&pixbuf);
g_clear_object (&icon_info);
g_clear_object (&item);
diff --git a/panels/background/bg-source.c b/panels/background/bg-source.c
index dee3ab2..b0127f9 100644
--- a/panels/background/bg-source.c
+++ b/panels/background/bg-source.c
@@ -21,6 +21,8 @@
#include "bg-source.h"
#include "cc-background-item.h"
+#include <cairo-gobject.h>
+
#define THUMBNAIL_WIDTH 256
#define THUMBNAIL_HEIGHT (THUMBNAIL_WIDTH * 3 / 4)
@@ -155,7 +157,7 @@ bg_source_init (BgSource *self)
priv = self->priv = SOURCE_PRIVATE (self);
- priv->store = gtk_list_store_new (3, G_TYPE_ICON, G_TYPE_OBJECT, G_TYPE_STRING);
+ priv->store = gtk_list_store_new (3, CAIRO_GOBJECT_TYPE_SURFACE, G_TYPE_OBJECT, G_TYPE_STRING);
}
GtkListStore*
@@ -167,6 +169,14 @@ bg_source_get_liststore (BgSource *source)
}
gint
+bg_source_get_scale_factor (BgSource *source)
+{
+ g_return_val_if_fail (BG_IS_SOURCE (source), 1);
+
+ return gtk_widget_get_scale_factor (source->priv->window);
+}
+
+gint
bg_source_get_thumbnail_height (BgSource *source)
{
g_return_val_if_fail (BG_IS_SOURCE (source), THUMBNAIL_HEIGHT);
diff --git a/panels/background/bg-source.h b/panels/background/bg-source.h
index bb6f9d4..5719247 100644
--- a/panels/background/bg-source.h
+++ b/panels/background/bg-source.h
@@ -67,6 +67,8 @@ GType bg_source_get_type (void) G_GNUC_CONST;
GtkListStore* bg_source_get_liststore (BgSource *source);
+gint bg_source_get_scale_factor (BgSource *source);
+
gint bg_source_get_thumbnail_height (BgSource *source);
gint bg_source_get_thumbnail_width (BgSource *source);
diff --git a/panels/background/bg-wallpapers-source.c b/panels/background/bg-wallpapers-source.c
index d817ba0..e4bced5 100644
--- a/panels/background/bg-wallpapers-source.c
+++ b/panels/background/bg-wallpapers-source.c
@@ -25,6 +25,7 @@
#include "cc-background-item.h"
#include "cc-background-xml.h"
+#include <cairo-gobject.h>
#include <libgnome-desktop/gnome-desktop-thumbnail.h>
#include <gio/gio.h>
@@ -49,7 +50,9 @@ load_wallpapers (gchar *key,
GtkTreeIter iter;
GIcon *pixbuf;
GtkListStore *store = bg_source_get_liststore (BG_SOURCE (source));
+ cairo_surface_t *surface = NULL;
gboolean deleted;
+ gint scale_factor;
gint thumbnail_height;
gint thumbnail_width;
@@ -60,17 +63,24 @@ load_wallpapers (gchar *key,
gtk_list_store_append (store, &iter);
+ scale_factor = bg_source_get_scale_factor (BG_SOURCE (source));
thumbnail_height = bg_source_get_thumbnail_height (BG_SOURCE (source));
thumbnail_width = bg_source_get_thumbnail_width (BG_SOURCE (source));
pixbuf = cc_background_item_get_thumbnail (item, priv->thumb_factory,
- thumbnail_width, thumbnail_height);
+ thumbnail_width, thumbnail_height,
+ scale_factor);
+ if (pixbuf == NULL)
+ goto out;
+ surface = gdk_cairo_surface_create_from_pixbuf (GDK_PIXBUF (pixbuf), scale_factor, NULL);
gtk_list_store_set (store, &iter,
- 0, pixbuf,
+ 0, surface,
1, item,
2, cc_background_item_get_name (item),
-1);
+ out:
+ g_clear_pointer (&surface, (GDestroyNotify) cairo_surface_destroy);
if (pixbuf)
g_object_unref (pixbuf);
}
diff --git a/panels/background/cc-background-chooser-dialog.c
b/panels/background/cc-background-chooser-dialog.c
index 2c087a8..79b39a2 100644
--- a/panels/background/cc-background-chooser-dialog.c
+++ b/panels/background/cc-background-chooser-dialog.c
@@ -413,18 +413,12 @@ cc_background_chooser_dialog_init (CcBackgroundChooserDialog *chooser)
g_signal_connect (priv->icon_view, "item-activated", G_CALLBACK (on_item_activated), chooser);
renderer = gtk_cell_renderer_pixbuf_new ();
- /* set stock size to 32px so that emblems render at 16px. see:
- * https://bugzilla.gnome.org/show_bug.cgi?id=682123#c4
- */
- g_object_set (renderer,
- "stock-size", GTK_ICON_SIZE_DND,
- NULL);
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->icon_view),
renderer,
FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->icon_view),
renderer,
- "gicon", 0,
+ "surface", 0,
NULL);
gtk_dialog_add_button (GTK_DIALOG (chooser), _("_Cancel"), GTK_RESPONSE_CANCEL);
diff --git a/panels/background/cc-background-item.c b/panels/background/cc-background-item.c
index 3548771..b4b8a4b 100644
--- a/panels/background/cc-background-item.c
+++ b/panels/background/cc-background-item.c
@@ -25,6 +25,7 @@
#include <gtk/gtk.h>
#include <gio/gio.h>
#include <glib/gi18n-lib.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
#include <libgnome-desktop/gnome-bg.h>
#include <gdesktop-enums.h>
@@ -52,6 +53,7 @@ struct CcBackgroundItemPrivate
guint64 modified;
/* internal */
+ GdkPixbuf *slideshow_emblem;
GnomeBG *bg;
char *mime_type;
int width;
@@ -81,15 +83,63 @@ static void cc_background_item_finalize (GObject *object
G_DEFINE_TYPE (CcBackgroundItem, cc_background_item, G_TYPE_OBJECT)
-static GEmblem *
-get_slideshow_icon (void)
+static GdkPixbuf *slideshow_emblem = NULL;
+
+static GIcon *
+get_emblemed_pixbuf (CcBackgroundItem *item, GdkPixbuf *pixbuf, gint scale_factor)
{
- GIcon *themed;
- GEmblem *emblem;
- themed = g_themed_icon_new ("slideshow-emblem");
- emblem = g_emblem_new_with_origin (themed, G_EMBLEM_ORIGIN_DEVICE);
- g_object_unref (themed);
- return emblem;
+ GIcon *icon = NULL;
+ GIcon *retval;
+ GtkIconInfo *icon_info = NULL;
+ int eh;
+ int ew;
+ int h;
+ int w;
+ int x;
+ int y;
+
+ retval = g_object_ref (pixbuf);
+
+ if (item->priv->slideshow_emblem == NULL) {
+ if (slideshow_emblem == NULL) {
+ GError *error = NULL;
+ GtkIconTheme *theme;
+
+ icon = g_themed_icon_new ("slideshow-emblem");
+ theme = gtk_icon_theme_get_default ();
+ icon_info = gtk_icon_theme_lookup_by_gicon_for_scale (theme,
+ icon,
+ 16,
+ scale_factor,
+ GTK_ICON_LOOKUP_FORCE_SIZE |
+ GTK_ICON_LOOKUP_USE_BUILTIN);
+ slideshow_emblem = gtk_icon_info_load_icon (icon_info, &error);
+ if (slideshow_emblem == NULL) {
+ g_warning ("Failed to load slideshow emblem: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+
+ g_object_add_weak_pointer (G_OBJECT (slideshow_emblem), (gpointer *)
(&slideshow_emblem));
+ item->priv->slideshow_emblem = slideshow_emblem;
+ } else {
+ item->priv->slideshow_emblem = g_object_ref (slideshow_emblem);
+ }
+ }
+
+ eh = gdk_pixbuf_get_height (slideshow_emblem);
+ ew = gdk_pixbuf_get_width (slideshow_emblem);
+ h = gdk_pixbuf_get_height (pixbuf);
+ w = gdk_pixbuf_get_width (pixbuf);
+ x = w - ew;
+ y = h - eh;
+
+ gdk_pixbuf_composite (slideshow_emblem, pixbuf, x, y, ew, eh, x, y, 1.0, 1.0, GDK_INTERP_BILINEAR,
255);
+
+ out:
+ g_clear_object (&icon_info);
+ g_clear_object (&icon);
+ return retval;
}
static void
@@ -174,6 +224,7 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
GnomeDesktopThumbnailFactory *thumbs,
int width,
int height,
+ int scale_factor,
int frame,
gboolean force_size)
{
@@ -214,11 +265,7 @@ cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
if (pixbuf != NULL
&& frame != -2
&& gnome_bg_changes_with_time (item->priv->bg)) {
- GEmblem *emblem;
-
- emblem = get_slideshow_icon ();
- icon = g_emblemed_icon_new (G_ICON (pixbuf), emblem);
- g_object_unref (emblem);
+ icon = get_emblemed_pixbuf (item, pixbuf, scale_factor);
g_object_unref (pixbuf);
} else {
icon = G_ICON (pixbuf);
@@ -241,9 +288,10 @@ GIcon *
cc_background_item_get_thumbnail (CcBackgroundItem *item,
GnomeDesktopThumbnailFactory *thumbs,
int width,
- int height)
+ int height,
+ int scale_factor)
{
- return cc_background_item_get_frame_thumbnail (item, thumbs, width, height, -1, FALSE);
+ return cc_background_item_get_frame_thumbnail (item, thumbs, width, height, scale_factor, -1, FALSE);
}
static void
@@ -801,6 +849,8 @@ cc_background_item_finalize (GObject *object)
if (item->priv->bg != NULL)
g_object_unref (item->priv->bg);
+ g_clear_object (&item->priv->slideshow_emblem);
+
G_OBJECT_CLASS (cc_background_item_parent_class)->finalize (object);
}
diff --git a/panels/background/cc-background-item.h b/panels/background/cc-background-item.h
index 401ad8a..633a719 100644
--- a/panels/background/cc-background-item.h
+++ b/panels/background/cc-background-item.h
@@ -73,11 +73,13 @@ gboolean cc_background_item_changes_with_time (CcBackgroundItem
GIcon * cc_background_item_get_thumbnail (CcBackgroundItem *item,
GnomeDesktopThumbnailFactory *thumbs,
int width,
- int height);
+ int height,
+ int scale_factor);
GIcon * cc_background_item_get_frame_thumbnail (CcBackgroundItem *item,
GnomeDesktopThumbnailFactory *thumbs,
int width,
int height,
+ int scale_factor,
int frame,
gboolean force_size);
diff --git a/panels/background/cc-background-panel.c b/panels/background/cc-background-panel.c
index 95eca6b..77c623d 100644
--- a/panels/background/cc-background-panel.c
+++ b/panels/background/cc-background-panel.c
@@ -213,6 +213,7 @@ update_display_preview (CcBackgroundPanel *panel,
GtkAllocation allocation;
const gint preview_width = 309;
const gint preview_height = 168;
+ gint scale_factor;
GdkPixbuf *pixbuf;
GIcon *icon;
cairo_t *cr;
@@ -222,10 +223,12 @@ update_display_preview (CcBackgroundPanel *panel,
if (!current_background)
return;
+ scale_factor = gtk_widget_get_scale_factor (widget);
icon = cc_background_item_get_frame_thumbnail (current_background,
priv->thumb_factory,
preview_width,
preview_height,
+ scale_factor,
-2, TRUE);
pixbuf = GDK_PIXBUF (icon);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]