Merge lp:~3v1n0/libindicator/reduce-image-serialization into lp:libindicator/14.04

Proposed by Marco Trevisan (Treviño)
Status: Merged
Merged at revision: 526
Proposed branch: lp:~3v1n0/libindicator/reduce-image-serialization
Merge into: lp:libindicator/14.04
Diff against target: 136 lines (+44/-40)
1 file modified
libindicator/indicator-image-helper.c (+44/-40)
To merge this branch: bzr merge lp:~3v1n0/libindicator/reduce-image-serialization
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Lars Karlitski (community) Approve
Review via email: mp+208736@code.launchpad.net

Commit message

IndicatorImageHelper: always try to use a GIcon or the filename as source of the GdkImage

We don't need to fallback to pure pixbuf, unless an indicator provided a custom icon that is not in the current theme path.
This helps a lot in reducing the Unity7 workload as this decreases the cases where
we need to encode the pixbuf contents, send them via dbus to unity, encode them
back, reload to a new pixbuf...

Also thanks to this, the library clients can load the actual icon, scaled at the value they want.

Description of the change

Try to avoid image loading to a pixbuf, unless we can't export a GImage or a
filename

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Lars Karlitski (larsu) wrote :

Yeah, I'd love to have this as well, but some of the icons aren't square and need different rescaling.

For example, this patch breaks indicator-power's icon. It's much smaller and blurry.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

> Yeah, I'd love to have this as well, but some of the icons aren't square and
> need different rescaling.
>
> For example, this patch breaks indicator-power's icon. It's much smaller and
> blurry.

Well, not in unity [with lp:~3v1n0/unity/hidpi-better-scaling]... As we handle this thing at UI level (where it should be done imho), btw I've pushed also a change to the indicator-loader to show how to deal with this case.

I know it's something it would be nice to have at library level, but the gain in handling just image references is too high for us...
We could probably do the same thing I did here at unity-panel-service level (reading the "private" INDICATOR_NAMES_DATA, but I'd prefer to depend on an unstable data element like that).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Lars Karlitski (larsu) wrote :

> Well, not in unity [with lp:~3v1n0/unity/hidpi-better-scaling]... As we handle
> this thing at UI level (where it should be done imho), btw I've pushed also a
> change to the indicator-loader to show how to deal with this case.

I totally agree that this is where it should be handled. I didn't know you already fixed it. Nice work!

There's a bigger margin around the menu item in the loader now, but the size of the pixbuf seems to be correct. (Doesn't need to be fixed, I'm just mentioning it.)

I'm fine with landing this after the hidpi unity branch landed. Thanks!

review: Approve
528. By Marco Trevisan (Treviño)

IndicatorLoader: Make sure that we load the icon at its original size, if not higher than IMAGE_SIZE

In this way icons such as the battery one won't be shrunk.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

So, I've pushed a new revision that handles the things in a different way: basically setting the pixel size to 0 makes gtk to load the icon at its full size; so we can safely do that if the actual icon size isn't bigger than the ICON_SIZE value.

In this way also gtk apps (such as the greeter) won't need any change to support these kinds of icons.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
529. By Marco Trevisan (Treviño)

IndicatorImageHelper: let's use the actual icon file if its height is less than ICON_SIZE

Revision history for this message
Lars Karlitski (larsu) wrote :

Works fine again after the latest changes. Thanks!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libindicator/indicator-image-helper.c'
2--- libindicator/indicator-image-helper.c 2013-12-20 11:30:44 +0000
3+++ libindicator/indicator-image-helper.c 2014-03-03 10:25:52 +0000
4@@ -25,6 +25,7 @@
5 #include "indicator-image-helper.h"
6
7 const gchar * INDICATOR_NAMES_DATA = "indicator-names-data";
8+const gint ICON_SIZE = 22;
9
10 static void
11 refresh_image (GtkImage * image)
12@@ -32,21 +33,20 @@
13 g_return_if_fail(GTK_IS_IMAGE(image));
14 const gchar * icon_filename = NULL;
15 GtkIconInfo * icon_info = NULL;
16- gint icon_size = 22;
17
18 GIcon * icon_names = (GIcon *)g_object_get_data(G_OBJECT(image), INDICATOR_NAMES_DATA);
19- g_return_if_fail(icon_names != NULL);
20+ g_return_if_fail(G_IS_ICON (icon_names));
21
22 /* Get the default theme */
23 GtkIconTheme * default_theme = gtk_icon_theme_get_default();
24 g_return_if_fail(default_theme != NULL);
25
26 /* Look through the themes for that icon */
27- icon_info = gtk_icon_theme_lookup_by_gicon(default_theme, icon_names, icon_size, 0);
28+ icon_info = gtk_icon_theme_lookup_by_gicon(default_theme, icon_names, ICON_SIZE, 0);
29 if (icon_info == NULL) {
30 /* Maybe the icon was just added to the theme, see if a rescan helps */
31 gtk_icon_theme_rescan_if_needed(default_theme);
32- icon_info = gtk_icon_theme_lookup_by_gicon(default_theme, icon_names, icon_size, 0);
33+ icon_info = gtk_icon_theme_lookup_by_gicon(default_theme, icon_names, ICON_SIZE, 0);
34 }
35 if (icon_info == NULL) {
36 /* Try using the second item in the names, which should be the original filename supplied */
37@@ -63,25 +63,56 @@
38 icon_filename = gtk_icon_info_get_filename(icon_info);
39 }
40
41- if (icon_filename == NULL && !G_IS_BYTES_ICON (icon_names)) {
42+ if (icon_filename == NULL && !G_IS_BYTES_ICON(icon_names)) {
43 /* show a broken image if we don't have a filename or image data */
44- gtk_image_set_from_icon_name (image, "image-missing", GTK_ICON_SIZE_LARGE_TOOLBAR);
45+ gtk_image_set_from_icon_name(image, "image-missing", GTK_ICON_SIZE_LARGE_TOOLBAR);
46 return;
47 }
48
49- /* Build a pixbuf */
50- GdkPixbuf * pixbuf = NULL;
51-
52- if (icon_filename == NULL) {
53+ if (icon_info != NULL) {
54+ GdkPixbuf *pixbuf = gtk_icon_info_load_icon(icon_info, NULL);
55+
56+ if (gdk_pixbuf_get_height(pixbuf) < ICON_SIZE) {
57+ gtk_image_set_from_file(image, icon_filename);
58+ } else {
59+ gtk_image_set_from_gicon(image, icon_names, GTK_ICON_SIZE_LARGE_TOOLBAR);
60+ }
61+ g_object_unref (pixbuf);
62+ } else if (icon_filename != NULL) {
63+ gtk_image_set_from_file(image, icon_filename);
64+
65+ gint height;
66+ gdk_pixbuf_get_file_info(icon_filename, NULL, &height);
67+
68+ if (height > ICON_SIZE) {
69+ gtk_image_set_pixel_size(image, ICON_SIZE);
70+ }
71+ } else if (G_IS_LOADABLE_ICON(icon_names)) {
72+ /* Build a pixbuf if needed */
73+ GdkPixbuf * pixbuf = NULL;
74 GError * error = NULL;
75- GInputStream * stream = g_loadable_icon_load (G_LOADABLE_ICON (icon_names), icon_size, NULL, NULL, &error);
76+ GInputStream * stream = g_loadable_icon_load(G_LOADABLE_ICON(icon_names), ICON_SIZE, NULL, NULL, &error);
77
78 if (stream != NULL) {
79- pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
80+ pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, &error);
81 g_input_stream_close (stream, NULL, NULL);
82 g_object_unref (stream);
83
84- if (pixbuf == NULL) {
85+ if (pixbuf != NULL) {
86+ /* Scale icon if all we get is something too big. */
87+ if (gdk_pixbuf_get_height(pixbuf) > ICON_SIZE) {
88+ gfloat scale = (gfloat)ICON_SIZE / (gfloat)gdk_pixbuf_get_height(pixbuf);
89+ gint width = round(gdk_pixbuf_get_width(pixbuf) * scale);
90+
91+ GdkPixbuf * scaled = gdk_pixbuf_scale_simple(pixbuf, width, ICON_SIZE, GDK_INTERP_BILINEAR);
92+ g_object_unref(G_OBJECT(pixbuf));
93+ pixbuf = scaled;
94+ }
95+
96+ /* Put the pixbuf on the image */
97+ gtk_image_set_from_pixbuf(image, pixbuf);
98+ g_object_unref(G_OBJECT(pixbuf));
99+ } else {
100 g_warning ("Unable to load icon from data: %s", error->message);
101 g_error_free (error);
102 }
103@@ -89,33 +120,6 @@
104 g_warning ("Unable to load icon from data: %s", error->message);
105 g_error_free (error);
106 }
107- } else {
108- GError * error = NULL;
109-
110- pixbuf = gdk_pixbuf_new_from_file (icon_filename, &error);
111-
112- if (pixbuf == NULL) {
113- g_warning ("Unable to load icon from file '%s': %s", icon_filename, error->message);
114- g_error_free (error);
115- }
116- }
117-
118- if (pixbuf != NULL) {
119- /* Scale icon if all we get is something too big. */
120- if (gdk_pixbuf_get_height(pixbuf) > icon_size) {
121- gfloat scale = (gfloat)icon_size / (gfloat)gdk_pixbuf_get_height(pixbuf);
122- gint width = round(gdk_pixbuf_get_width(pixbuf) * scale);
123-
124- GdkPixbuf * scaled = gdk_pixbuf_scale_simple(pixbuf, width, icon_size, GDK_INTERP_BILINEAR);
125- g_object_unref(G_OBJECT(pixbuf));
126- pixbuf = scaled;
127- }
128-
129- /* Put the pixbuf on the image */
130- gtk_image_set_from_pixbuf(image, pixbuf);
131- g_object_unref(G_OBJECT(pixbuf));
132- } else {
133- gtk_image_set_from_icon_name (image, "image-missing", GTK_ICON_SIZE_LARGE_TOOLBAR);
134 }
135
136 if (icon_info != NULL) {

Subscribers

People subscribed via source and target branches