After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 671750 - set "representative color" property on the root window
set "representative color" property on the root window
Status: RESOLVED FIXED
Product: gnome-desktop
Classification: Core
Component: libgnome-desktop
unspecified
Other All
: Normal enhancement
: ---
Assigned To: Desktop Maintainers
Desktop Maintainers
Depends on:
Blocks:
 
 
Reported: 2012-03-09 20:07 UTC by Allison Karlitskaya (desrt)
Modified: 2012-03-10 16:12 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gnome-bg: have pixbuf_average_value return GdkRGBA (2.44 KB, patch)
2012-03-09 20:07 UTC, Allison Karlitskaya (desrt)
reviewed Details | Review
gnome-bg: publish the 'representative color' (3.56 KB, patch)
2012-03-09 20:07 UTC, Allison Karlitskaya (desrt)
reviewed Details | Review
gnome-bg: have pixbuf_average_value return GdkRGBA (2.78 KB, patch)
2012-03-09 21:38 UTC, Allison Karlitskaya (desrt)
committed Details | Review
gnome-bg: publish the 'representative color' (4.03 KB, patch)
2012-03-09 21:38 UTC, Allison Karlitskaya (desrt)
committed Details | Review

Description Allison Karlitskaya (desrt) 2012-03-09 20:07:16 UTC
Some various parts of chrome in Unity (and notify-osd) want to change their colour according to the predominant/average background image colour.  They currently have some bad hacks to deal with that (including writing the current average colour to GSettings from the window manager).

Far better would be to go straight to the source: set an X property from the same place as we set the other X properties: GnomeBG.
Comment 1 Allison Karlitskaya (desrt) 2012-03-09 20:07:50 UTC
Created attachment 209354 [details] [review]
gnome-bg: have pixbuf_average_value return GdkRGBA

Now that we have a proper type for RGBA values, we should use it
(instead of packing the four components into a uint32).
Comment 2 Allison Karlitskaya (desrt) 2012-03-09 20:07:52 UTC
Created attachment 209355 [details] [review]
gnome-bg: publish the 'representative color'

Publish a list of 'representative colours' as a property on the root
window _GNOME_BACKGROUND_REPRESENTATIVE_COLORS.  This is alongside the
normal properties pointing at the pixmap of the background image.

Right now, this is just implemented as an average using the existing
pixbuf_average_value() function.  Strictly speaking, the property is a
list of colours and in the future we may set more than one.
Comment 3 Ray Strode [halfline] 2012-03-09 20:27:47 UTC
Review of attachment 209354 [details] [review]:

reasonable cleanup

::: libgnome-desktop/gnome-bg.c
@@ +138,2 @@
 /* Pixbuf utils */
+static GdkRGBA    pixbuf_average_value (GdkPixbuf  *pixbuf);

Can you make this an out arg?  returning structs makes me irrationally twitchy
Comment 4 Ray Strode [halfline] 2012-03-09 20:29:34 UTC
Review of attachment 209354 [details] [review]:

Also, any chance you want to clean up the other things that could be GdkRGBA (the GdkColor stuff i mean) ?
Comment 5 Ray Strode [halfline] 2012-03-09 20:41:55 UTC
Review of attachment 209355 [details] [review]:

::: libgnome-desktop/gnome-bg.c
@@ +128,3 @@
 };
 
+static cairo_user_data_key_t average_color_key;

should be const and maybe called representative_colors_key ?

@@ +1126,3 @@
+	cairo_surface_set_user_data (surface, &average_color_key,
+	                             gdk_rgba_copy (&average),
+	                             (cairo_destroy_func_t) gdk_rgba_free);

Oh I see you aren't bothering with the list internally yet. That's probably fine, but if you did do it now, would mean less typing a more clear roadmap for the future later on.

@@ +1496,3 @@
+		                 XA_STRING, 8, PropModeReplace,
+		                 (guchar *) string, strlen (string) + 1);
+		g_free (string);

strlen (string) not strlen (string) + 1 (according to xprop.c in xorg-x11-utils anyway)

@@ +1499,3 @@
+	} else {
+		XDeleteProperty (display, RootWindow (display, screen_num),
+		                 gdk_x11_get_xatom_by_name ("_GNOME_BACKGROUND_REPRESENTATIVE_COLORS"));

When will this code path hit?
Comment 6 Ray Strode [halfline] 2012-03-09 20:41:56 UTC
Review of attachment 209355 [details] [review]:

::: libgnome-desktop/gnome-bg.c
@@ +128,3 @@
 };
 
+static cairo_user_data_key_t average_color_key;

should be const and maybe called representative_colors_key ?

@@ +1126,3 @@
+	cairo_surface_set_user_data (surface, &average_color_key,
+	                             gdk_rgba_copy (&average),
+	                             (cairo_destroy_func_t) gdk_rgba_free);

Oh I see you aren't bothering with the list internally yet. That's probably fine, but if you did do it now, would mean less typing a more clear roadmap for the future later on.

@@ +1496,3 @@
+		                 XA_STRING, 8, PropModeReplace,
+		                 (guchar *) string, strlen (string) + 1);
+		g_free (string);

strlen (string) not strlen (string) + 1 (according to xprop.c in xorg-x11-utils anyway)

@@ +1499,3 @@
+	} else {
+		XDeleteProperty (display, RootWindow (display, screen_num),
+		                 gdk_x11_get_xatom_by_name ("_GNOME_BACKGROUND_REPRESENTATIVE_COLORS"));

When will this code path hit?
Comment 7 Ray Strode [halfline] 2012-03-09 20:43:07 UTC
yay dupes
Comment 8 Allison Karlitskaya (desrt) 2012-03-09 21:28:14 UTC
Review of attachment 209355 [details] [review]:

::: libgnome-desktop/gnome-bg.c
@@ +128,3 @@
 };
 
+static cairo_user_data_key_t average_color_key;

will make this const.

@@ +1126,3 @@
+	cairo_surface_set_user_data (surface, &average_color_key,
+	                             gdk_rgba_copy (&average),
+	                             (cairo_destroy_func_t) gdk_rgba_free);

I'd rather not complicate the code on the basis of a feature we may or may not add later.  It's internal API so there is no risk associated with not doing it now.

@@ +1496,3 @@
+		                 XA_STRING, 8, PropModeReplace,
+		                 (guchar *) string, strlen (string) + 1);
+		g_free (string);

Keep in mind that this is actually a string array.  String arrays are encoded with a nul following each item.  so

  ["foo", "bar", "baz"]

is encoded like

 'f' 'o' 'o' '\0' 'b' 'a' 'r' '\0' 'b' 'a' 'z' '\0'

and has a length of 12.


Could probably use a comment.  I'll add it.

@@ +1499,3 @@
+	} else {
+		XDeleteProperty (display, RootWindow (display, screen_num),
+		                 gdk_x11_get_xatom_by_name ("_GNOME_BACKGROUND_REPRESENTATIVE_COLORS"));

It could happen if someone gives us a cairo surface that we did not create.  I don't know if anyone will do that, but it's a theoretical possibility.
Comment 9 Allison Karlitskaya (desrt) 2012-03-09 21:29:06 UTC
Review of attachment 209354 [details] [review]:

If we are going to have a general GdkColor -> GdkRGBA, I think there should be a separate bug.

::: libgnome-desktop/gnome-bg.c
@@ +138,2 @@
 /* Pixbuf utils */
+static GdkRGBA    pixbuf_average_value (GdkPixbuf  *pixbuf);

if it makes you feel better.... :)
Comment 10 Allison Karlitskaya (desrt) 2012-03-09 21:38:57 UTC
Created attachment 209361 [details] [review]
gnome-bg: have pixbuf_average_value return GdkRGBA

Now that we have a proper type for RGBA values, we should use it
(instead of packing the four components into a uint32).
Comment 11 Allison Karlitskaya (desrt) 2012-03-09 21:38:59 UTC
Created attachment 209362 [details] [review]
gnome-bg: publish the 'representative color'

Publish a list of 'representative colours' as a property on the root
window _GNOME_BACKGROUND_REPRESENTATIVE_COLORS.  This is alongside the
normal properties pointing at the pixmap of the background image.

Right now, this is just implemented as an average using the existing
pixbuf_average_value() function.  Strictly speaking, the property is a
list of colours and in the future we may set more than one.
Comment 12 Ray Strode [halfline] 2012-03-09 21:55:22 UTC
Review of attachment 209361 [details] [review]:

::: libgnome-desktop/gnome-bg.c
@@ +2380,3 @@
 	}
+
+	dd = dividend * 0xFF;

I don't really understand the naming scheme used here (even before your changes). I would probably rename dividend to devisor or denominator, and roll dd into it.

But up to you.
Comment 13 Ray Strode [halfline] 2012-03-09 21:57:15 UTC
Review of attachment 209362 [details] [review]:

::: libgnome-desktop/gnome-bg.c
@@ +134,3 @@
 G_DEFINE_TYPE (GnomeBG, gnome_bg, G_TYPE_OBJECT)
 
+

drop this newline

@@ +1105,3 @@
 	if (!bg->filename && bg->color_type == G_DESKTOP_BACKGROUND_SHADING_SOLID) {
 		gdk_cairo_set_source_color (cr, &(bg->primary));
+		average.red = bg->primary.red / (double) 0xff;

maybe 255.0 instead of (double) 0xff ? doesn't really matter i guess.
Comment 14 Ray Strode [halfline] 2012-03-09 22:00:58 UTC
oh one other thought, should probably only muck with the property/do the average if create_surface has is_root = true
Comment 15 Allison Karlitskaya (desrt) 2012-03-09 22:33:06 UTC
'dd' is 'dividend, as a double' *shrug*

patch pushed with requested changes.

Thanks for the fast review.

Attachment 209361 [details] pushed as e8afbf1 - gnome-bg: have pixbuf_average_value return GdkRGBA
Attachment 209362 [details] pushed as 22d7f10 - gnome-bg: publish the 'representative color'
Comment 16 Sebastien Bacher 2012-03-10 11:40:49 UTC
Ryan, did you mesure how long takes the pixbuf_average_value() computation? When does it happen? I would like to avoid adding extra cpu use to calculate that value at login, ideally that would be stored and read at login and only updated when somebody change backgrounds...
Comment 17 Allison Karlitskaya (desrt) 2012-03-10 15:45:12 UTC
hi Seb,

(In reply to comment #16)
> Ryan, did you mesure how long takes the pixbuf_average_value() computation?
> When does it happen? I would like to avoid adding extra cpu use to calculate
> that value at login, ideally that would be stored and read at login and only
> updated when somebody change backgrounds...

The value can't really be stored anywhere because of how some background setups are slideshow-type backgrounds where the average colour is going to be changing dynamically.

We considered the performance when discussing the bug on IRC.  The idea was that we would go ahead with the current code unless it became a problem and then we would look for ways to fix it.  A rather good low-impact way is quite obvious: instead of sampling every pixel, sample a point grid spaced at 16x16 or so -- this would cut the amount of time by 1/256.

In any case, the question is a good one.  I'll do some measurements.
Comment 18 Allison Karlitskaya (desrt) 2012-03-10 16:12:26 UTC
-> Bug 671780